I've been tasked with developing a bootloader to enable a device to do a firmware update via USB.
I'm sure this question has been asked in various forms many times, but I'm new to the world of STM32 and ARM and I'm having a bit of trouble putting all the information I've been finding together.
First off, I'll describe more specifically what we would like to do. We want a simple, reliable way to upgrade our devices in the field without requiring service technicians to bring chip programmers with them.
Ideally, a technician would use a hidden factory menu on the device to enable bootloader update mode, at which point the device would reboot into the bootloader and wait for the USB stick to be plugged in. After the update, the device would reboot back into the application. These devices are large appliances that could potentially be difficult to disconnect from power, so all resets would need to be initiated by the code.
Our starting point for this endeavour is the STM322xG-EVAL_USBH-FS example project. So far I've successfully modified the example to match our board layout, and I've been able to successfully flash our application from the bootloader and have it start automatically once the vector table location was updated in the application.
The current flash settings are (let me know if you need more information, the rest of the code is essentially the same as the example):
Application start address (linker setting) 0x08008000
However, after the bootloader flashes the app, the device will no longer go into the bootloader. To be able to run the bootloader again, I have to erase the chip (using a ST-LINK V2 programmer and the ST-LINK Utility) and reflash the bootloader. Simply reflashing the bootloader while the application is loaded still results in the application launching each time, bypassing the bootloader. I checked the bootloader size to make sure it wasn't being partially overwritten and it looks okay (bootloader size is listed as 0x58A8 by the ST-LINK Utility).
So right now my questions are:
- Where do I start in continuing to debug this? What could cause this behavior of the bootloader not running on subsequent boots after successfully flashing the application until I do a full chip erase? Is there a non-volatile pointer that tells the chip where the table is located so after the update it points to the application? Like I said, I'm new to ARM and still learning how this all works.
- What is considered best-practice for jumping to the bootloader from the application? Should the application write a value into flash/RAM that the bootloader then checks to see if it needs to enter update mode?
- Are there any standard best-practices for validating the firmware before flashing it like a simple checksum function in the bootloader? How should version/model information be encoded so it won't just blindly flash whatever it's been given?
- Are there any other considerations I should be aware of that I haven't mentioned?
Thanks in advance for any help and for pointing me in the right direction with this.