modm API documentation
|
Modules | |
NUCLEO-G071RB | |
lbuild module: modm:board
modm provides pre-configured BSPs for several commercial off-the-shelf development boards. There are two main components to the BPSs:
board.xml
containing the HAL target, options and the board module. This pre-defined configuration is aliased as a repo configuration so that your project.xml
simply <extends>modm:{board-name}</extends>
.modm:board:{board-name}
that pulls in required dependencies, configures the modm library and provides the code to initialize the board. You can then #include <modm/board.hpp>
in your project.The BSPs all use a common interface within a top-level namespace Board
:
Board::initialize()
: Initializes the targets clock system, logger, LEDs and Buttons.Board::initialize{subsystem}()
: Initializes optional board subsystems.Board::SystemClock
: Provides the clock configuration for use in Peripheral::initialize<Board::SystemClock, ...>()
.Board::Led{name}
: Board-specific LEDs are initialized as outputs and off.Board::Leds
: A modm::platform::SoftwareGpioPort
containing all board LEDs.Board::Button
: Board-specific input buttons are initialized as input with pull-up/down as required.Board::{pin-name}
: All board-specific pins are aliased to their respective modm::platform::Gpio{port}{pin}
.If the board supports a dedicated serial logging output the BSP redirects the modm:debug
module debug stream MODM_LOG_INFO
as well as the output of the standalone printf
function.
Please note that YOU must explicitly call the Board
functions to initialize your hardware, just including the board module is not enough. Here is an example using the modm:disco-f469ni
BSP:
The BSPs contain an opinionated set of pre-defined functionality and settings. This is great for just quickly prototyping something, however, when you want to use custom hardware, or even just change a few settings, it's better to use your own BSP:
modm/src/modm/board/{name}
to your own project and modify them.project.xml
remove the board config inheritance (<extends>
) and instead copy the pre-defined options into your own config.module.depends(...)
in the BSPs module.lb
).env.collect(...)
in the BSPs module.lb
).The easiest way using ST's CubeMX tool.
First we create a project in CubeMX with the desired microcontroller using the largest (pin-count, flash) variant. CubeMX displays something like this in the "Clock configuration" tab:
Then configure all clocks, muxes, multipliers and dividers to the highest allowed clock speeds (*).
(*) exceptions: E.g. USB usually requires exactly 48 MHz.
This settings are reflected in the constants static constexpr uint32_t Frequency
, Apb1
and Apb2
as well as in const Rcc::PllFactors pllFactors{...}
and the following lines. The PllFactors
struct should be fairly self-explanatory.
As we can see in the graphic above, there are different clock ranges. Each peripheral is connected to a clock domain. Some peripherals have an upstream clock mux, this is currently ignored in modm and the default setting for the clock mux is assumed.
The figure shows the block diagram of the controller, which can be found at the beginning of the data sheet (not in the reference manual):
For each peripheral we create a static constexpr uint32_t
member in the struct SystemClock
and assign the value of the clock domain to which the peripheral is connected.