I have developed a Firmware upgrade Over The Air (FOTA) mechanism for my custom F7 board that seems to work properly, but hard faults during the subsequent reboot process of the main application.
Thanks to Clive1's suggestions I was able to fashion a reliable bootloader that checks a pre-defined RAM location for a pre-defined value. This value sends the program to either 1) the main application (at 0x8040000), 2) the firmware upgrade flash function (co-resides with the bootloader sector at 0x8000000), or jumps to the DFU (0x1FF00000).
The FOTA function in the main app downloads a binary image file over the air to RAM. The RAM start location is pre-defined so that both the app and bootloader know its location. Once the binary image has been successfully downloaded to RAM, the file size is also stored in a pre-defined RAM location. The app then does a system reset passing control back to the bootloader.
*((unsigned long *)0x2007FEE0) = fw_upgrade_file_size;
*((unsigned long *)0x2007FEF0) = 0xDEADF00D; // Boot to Flasher
The bootloader then flashes the binary image to the app location (0x80400000). It then sets the stack pointer and VTOR to the appropriate application address and jumps to this address.
case 0xDEADF00D: //Do FW upgrade then jump to main app
appStack = (uint32_t) *((__IO uint32_t*)APPLICATON_ADDRESS);
appEntry = (pFunction) *(__IO uint32_t*)(APPLICATON_ADDRESS + 4);
SCB->VTOR = APPLICATON_ADDRESS;
The code successfully arrives at the app location and begins to run the startup code. However, something causes a hard fault in/around the subsequent startup (_stm32f765xx.s) code bl __libc_init_array. I have stepped through the code and it appears that the processor is skipping over this array initialization. The TrueStudio Fault Analyzer says:
This seems to have something to do with data alignment, but I have no clue where. I have seen other threads that talk about DFU data alignment issues. But I am not using DFU. I am simply programming the image directly to flash. The size of the binary image that gets flashed is 0x2B1EF, so I pass the size value of 0x2B1F0 to the flasher in the bootloader hoping that it may avoid some sort of data alignment/boundary issue with the flasher. to no avail.
The other curious thing is, if I load flash manually using J-Link the __libc_init_array. code executes and application runs properly.
I'm pulling what's left of my hair out trying to figure out what's going on. If anyone has any suggestions, I'm all ears.