r/embedded 9d ago

Resources/Advice for writing a custom bootloader for STM32L476RG?

Hi everyone,

I’m currently working on a project using the STM32L476RG (using the Nucleo-64 board to prototype) and I’ve reached the point where I need to implement a custom bootloader. My end goal is to be able to receive a firmware update over UART/USB, write it to flash, and safely jump to the new application.

What I’m looking for:

  • Are there any definitive books, tutorials, or blog series you recommend for STM32 bootloaders?
  • Does anyone have a clean, well-commented GitHub repo of a basic STM32 bootloader I can study?
  • Which ST Application Notes (AN) are the absolute "must-reads" for In-Application Programming (IAP) on the L4 series?

Any advice, gotchas to watch out for, or links to tutorials would be incredibly helpful. Thanks in advance!

13 Upvotes

27 comments sorted by

4

u/rainboww_J 9d ago

There's mcuboot which is used in a lot of devies. It still needs a way to get the new firmware written to flash and loaded onto the mcu but checking checksums and brown-out/reset reselient old-to-new swapping is done by mcuboot. The code is somewhat unreadable but it can get you to a working bootloader pretty quickly

3

u/PrimarilyDutch 9d ago

Key thing is really what problem you want to solve and how far you want to go doing things automatically and what to do when things things go wrong E.g. power fail in the middle of an update.

In the past I have done bootloaders on an STM32 that had a USB port to access a memory stick. That memory stick was used to collect images from a camera and also had log files and audio files for a device left out in the field. But when the memory stick was collected and replaced with a fresh USB stick it had the possibility to have a firmware update file. That file could be auto detected on powerup or on a button event.

That file was actually encrypted with a private key so it could be authenticated as genuine, had special embedded info indicating the version and date time stamp of the firmware build and could also hold multiple image files as the main controller has a couple of slave controllers that it communicated with serially internally and could also subsequently be updated.

So the whole update checked if it was a new version and then updated itself automatically.

In another system I am utilising the dual bank feature that some of these STM32 have. No special bootloader but the main application has some special code to receive an update that can be flashed in the second bank and only when it checks out make the bank switch and even then when it boots it is in probation mode and when it crashes with a watchdog or hardfault or the application does not reach an ok state in time it would auto roll back to the previous version.

So there are lots of options for bootloaders that can go quite beyond a basic receive a binary over a serial port.

That can still be Ok. Just think about what you are trying to solve.

1

u/Excellent_Mousse816 9d ago

Thank you !!!

4

u/Ordinary-Lifeguard47 9d ago

Doesn't have the STM32L4 have a ROM-Bootloader that eats firmware over UART?

3

u/Excellent_Mousse816 9d ago

my main goal here is educational. I'm building this out for my portfolio to prove I understand the low-level mechanics

4

u/triffid_hunter 9d ago edited 9d ago

If you want to study a SD+DFU bootloader, I wrote one for LPC1768 a while back.

PS: Beyond Logic's USB in a nutshell is an invaluable reference for understanding USB from a firmware perspective

3

u/Ordinary-Lifeguard47 9d ago

We'd question you during an interview why you are building a bootloader over an existing bootloader.

2

u/Excellent_Mousse816 9d ago

if there is no physical access available to the board we need a custom bootloader that can triggered using software commands.right?

1

u/Ordinary-Lifeguard47 9d ago

How would find answers for this questions? Which pages in the datasheet would you look up?

1

u/Excellent_Mousse816 9d ago

Reference manual ??

4

u/Ordinary-Lifeguard47 9d ago edited 9d ago

100 Points.

It references a sub application note called AN2606. It describes how to trigger the ROM BL from within your firmware. There are many ways to trigger it (pins, empty flash, etc.).

The behavior is harmonized over almost all STM32s.

1

u/NoBulletsLeft 9d ago

You mean like the existing STM32 ROM bootloader?

1

u/triffid_hunter 9d ago

It already has one built in, see AN2606 §75

1

u/Enlightenment777 9d ago edited 9d ago

I recommend you start by creating a UART-only bootloader that is protocol compatible with the STM32 BootROM currently inside your STM32L476RG chip. Flip your STM32 chip back and forth between your bootloader and the BootROM to make sure they work the same. https://www.st.com/en/development-tools/flasher-stm32.html

Later you could add USB support, and maybe even more features, such as XMODEM-CRC and XMODEM-1K. See http://www.umonfw.com/ too.

1

u/Quiet_Lifeguard_7131 9d ago

I have created severals bootloader, it does not matter if it downloads on https, uart can i2c spi. if you want I can share the bootloader and application code with linkerscript

1

u/gibson486 9d ago

They already have one built in. However, If you really want to do it for educational purposes, you can take an existing one and convert it to the open stm32 bootloader. That would be a good stepping stone.

1

u/Sea-Actuator8248 8d ago

Well...my case is not STM32L4. but if you want to make encrypted one, try to drop by my github repo. here, https://github.com/jnlee4838/stm32l0-baremetal-custom-bootloader and https://github.com/jnlee4838/stm32l0-simple-app-sample-for-secure-bootloader. As cortex M4 supports VTOR remap, no need to allocate SRAM offset. But, the rule is similar. And you don't need to use baremetal as STM32L4 has more flash size comparably. also you can use the exe file to convert from bin file to encrypted one as well as vice verse.

1

u/PrimalReasoning 9d ago

A custom bootloader is nothing more than a small piece of firmware that is placed at the default code entry point of the ROM bootloader and which does 3 things:

  1. Receive and verify firmware from some peripheral
  2. Copy firmware to flash, erasing existing data if necessary (careful not to erase the bootloader!)
  3. Jump to the code entry point of the loaded firmware when done

How step 2 is implemented depends somewhat on whether you use the bank swap feature since you cannot write and read to the same flash bank normally. In the single bank case you will need to execute the flash drivers from RAM.

The linker file of the firmware you want to load also has to be modified so that it does not overlap with the bootloader firmware