SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: stm32 bootloader example
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

stm32 bootloader example

Graham Kruk
Last updated: October 5, 2023 9:55 am
Graham Kruk 6 Min Read
Share
SHARE

A bootloader is a small program that runs when a microcontroller like STM32 first powers up. It initializes the device, performs basic checks, and can load firmware into the main flash memory. Using a bootloader allows you to update firmware without external programmers. Here is an overview of how to create a simple bootloader for STM32 devices.

Contents
Bootloader GoalsBootloader Code LocationEntering Bootloader ModeBootloader InitializationFirmware Update MechanismFlashing FirmwareBooting Main FirmwareDevelopment WorkflowDebugging the BootloaderBootloader Security FeaturesExample ProjectsConclusion

Bootloader Goals

The main goals of an STM32 bootloader are:

  • Initialize system clocks, peripherals, and memory
  • Check for forced entry to bootloader mode
  • Optionally erase flash, write new firmware, then reboot
  • Boot into main firmware if no update needed

This gives a way to load new firmware onto an STM32 over serial, USB, Ethernet, or other interface without needing a debugger or external flash tool.

Bootloader Code Location

The bootloader code must fit into the internal bootloader memory reserved on the STM32. This is around 16kB on most chips. The linker script must be configured to place the bootloader code and data into the correct memory region. The vector table also needs to be offset to the bootloader region base address.

Entering Bootloader Mode

The bootloader needs a way to detect if it should stay in bootloader mode or boot the main firmware. Some options are:

  • Button press on powerup
  • Special pulses on reset pin
  • Force bootloader mode via option bytes
  • Check a “bootloader request” variable in backup SRAM

The simplest approach is using the system reset button. Hold it down while powering up to enter bootloader mode.

Bootloader Initialization

The bootloader code needs to initialize enough system resources to function:

  • Setup clock sources and PLL
  • Configure SYSCFG and interrupts
  • Initialize GPIO for bootloader signals
  • Configure USART, I2C, or other interfaces
  • Setup systick for delays

It does not need to initialize unused peripherals to save space. The initialization code can often be shared or based on the main application firmware for efficiency.

Firmware Update Mechanism

The bootloader needs a way to actually update the main firmware. Some options are:

  • UART – Simple serial DFU protocol
  • USB – CDC-ACM or DFU class
  • I2C/SPI – External flash chip
  • Ethernet – TCP/IP based update
  • CAN – Automotive-oriented update bus

UART is the easiest protocol for initial testing. The firmware file can be sent over serial from a PC terminal program. Example open source DFU bootloaders like stm32-dfu or dfu-util provide portable DFU implementations.

Flashing Firmware

To program the new firmware received over the interface, the bootloader must:

  1. Erase the entire flash memory array
  2. Write each packet of firmware data to the flash
  3. Optionally verify the flash contents
  4. Reset and boot the new firmware

The STM32 HAL provides functions to erase and write to flash. The bootloader can use these to avoid low-level flash programming details.

Booting Main Firmware

After completing any firmware update or determining no update is required, the bootloader should branch to the main firmware entry point. This is done by loading the Stack Pointer (SP) and Program Counter (PC) from the firmware vector table.

To reduce bootloader size, it can disable interrupts and some peripherals before booting the firmware. This avoids having driver code for devices unused by the bootloader.

Development Workflow

A typical workflow for developing an STM32 bootloader is:

  1. Create bootloader project
  2. Write basic initialization code
  3. Add interface and DFU logic
  4. Implement flash programming functions
  5. Split main application into separate project
  6. Generate HEX file for bootloader
  7. Flash bootloader once onto device
  8. Iteratively update main firmware via bootloader

The bootloader only needs to be flashed initially using SWD or JTAG. After that, new firmware can be loaded solely through the bootloader interface like UART or USB.

Debugging the Bootloader

Debugging bootloader code brings some unique challenges:

  • Cannot debug before bootloader flashes
  • Limited space for debug logic
  • Hardware debugger access disappears when booting firmware

Possible techniques to debug bootloaders include:

  • Logging over serial or other interface
  • Debug mode entered via codeword or input sequence
  • Hybrid debug access using SWD and serial together
  • Simulate update process on simple test board first

Extensive use of LEDs as status indicators is very helpful. Being able to log messages over the firmware update interface provides visibility into the bootloader operation.

Bootloader Security Features

Some enhancements to provide security in STM32 bootloaders:

  • Cryptographic signature verification on firmware images
  • Write protection disable only after authentication
  • Validated firmware version numbers
  • Readback verify to detect flash tampering

The STM32 hardware encryption accelerators like AES can enable efficient signing of firmware files. U-boot and TrustZone options also available for advanced security.

Example Projects

Some open source STM32 bootloader example projects to study:

  • STLink – Simple serial DFU loader
  • MCUBoot – Secure bootloader
  • STM32-DFU – USB DFU bootloader
  • STM32duino Ethernet – Web update

Leveraging reference designs like these can help accelerate bootloader development and ensure best practices.

Conclusion

Developing a custom bootloader for STM32 provides a flexible way to field update device firmware. It requires planning the update interface, initialization sequence, flash programming, and branch to main firmware. With careful coding it can fit into 16kB or less. Example open source projects are available to learn from and speed up bootloader creation.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Bootloader Code Example
Next Article Cortex-M33 Bootloader
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

What is the debug subsystem in arm?

The debug subsystem in ARM processors provides hardware support for…

10 Min Read

What is the assembly level language of ARM?

ARM processors use a reduced instruction set computing (RISC) architecture…

8 Min Read

What is the difference between firmware and bootloader?

Firmware and bootloader are two important software components in many…

9 Min Read

What is ARM Cortex-R82?

The ARM Cortex-R82 is the latest high-performance real-time processor from…

7 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account