Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22018

STM32F429 hardfaults in __libc_init_array after jumping to application's Reset_Handler from bootloader. Why?

$
0
0

I’m creating a custom USB HS DFU bootloader for my STM32F429 project, using arm-none-eabi-gcc together with the CLion IDE. I’m having trouble jumping to the application code from the bootloader.

The CLion project consists of a bootloader target and a firmware image target, as well as a standalone firmware target that excludes the bootloader and enables me to debug the application code directly.The image target uses modified startup code (explained later), creates the image binary and signs it with a custom tool. This tool also merges the bootloader and image binaries into a single one.It places the bootloader at 0x00000000 (0x08000000 in flash) and the firmware at 0x0004000 (0x08040000 in flash). With a hex-editor I can confirm the signing and placing of the parts is performed correctly.

After flashing the merged binary, I re-flash the bootloader target and debug it. Just before the jump to the application, the vector table is relocated to the start of the firmware code, the address of the reset-handler is casted a void(void) function pointer and is called:

void DFUBootloader::startApplication(const uint32_t *imageBase){    // Copy vector table to ram be able to look at its contents in the debugger easily    VectorTable vectorTable;    memcpy(&vectorTable, imageBase, sizeof(VectorTable));    // get image reset handler function pointer    void (*imageResetHandler)() = reinterpret_cast<void(*)()>(vectorTable.resetHandler);    // disable interrupts    RCC->CIR = 0x00000000;    // relocate vector table to start of image binary.    SCB->VTOR = (uint32_t)imageBase;    __set_MSP(vectorTable.stackPointerInitValue);    imageResetHandler();}

From the debugger, I can confirm the jump to the firmware entry point is performed correctly. As execution continues from the firmware entry point, there is no more debug-info. I haven't found a way to "merge" the debug-info into one, but at least I can match the dissasembly to the modified startup_stm32f429xx.s assembly file, confirming the jump is successful. The modified startup file for the firmware image omits the call to SystemInit, since its job has been performed by the bootloader code already.

For some reason, the MCU seems to crash in the __libc_init_array routine.I suspect the relocation of the firmware from 0x08000000 (when it was built) to 0x08040000 in flash might have something to do with it, or maybe jump from the bootloader code leaves registers in a "dirty" state.I can't figure out what's going from from the disassembly alone, but it ends with a blx to 0x00000000. Not sure if that's deliberate or not.

In hope of taking away all of __libc_init_array's work, I have tried to make the firmware binary as bare-bones as possible, with only the linker script, the startup file and a main.c containing only a infinite while-loop, But alas.Does anyone know how to solve this?


Viewing all articles
Browse latest Browse all 22018

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>