Getting Started¶
This guide takes you from a clean checkout to a running bootloader and your first encrypted firmware update in under fifteen minutes.
Tool Ecosystem¶
The bootloader is one part of a three-tool chain. You need all three for a full firmware-update workflow:
| Tool | Purpose | Install |
|---|---|---|
| 🛡️ SECURE_BOOTLOADER (this project) | Runs on the MCU — decrypts, verifies, and flashes firmware | Build & flash with CMake (see below) |
| 🔐 EncryptBIN | Produces the encrypted .bin package on the PC |
pip install or pre-built binary |
| 📡 SecureLoader | Transfers the encrypted package to the device over serial | pip install or pre-built binary |
Prerequisites¶
# ARM cross-compiler (STM32 targets)
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi
# AVR cross-compiler (ATmega328P target)
sudo apt install gcc-avr avr-libc avrdude
# Build tools
sudo apt install cmake ninja-build make
# STM32 flashing — install STM32CubeProgrammer from st.com (CLI is auto-detected by CMake)
# or open-source alternative:
sudo apt install stlink-tools
# Optional: code quality tools
sudo apt install cppcheck clang-format
pip install lizard
EncryptBIN (produces the encrypted firmware package):
# From source
git clone https://github.com/niwciu/EncryptBIN.git
cd EncryptBIN && pip install -e ".[gui]"
# Or download a pre-built binary from the Releases page
SecureLoader (uploads the encrypted package to the target):
Open the repository in VS Code and accept the prompt to reopen in the Dev Container.
All toolchains (ARM GCC, AVR GCC, CMake, Ninja, Python) are pre-installed in the container image.
Install EncryptBIN and SecureLoader from source inside the container:
- Install ARM GNU Toolchain
- Install CMake
- Install Ninja
- Install STM32CubeProgrammer — the CLI (
STM32_Programmer_CLI) is auto-detected at CMake configure time - Download EncryptBIN and SecureLoader Windows installers from their respective Releases pages
Build¶
Each hardware target is configured once with CMake. After that, all build, flash, erase, and reset operations are available as predefined Ninja targets — no need to remember long CLI commands.
cd hw/STM32G070RB
# Configure once (Debug build, software CRC, default key and device ID)
cmake -S . -B Debug -G Ninja -DBUILD_TYPE=Debug
# Build all artefacts (.elf .bin .hex .lss)
ninja -C Debug
# Flash to target (requires STM32CubeProgrammer — detected at configure time)
ninja -C Debug flash
# Erase flash
ninja -C Debug erase
# Reset MCU
ninja -C Debug reset
cd hw/ATMEGA328P_ARDUINO_UNO_R3
cmake -S . -B Debug -G Ninja -DBUILD_TYPE=Debug
ninja -C Debug
ninja -C Debug flash # flash via avrdude
ninja -C Debug erase # chip erase
ninja -C Debug write_fuses # program fuse bits
ninja -C Debug read_fuses # read current fuses
ninja -C Debug read_flash # read flash back
Programmer auto-detection
CMake detects STM32_Programmer_CLI (STM32) or avrdude (AVR) at configure time and creates the flash, erase, and reset targets automatically. If the tool is found, you will see a status message like:
If the programmer is not on PATH at configure time, re-run CMake after adding it.
Production build
Add -DBUILD_TYPE=Release and supply your real device ID and AES key — see Build System for the full option reference.
Supply the AES Key and Device ID¶
The AES key and device ID are injected at compile time so they never appear in source files.
cmake -S . -B Release -G Ninja \
-DBUILD_TYPE=Release \
-DDEVICE_ID=0x00A0000BC22510E1 \
-DENCR_KEY="{0x21,0xBB,0xA1,0x8D,0xF4,0x9B,0x1E,0x77,0x26,0x6F,0x80,0x92,0x4C,0x35,0xE6,0xB8}"
See Build System — CMake Options for all accepted key formats.
Verify the Bootloader is Running¶
Connect a UART terminal (115200 baud, 8N1) to the target's UART2 pins.
On reset, the bootloader starts a 5-tick (500 ms) countdown. During this window it listens for a CMD_GET_VERSION byte (0x01).
Send 0x01 and you should receive:
0x41 # CMD_OK | CMD_GET_VERSION
0x01 0x00 0x00 0x00 # protocol_version = 1
<8 bytes> # device ID
0x00 0x08 0x00 0x00 # flash_page_size = 2048
If no valid command is received before the timeout expires, the bootloader jumps to the application (if a valid image is present) or performs a system reset.
Extend the Bootloader Window¶
Press and hold the USER button before or during reset. The bootloader detects the held button at startup and extends the stay-alive timeout to PUSH_BUTTON_DET_TIMEOUT ticks (60 seconds by default). Release the button; the timeout resets to PUSH_BUTTON_TIMEOUT ticks (300 seconds) after a confirmed press-release cycle.
This allows firmware updates without a host-side keep-alive loop.
Update Firmware (EncryptBIN + SecureLoader)¶
Once the bootloader is running on the device, the firmware update workflow is:
Step 1 — Encrypt your application binary with EncryptBIN:
encrypt-bin \
--input app_firmware.bin \
--output encrypted_firmware.bin \
--device-id 0x00A0000BC22510E1 \
--bootloader-id 0x00000001 \
--key "21 BB A1 8D F4 9B 1E 77 26 6F 80 92 4C 35 E6 B8" \
--app-version 0x20260301 \
--prev-app-version 0x20260201
The AES key and device ID must match the values the bootloader was compiled with.
Step 2 — Upload with SecureLoader CLI:
Or use the GUI:
The GUI provides a live progress view and handles connect → handshake → transfer → disconnect automatically.
Configuration file
EncryptBIN supports a configuration file so you don't repeat flags on every call:
See the EncryptBIN documentation for the config file format.
Run Unit Tests¶
The test suite runs entirely on the host — no hardware required.
After configuring, the following targets are available:
| Target | Description |
|---|---|
ninja -C Debug |
Build the test binary |
ninja -C Debug run |
Build and run all unit tests |
ninja -C Debug ccc |
Run tests and check code coverage (gcovr) |
ninja -C Debug ccr |
Generate HTML coverage report |
ninja -C Debug cppcheck |
Run static analysis with cppcheck |
ninja -C Debug ccm |
Code complexity metrics (lizard, console) |
ninja -C Debug ccmr |
Code complexity HTML report |
ninja -C Debug format |
Auto-format source files with clang-format |
ninja -C Debug format_check |
Check formatting without modifying files |
For the CRC module tests:
See Testing for a full description of the test suite and coverage setup.