modm API documentation
|
Modules | |
CMake Build Script Generator | |
CompilationDB Generator | |
Makefile Build Script Generator | |
SCons Build Script Generator | |
lbuild module: modm:build
This parent module defines a common set of functionality that is independent of the specific build system generator implementation. This includes straight-forward options like project name and build path but also more complicated configuration for programming your target via AvrDude or OpenOCD and debugging via GDB.
Note that this module does not compile your project, you will need to choose the modm:build:scons
or modm:build:cmake
submodule for that, or provide your own build system.**
We maintain a common set of compiler options for all build system generator, so that they all have feature parity. We currently only support compiling modm with GCC for AVR, ARM Cortex-M and x86/posix with the options mentioned in the offical GCC options documentation.
You can find all compiler options inside the generated build script for your project, the options presented here are only the most important ones.
-W{all, extra}
: a basic set of warnings.-Werror={format, maybe-uninitialized, overflow, sign-compare}
: these warnings are treated as errors.-f{data, function}-sections
: puts data and functions into their own linker section.-funsigned-{char, bitfields}
: modm tries to use stdint.h
types everywhere, but just in case.-fwrapv
: integer overflows wrap around according to 2s complement.For release builds:
-Os
: optimize for smaller size.For debug builds:
-Og
: optimize for debugging experience.MODM_DEBUG_BUILD
: this macro is only defined in debug profile. You can use it with #ifdef MODM_DEBUG_BUILD
to enable debug code.-std=gnu2x
: use C23 with GNU extensions (for asm volatile
).-std=c++23
: use C++23For exception and RTTI flags, see modm:stdc++
module.
--gc-section
: garbage collecting sections throws out a lot of unused data/code.-L{linkdir} -Tlinkerscript.ld
: modm uses a custom linkerscript.For target specific flags, see the modm:platform:core
and related modules.
This module generates a common set of configuration files that are used by the common tooling. Please note that these files are the foundation of more extensive tooling available as Python scripts which are then again wrapped by your chosen build system for convenience.
For accessing your ARM Cortex-M based device, we use OpenOCD by default and generate a modm/openocd.cfg
file with the target specific configuration:
path.openocd
collector.openocd.source
collector. Your custom modm:build:openocd.cfg
is added here too.You need to start openocd with this configuration file:
Unfortunately AvrDude does not support a project-specific configuration file like OpenOCD does (only a undocumented user config in ~/.avrduderc
), so there is no convenient one-line command to issue. You have to use the wrapper support of the specific build system or simply call AvrDude yourself via its command line.
A few commands are provided for convenience via the modm/gdbinit
configuration:
reset
: resets the device and halts.rerun
: resets the device and continues execution.modm_coredump
: Dumps all volatile memories into a coredump.txt
file. See the modm:platform:fault
module for details.modm_build_id
: Finds and prints the GNU build id of the firmware.GDB continues running the target after attaching, but does not load an ELF file! Please pass the ELF file as a command line argument.
You can start your GDB session like so:
We have written a number of pure Python tools to provide common functionality that get wrapped by the build system.
Here is a selection of tools that have a command line interface, so you can call them even without build system support in case you have a special setup. Note that there are even more tools that can be called in Python only, so have a look in your generated modm/modm_tools
folder.
modm_tools
to your Python path To call modm_tools
via module syntax, you need to add the generated modm folder to your Python path: export PYTHONPATH=path/to/generated/modm
. You can also use the module in this repository directly.This tool simply wraps the avrdude
command to provide two features:
Fuses stored in the ELF file can be programmed by passing --fuse
arguments:
(* only AVR targets)
Simply wraps OpenOCD and issues the right command to program the target.
You can also reset the target:
You can use a different OpenOCD binary by setting the MODM_OPENOCD_BINARY
environment variable before calling this script. This can be useful when using a custom OpenOCD build for specific targets.
(* only ARM Cortex-M targets)
This tool wraps GDB to program an ELF file onto a target connected to a BMP. You can explictly pass the serial port, or let the tool guess it.
You can also reset the target:
(* only ARM Cortex-M targets)
For debugging your program on ARM Cortex-M device, this Python tool wraps arm-none-eabi-gdb
and connects it to a number of programmers running in the background or remotely.
The tool can be called from the command line. Here is a typical use-case using the openocd backend with the common configuration files:
Or you can call the Python API directly:
This configuration starts the OpenOCD process in the background for you, however, if you want to connect to an already running process, you can use the remote backend with the --host={ip or hostname}
via the command line:
Note that you can use different programmer backends to GDB, for example the Black Magic Probe:
To analyze a core dump, you can use the CrashDebug
GDB backend. See the modm:crashcatcher
module for details.
(* only ARM Cortex-M targets)
Currently three UIs are implemented for debugging:
--ui=cmd
: No UI, only the GDB command shell.--ui=tui
: Text-based UI in your shell.--ui=gdbgui
: Web-based UI in your browser, based on gdbgui.This UI is builtin to GDB and is therefore always available.
This UI simply uses the gdbgui project and works very well as an advanced IDE-independent debugging solution.
Inspects the ELF file and generates a size report of the static usage of the device's memories. You must pass the available memory segments as a Python dictionary:
(* only ARM Cortex-M targets)
This tool generates a set of source files containing information about the repository state.
You can use the --check-rebuild
flag to only write the output file when the information changed. This prevents unnecessary rebuilding and relinking.
The git_info(directory)
function returns a dictionary with these values:
MODM_GIT_SHA
: commit hash: H
.MODM_GIT_SHA_ABBR
: short commit hash: h
.MODM_GIT_SUBJECT
: commit subject as text: s
.MODM_GIT_AUTHOR
: author name: an
.MODM_GIT_AUTHOR_EMAIL
: author email: ae
.MODM_GIT_AUTHOR_DATE
: authoring date: ad
.MODM_GIT_AUTHOR_DATE_TIMESTAMP
: authoring date as Unix timestamp: at
.MODM_GIT_COMMITTER
: committer name: cn
.MODM_GIT_COMMITTER_EMAIL
: committer email: ce
.MODM_GIT_COMMITTER_DATE
: committer date: cd
.MODM_GIT_COMMITTER_DATE_TIMESTAMP
: committer das as Unix timestamp: ct
.MODM_GIT_CONFIG_USER_NAME
: local user name: user.name
.MODM_GIT_CONFIG_USER_EMAIL
: local user email: user.email
.The git_info(directory, with_status=True)
function returns these additional values:
MODM_GIT_MODIFIED
: number of modified files: M
.MODM_GIT_ADDED
: number of added files: A
.MODM_GIT_DELETED
: number of deleted files: D
.MODM_GIT_RENAMED
: number of renamed files: R
.MODM_GIT_COPIED
: number of copied files: C
.MODM_GIT_UNTRACKED
: number of untracked files: ?
.This example project is showing an unclean repository state with uncommitted changes. This can give you a few hints as to where a firmware came from and help you pinpoint the source of a bug or feature.
Generates a files with these values defined as const char *
strings:
MODM_BUILD_PROJECT_NAME
: as defined in the modm:build:project.name
option.MODM_BUILD_MACHINE
: machine information.MODM_BUILD_USER
: user information.MODM_BUILD_OS
: OS version string (best effort, may not be useful!).MODM_BUILD_COMPILER
: compiler information.Example output on macOS:
Simply wraps JLinkGDBServer and issues the right command to program the target.
You can also reset the target:
You can set the MODM_JLINK_BINARY
environment variable to point this script to a specific JLinkGDBServer
binary:
(* only ARM Cortex-M targets)
This tools scans a directory for files ending in _test.hpp
, extracts their test cases and generates a source file containing the test runner.
Note that the files containing unittests must contain one class that inherits from the unittest::TestSuite
class, and test case names must begin with test
:
Logging using the SWO protocol is supported by the modm:platform:itm
module. You can use OpenOCD to receive the output, but you must manually supply the CPU frequency:
JLink is also supported and can determine the CPU frequency automatically:
(* only ARM Cortex-M targets)
Logging using the RTT protocol is supported by the modm:platform:rtt
module. You can use OpenOCD to send and receive on a channel of your choice using the built-in Python telnet client:
JLink is also supported and may have faster transfer rates:
(* only ARM Cortex-M targets)
To extract the build ID from an ELF file:
To copy the ELF file to a artifact cache:
(* only ARM Cortex-M targets)
This tool can convert P1 .pbm
files into C++ source code.
UF2 is a Microsoft file format to pass to a on-device bootloader.
(* only ARM Cortex-M targets)
The project name defaults to the folder name you're calling lbuild from.
It's used by your build system to name the executable and it may also be passed to your application via a string constant or CPP define.
Generated with: tmpo0lsdol0 in [String]
The build path is defaulted to build/{modm:build:project.name}
.
If you have a lot of embedded projects, you may want to change the build path to a common directory so that you don't have build/
folders everywhere. Remember to add your build path to your .gitignore
.
You should use a relative path instead of an absolute one, so that this option still works for other developers.
Generated with: build/tmpo0lsdol0 in [Path]
When this path is declared, the generated build script will compile only the unittests, not your application source code! You must use separate project configurations for compiling your unittest and application!
Generated with: [] in [Path]
Generated with: [] in [Path]
Info
: generates information about the last commit.Info+Status
: like Info
plus git file status.Generated with: Disabled in [Disabled, Info, Info+Status]
Generated with: no in [yes, no]
If you have a custom configuration file for your target, it will get included by the generated modm/openocd.cfg
.
This is useful for not having to duplicate your config if you have several projects using the same target (like small bring-up and test projects).
init
or similar in your script will mess with modm's ability to program and debug a device correctly.Generated with: [] in [Path]