2024-08-29 12:28 PM
How can you write a program that updates itself for an STM32, eg. for an STM32F103C8?
I'm not talking about a bootloader, since (as far as I know), a bootloader lives from (say) 0x08000000 to 0x08001000 in Flash and then updates another program (another part of flash), in this case, eg., starting at 0x08001000.
One option I thought of would be to run the code not from flash but from RAM/SRAM, like in this question and then update the flash memory, reset, and boot from flash. However, the answers there involve booting from SRAM, which I think I may not want to do. (One of the reasons being that this must run in production, without a debugger.)
Rather, what makes more sense to me is to flash the program to the STM32 flash, as usual, at 0x08000000, run the code from flash, and then, at runtime, upon receiving the update command from the user, move the entire program (or perhaps just the strictly necessary parts) to RAM/SRAM, continue execution from SRAM, and then update the entire flash memory and reset the MCU and boot from flash, again, as usual. (In particular, you never boot from SRAM, and you only run code from SRAM when you want to update.)
So, can this (or something logically similar) be done, in order to have a program that updates itself completely?
Now, I know this is possible if you only want to update a subset of flash memory (eg. I think VIA does a partial update of flash memory at runtime in order to update keyboard mappings without reflashing the keyboard and without as much as reconnecting your keyboard), but I wonder how it can be done if you want to update the entire contents of flash memory.
2024-08-29 01:44 PM
@Tesla DeLorean wrote:Well should definitely be possible to migrate the firmware into RAM, I'd approach vis code in Reset Handler, and immediately after the Vector Table.
As there's no DFU in ROM, overwriting the FLASH gets to be a proposition with a lot of risk, and very few avenues for recovery.
- Yes, that sounds like something I could use. Could you please give more detail about doing this using a Reset Handler and the Vector Table?
- About recovery: is the STM32 device gets bricked, is it possible to recover by reflashing the keyboard using an ST-LINK programmer?
2024-08-29 02:04 PM
Build for 0x20000000 base address, with whatever split for data, rebase the Reset_Handler entry point, copy the entire FLASH image to RAM, set SCB->VTOR to 0x20000000 per SystemInit() and fork.
You could use ST-LINK with SWD/JTAG for recovery.
2024-08-29 05:52 PM
Thank you very much.
Can you elaborate more on the first part of the answer, please?
"Build for 0x20000000 base address, with whatever split for data, rebase the Reset_Handler entry point, copy the entire FLASH image to RAM, set SCB->VTOR to 0x20000000 per SystemInit() and fork."
Eg. when you say "Build for 0x20000000 base address" do you mean to change the base flash address in the .ld linker script from 0x08000000 to 0x20000000?
What do the other things mean?
I'm still in the process of learning STM32 programming in general, and STM32F103 programming in particular.