This repository hosts experimental Rust firmware code for the BMC (and related) microcontrollers. The research conducted here is focused on enabling Racklet BMC functionality, such as hosting boot partition files, performing cryptographic verification, and logging traces on ARM Cortex-M microcontrollers. We're all still learning, and the embedded Rust ecosystem is still quite young, so feel free to join the pioneering!
The experiments in this repository currently target the ATSAMD51G19A microcontroller (MCU) (on an Adafruit ItsyBitsy M4 Express) as it was readily available, and has decent community support and enough resources for learning and experimentation. While the final chip used for the BMC boards is still undecided, the long term goal for the firmware and libraries here is to be somewhat vendor and chip agnostic using abstraction layers and feature gates. The core team doesn't have a wide variety of hardware available, but if you can put in the effort to support and test the builds on your particular microcontroller board, we're more than happy enable support for it!
This repository uses probe-run
to enable running (and to some extent
debugging) embedded applications just like native ones using cargo run
. This
includes support for highly performant stdin/stdout and automatic panic message
output using the Real-Time Transfer (RTT) I/O protocol from the probe-rs
project. For more serious debugging a configuration for cargo-embed
is
provided, which will provide a GDB server when run with cargo embed debug <args>
which can then be attached to using a multi-arch GDB build either from
the CLI or your favorite IDE.
The use of probe-rs
-based tooling (probe-run
and cargo-embed
) requires you
to attach to your MCU board using a debug probe supporting the debugging
protocol of your particular MCU (either JTAG or preferably SWD for ARM
Cortex-M based chips like the ATSAMD51G19A).
In addition to considering what protocol is used between the MCU and the debug
probe, it's also important to check what protocol the debug probe uses to talk
to the host computer (the machine where you're uploading code and debugging
from). At present (August 23rd, 2021) the probe-rs
supported probe protocols
include CMSIS-DAP, ST-LINK, J-Link and experimentally FTDI (JTAG only). Feel
free to look into each to understand their differences and use what works for
you. Detailed below is a simplified table highlighting some key differences
between them as a starting point.
Protocol | Firmware License | Supported Probes | Supported MCUs |
---|---|---|---|
CMSIS-DAP | Open Source (implementation specific) | MCU based (e.g. ST-LINK series) | Everything* |
ST-LINK | Proprietary (STMicroelectronics) | ST-LINK series (and clones) | STM32 (and some others) |
J-Link | Proprietary (SEGGER) | J-Link debug probes | Everything |
FTDI | Hardware converter, no firmware | FTDI USB converters | Everything |
* Technically CMSIS-DAP requires the target MCU to have a CoreSight Debug Access Port (DAP). This is true for all ARM Cortex based CPU designs, but e.g. AVR and RISC-V based MCUs are not supported (unless there are some hacks involved).
Due to its Open Source firmware support, versatility and low cost availability, the Racklet core team has settled on using CMSIS-DAP as the host communication protocol of choice. It is not overly difficult to convert an ST-LINK debug probe to run a CMSIS-DAP compatible firmware, and presents an affordable way to debug the ItsyBitsy M4 running an Atmel (now owned by Microchip) ARM processor, which has difficulties communicating with the stock ST-LINK firmware. Details are elaborated below.
There are various low-cost clones of the ST-LINK V2 debugger probe available
from markets such as eBay and Aliexpress. It doesn't really matter which one you
choose/have (the original one should work as well), as the stock firmware that
only speaks the ST-LINK protocol needs to be replaced. While it could
technically work with probe-rs
, the firmware is proprietary and has issues
talking to anything other than STM32 ARM chips. Our recommendation is flashing
the probe with the dap42 CMSIS-DAP firmware, which enable the probe to support
basically any ARM chip (including STM32) and to work seamlessly with probe-rs
(well once #767 has made its way into a release anyways, use my probe-rs
fork in the meantime). Follow the dap42 flashing instructions to get going,
soldering wires is most likely necessary for the initial flash, but updates can
be delivered solely via USB when flashing the combined dapboot
image. Some
guides online may suggest soldering the SWO pin for tracing support, but this is
not necessary when using the Real-Time Transfer (RTT) I/O protocol.
Black Magic Probe (BMP) is an alternative, quite heavyweight debug probe
firmware that can run on some ST-LINK V2 clones. It provides conveniences,
such as directly hosting a GDB server from the debug probe itself. When compiled
the resulting firmware binary is roughly 100K in size, which exceeds the 64K
flash space available on the ST-LINK probes based on the STM32F103C8 MCU.
Normally this is not an issue however, since there is a secret: all original 64K
STM32F103 chips actually have 128K of flash, it has just been disabled due to
being untested or potentially unreliable (a form of product binning). Now the
issue is that there are cloned STM32 chips, and @twelho happens to have
a CKSF103C8, which only has 64K physically, in his ST-LINK V2 clone. This
makes flashing the Black Magic Probe firmware impossible. Since the Racklet
project values accessibility, and we cannot guarantee that this setup will work
for everyone, we went with the dap42 and probe-rs
combination instead.
(dap42 fits into 64K comfortably, even with the dapboot
DFU bootloader).
Out of the box when connecting the ItsyBitsy to an SWD debug probe it is quite likely that the connection will have parity errors or the probe will not be able to detect the chip at all, regardless of the communication speed used. This has been observed both with a dap42 flashed ST-LINK V2 clone as well as an FTDI FT232H based probe from Pine64. Additional grounding or improved power delivery did not improve the situation in either case. @twelho managed to finally trace the problem to a wrong value of the SWCLK pull-up resistor soldered to the ItsyBitsy. Adafruit is using a 2.2 kΩ resistor instead of a 1 kΩ one as stated by the SAM D5x datasheet on page 1907 to be "critical for reliable operation". Luckily this can be fixed without needing to solder SMD components by wiring an additional 1.8 kΩ resistor from SWCLK to 3.3 V, which will result in a combined resistance of 990 Ω, close enough to the guideline. This fix has completely eliminated all connection failures and instability for me. Make sure to double-check your connections to avoid frying your board and/or debug probe, remember that you do this at your own risk.
The SAM D5x series features a bootloader protection feature that prevents
writing to the first couple of kilobytes (configurable) of flash where a
software bootloader typically resides. This feature is enabled by default to
protect the UF2 bootloader the ItsyBitsy M4 Express ships with. It needs to be
disabled via OpenOCD before the chip can be used with probe-rs
. While
OpenOCD may be quite daunting for a beginner, this repository aims to provide
OpenOCD configurations that should mostly work out of the box for connecting to
the chip. (If you know of any simple OpenOCD guides, file an issue! We'd love to
have them linked here.) After fixing the SWD communication as described above
you may in an OpenOCD shell (e.g. via telnet
) execute
atsame5 bootloader
to check the size of the current bootloader protection region in bytes,atsame5 bootloader 0
to disable bootloader protection.
This process is fully reversible and only needs to be done once. Check the
details from the OpenOCD atsame5
documentation.
Please see CONTRIBUTING.md and our Code Of Conduct.
Other interesting resources include:
If you have any questions about, feedback for or problems with Racklet:
- Invite yourself to the Open Source Firmware Slack.
- Ask a question on the #racklet slack channel.
- Ask a question on the discussions forum.
- File an issue.
- Join our community meetings (see also the meeting-notes repo).
Your feedback is always welcome!
In alphabetical order:
- Dennis Marttinen, @twelho
- Jaakko Sirén, @Jaakkonen
- Lucas Käldström, @luxas
- Verneri Hirvonen, @chiplet