2025-05-18 11:34 PM - last edited on 2025-05-19 2:00 AM by Andrew Neil
Solved! Go to Solution.
2025-05-24 2:43 AM - edited 2025-05-24 2:45 AM
Thanks for the response everyone. I kind of wrote a simple bootloader for this. I split the flash into different sections. sector 1 was assigned for boot loader, then i assigned 384KB each for two different slots for M7, and two slots of 512KB each for M4. Then I added CRC and Magic number to the bin file that i upload. When i upload my firmware, it goes to slot B for both cores. Then my bootloader checks if the CRC and magic number is valid or not. If it is valid i copy my slot B to slot A. This way i will always have a backup version. My new code is always stored to slot B if it's not valid it won't be used and customers can still get firmware upgrade later as slot A makes sure that device runs. Even if the copying between slots fails i will still have a valid copy of firmware in Slot B which will be copied upon restart. I also check if CRC values of slots are same or not. If they are the same i won't copy code from slot B. Using write protect, i made sure that bootloader can't be erased. So even if both slots fail i can still upgrade firmware through bootloader.
2025-05-19 5:19 AM
Using the supported STM32CubeProgrammer is probably a better choice. Freeze the product version once you verify correct functionality.
> What are the best practices for implementing this kind of user-friendly recovery flow?
Prior to starting the flash, modify option bytes to always boot into the bootloader. After flashing and verifying new configuration, re-modify option bytes to always boot into the user code.
2025-05-19 9:00 AM
Can you make your OWN USB-DFU Device via the examples?
Have that as a Boot Loader, and facilitate the user updating a deeper part of the FLASH for the application code. And don't erase the loader, ever
What other modes of connectivity do you have?
If the Boot Loader determines the application code image is corrupt it could fall back to a recover mode.
Perhaps look at how the ST-LINK and UF2 type loaders provide a faux USB-MSC, or make a USB-MSC RAMDRIVE from SDRAM, that the update could be dragged-dropped in by the user, and then only applied is complete and valid.
If you have an external QSPI NOR you could make that a USB-MSC to stash updates.
2025-05-19 12:16 PM
You may have to define your update process more exactly to get a better answer.
Any properly built updater won't brick a device. Manufacturer provided dfu tools aren't always production ready from what I've seen.
My personal preferred flow:
No banking, lower code region is permanent boot load code. Encrypted firmware image stored in external flash , or can be downloaded from USB. Once decrypted and validated, the old image is erased, new written to flash, at completion a magic number is written to the end of the last flash page. In case of interruption, Either USB drive or network stack + external flash to restart process. Once complete, jump to app. I use hardware button to enter bootload mode, or flag in rtcc memory to initiate external flash attempt.
2025-05-19 1:16 PM - edited 2025-05-19 1:25 PM
> One of the key things we want to bulletproof before launch is firmware recovery for end users
At this step, base your recovery procedure on the debugger connection (SWD connector of any kind and ST-LINKv3 MINIE adapter in SWD mode, unless you have reason to use other adapter). This is quick, cheap (*) and closest to bulletproof.
Dependence on the "system" bootloader and BOOT0 pin is a recipe for failure - unless you're very sure what you're doing. Later you can develop a custom bootloader, as others advise.
(*) Users will need certain software and smarts to recover via SWD debugger. Consider the CubeProgrammer as the main tool, later optimize the user experience if/as needed.
2025-05-20 10:29 PM
Using STM cube programmer is not an option as we need it to update firmware using our software.
2025-05-20 10:36 PM
I am looking into custom boot loader now. Haven't coded that before, looks like a huge learning curve. I don't have any other mode of connectivity. I use USB CDC class to receive a command from our software to jump to DFU mode and then upload code using DFU utils. Since the circuit is already built there is not option for an external QSPI NOR.
2025-05-20 10:43 PM
We have a custom software built for our device which sends a command, when received by the hardware jumps to DFU mode. At this point the software uses DFU utils to erase flash and upload CM4 and CM7 elf files. Once it is done normally the device restarts.This is basically the whole update process. It works most of the times, but i noticed that there are some rare cases where it fails mainly because the cable is loose or something. At this point the microcontroller just freezes. I normally uses ST link to get it running again but from a customer point of view it's not possible. I just want some mechanism to fall back to my old code or something which lets my device stay in DFU mode so that i can try uploading again.
2025-05-21 6:16 AM
Is there no way to enter DFU mode again? I suppose you could write a small bootloader that validates the image, then either jumps to DFU or the APP, but this is going to be half the way to a custom bootloader.
You'll have to weight the cost of a half baked updater vs customer frustration. There are definitely too many parts and pieces of the stm dfu utility for my customers to be able to handle.
If your budget allows, there are options for bootloaders.
Other notes: You can use a hardware reset pin to enter bootload mode with a custom bootloader by checking the reset cause.
2025-05-21 7:47 AM
> I just want some mechanism to fall back to my old code or something which lets my device stay in DFU mode so that i can try uploading again.
You're using the system DFU bootloader, right? Setting option bytes will do this.