The firmware consists of a cargo workspace. This workspace contains all libraries and desktop binaries.
The firmware binaries are separated into their own binary crates. This allows them to not share any features of dependencies. The hal crates in particular have "select one" features for the specific target. These features cannot be enabled at the same time.
The common library crate provides basic functions that are used by all or most of the binary crates.
This currently includes a global allocator, a global logger and a panic handler.
In the future this should also include the CAN-bus implementation.
The template binary crate is an example blink application for the ST Nucleo with the STM32H7A3ZI µController.
It shows all the basics and gives a solid start.
A cargo xtask is provided. The xtask main purpose is to execute cargo commands in all crates - even those excluded from the workspace. This is used in the GitLabCI to build and check all crates. In development this functionality might not be that important but could be used to check that everything builds before crating a merge request.
Before you can start hacking away at the firmware, you need some tools. When using nix, you can just use the dev shell provided by the nix flake. When not using rust, you first need the rust toolchain. The toolchain can be installed using rustup:
$ rustup target add thumbv7em-none-eabihfNext we need flip-link. flip-link is a linker wrapper that allows for zero-cost stack overflow protection. You can install it using cargo:
$ cargo install flip-linkGreat. Now you are able to compile the template. In order to upload the binary to the µControllel you need another tool. I recommend probe-rs although there are others too. Install it using cargo:
$ cargo install probe-rs-toolsOn Linux you need to install some udev rules for probe-rs to work.
Now you can run
$ cd template
$ cargo runto build the template binary and flash it to the Nucleo development board. If no errors are reported, the Green LED should blink.
We need to be in the binary crate we want to run, because the binaries are not part of the workspace.
As a little extra, bacon is recommended. bacon is a background code checker. Install it using cargo:
$ cargo install baconNow you can run
$ bacon clippyto get a live output of all the build errors and lints.
To start a new binary crate, start by copying the template crate and adding it to the workspace excludes in the root Cargo.toml.
$ cp -R template <module_name># Cargo.toml
[workspace]
…
exclude = ["<module_name>", "template", …]
…If you are not using the STM32H7A3 µController, you need to adjust the binary crate a bit. You need to match the memory.x file in your crate to the memory map of the specific µController.
Additionally you need to change the µController specific features of the rtic-monotonics crate and select the correct hal.
To find the correct hal for your stm32 µController go to crates.io and search for the first seven letters of the µController and hal e.g. "stm32f4 hal".
Using another µController also almost certainly means you have to change the power and clock initialization in the setup_core function.
probe-rs needs to know what µController you are trying to flash too.
For this you need to change the selected chip in <module_name>/.cargo/config.toml.
# <module_name>/.cargo/config.toml
[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip <your modules chip>"
…The command cargo embed is part of the probe-rs-tools suite.
It provides a TUI interface for watching the different rtt streams send by the µController.
Sending data to the µController is Supported as well.
Running
$ cargo embedwill flash the µController with the firmware and open the tui. In the tui you can select which stream you want to watch using the [Fx] keys.
| Key | Stream |
|---|---|
| [F1] | Log |
| [F2] | Terminal Output |
| [F3] | Terminal Input |
When the Terminal Input is selected, you can enter text. The text will be send to the µController when the [Enter] key is pressed. Sadly the PC will not pace the Input. Thus any messages longer than the rtt buffer size (128 Byte) will be lost.