This repo is cross-platform UF2 Bootloader projects for MCUs based on TinyUSB
.
├── apps # Useful applications such as self-update, erase firmware
├── lib # Sources from 3rd party such as tinyusb, mcu drivers ...
├── ports # Port/family specific sources
│ ├── espressif
│ │ └── boards/ # Board specific sources
│ │ └── CMakeLists.txt # CMake project for this port
│ └── mimxrt10xx
├── src # Cross-platform bootloader sources files
Supported features are
- Double tap to enter DFU, reboot to DFU and quick reboot from application
- DFU with MassStorage (MSC)
- Self update with uf2 file
- Indicator: LED, RGB, TFT
- Debug log with uart/swd
Not all features are implemented for all MCUs, following is supported MCUs and its feature
| MCU | MSC | Double Reset | Self-update | Write Protection | Neopixel | TFT |
|---|---|---|---|---|---|---|
| ESP32 S2/S3/S31/P4 | ✔ | Need RC | ✔ | ✔ | ✔ | |
| K32L2 | ✔ | ✔ | ||||
| LPC55 | ✔ | ✔ | ✔ | |||
| MAX32 | ✔ | ✔ | ✔ | |||
| iMXRT | ✔ | ✔ | ✔ | ✔ | ||
| STM32F3 | ✔ | ✔ | ✔ | ✔ | ✔ | |
| STM32F4 | ✔ | ✔ | ✔ | ✔ | ✔ | |
| STM32H5 | ✔ | ✔ | ✔ | ✔ | ||
| STM32H7 | ✔ | ✔ | ✔ | |||
| STM32L4 | ✔ | ✔ | ✔ |
Please refer to supported boards for the complete list of supported MCUs and boards.
Following is generic compiling information. Each port may require extra set-up and slight different process e.g esp32s2 require ESP-IDF.
Clone this repo with its submodule
git clone git@github.com:adafruit/tinyuf2.git tinyuf2
cd tinyuf2
git submodule update --init
Firstly we need to get all submodule dependency for our board using tools/get_deps.py script with either family input or using --board option. You only need to do this once for each family
python tools/get_deps.py stm32f4
python tools/get_deps.py --board feather_stm32f405_express
Then build a board from the repository root with CMake, the way CI builds it (Espressif uses ESP-IDF's idf.py, see
its README):
cmake -B build -G Ninja -DBOARD=feather_stm32f405_express ports/stm32f4
cmake --build build
The bootloader images land in ports/<port>/_bin/<board> (-DARTIFACT_PATH=<dir> puts them elsewhere). Each
application the port supports (self-update, blinky, ...) is built as its own CMake project in build/apps/<app>, its
UF2 in _bin/<board>/apps.
Each port adds a flash target for each tool it supports; install the tool first, then build the target. For example feather_stm32f405_express through the STM32 ROM DFU bootloader:
cmake --build build --target tinyuf2-dfu-util
| Target | Tool | Ports |
|---|---|---|
tinyuf2-jlink |
J-Link JLinkExe |
boards whose board.cmake sets JLINK_DEVICE |
tinyuf2-stlink |
STM32_Programmer_CLI |
stm32f3, stm32f4, stm32h5, stm32h7, stm32l4 |
tinyuf2-pyocd |
pyOCD | kinetis_k32l2, lpc55, mimxrt10xx |
tinyuf2-dfu-util |
dfu-util to the STM32 ROM DFU bootloader | stm32f4, stm32h5, stm32l4 |
tinyuf2-openocd |
OpenOCD | ch32v20x (WCH's fork), maxim (ADI's) |
tinyuf2-sdp |
sdphost/blhost to the i.MX RT ROM |
mimxrt10xx, see its README |
tinyuf2-teensy |
teensy_loader_cli |
teensy40, teensy41 |
tinyuf2-erase-jlink |
J-Link JLinkExe erase |
boards whose board.cmake sets JLINK_DEVICE |
tinyuf2-erase-external-jlink |
J-Link JLinkExe erase of the external flash |
mimxrt10xx |
<app>-uf2 |
uf2conv.py --deploy to the bootloader drive |
each application a port builds, except espressif |
Make's ST-LINK, st-flash, pyOCD and DFU erase helpers are removed: erase with the tool's own command for your chip.
To compile for debugging configure with -DCMAKE_BUILD_TYPE=Debug, this will mostly change the compiler optimization
(-Og in place of the default MinSizeRel's -Os)
cmake -B build -G Ninja -DBOARD=feather_stm32f405_express -DCMAKE_BUILD_TYPE=Debug ports/stm32f4
cmake --build build
Should you have an issue running example and/or submitting an bug report. You could enable TinyUSB built-in debug logging with optional -DLOG=.
- LOG=1 will print message from bootloader and error if any from TinyUSB stack.
- LOG=2 and LOG=3 will print more information with TinyUSB stack events
cmake -B build -G Ninja -DBOARD=feather_stm32f405_express -DCMAKE_BUILD_TYPE=MinSizeRel -DLOG=1 ports/stm32f4
cmake --build build
By default log message is printed via on-board UART which is slow and take lots of CPU time comparing to USB speed. If your board support on-board/external debugger, it would be more efficient to use it for logging. There are 2 protocols:
-DLOGGER=RTT: use Segger RTT protocol- Cons: requires jlink as the debugger.
- Pros: work with most if not all MCUs
- Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package.
cmake -B build -G Ninja -DBOARD=feather_stm32f405_express -DCMAKE_BUILD_TYPE=MinSizeRel -DLOG=2 -DLOGGER=RTT ports/stm32f4
cmake --build build