2017-11-21 08:11 AM
I am having an issue where STM32F7 fails to start on reset. Here is a section of a startup code which fails:
IMPORT SystemInit
IMPORT __mainLDR R0, =SystemInit
BLX R0 LDR R0, =__initial_sp ; restore original stack pointer MSR MSP, R0 LDR R0, =__main BX R0 ENDPIt gets stuck on the line
BX R0 and never goes to main. Did anyone ever had similar issues? It only happens if I am trying to put something into external SRAM, though the SystemInit code stays the same regardless, and all registers before BX R0 look identical in both cases.
Any ideas? I am really stuck here
2017-11-21 08:55 AM
This isn't your main() function, but rather the Keil code to initialize the statics, ie copy initial content to RAM, and zero other areas. Once the __main function completes it calls your main function.
Your code in SystemInit() needs to completely initialize the external bus and memories so that data you have directed to external memory via the linker can be placed there. This means clocks, pins, peripheral, all the things need to bring up the interface and devices attached to it.
You should 'STOP' the debugger once your code crashes and see where it is, most likely in the while(1) loop of you Hard Fault Handler.
2017-11-21 10:10 AM
SystemInit() is not an issue as I can run with RW and ZI section located in external SRAM and it works. In this case I am trying to put just 1 array into external SRAM, and it is not used util way further in the code. The problem is it never gets past BX R0 as it does go to Hard Fault on this line.
2017-11-21 10:14 AM
So dump out the registers, look at the exception registers, and the context that has been stacked.
Is R0 an ODD or EVEN number? Does the stack look to be viable? Is the stack on the external memory? Going to be slower
Hard to debug through a key-hole
2017-11-21 11:00 AM
right before the call:
R0 0x080001C9
R1
0xE000ED08
R13
0x20023C48
R14
0x08013D95
R15
0x080002A4
MSP 0x20023C48
xPSR 0xA1000000
after the fault:
R0 0x2005000
R1 0x6804F1D5
R3 0xFFFB0E2A
R4 0x68025800
R6 0x0000009C
R13
0x20023C18
R14
0xFFFFFFF9
R15
0x0800F36E
MSP
0x20023C18
xPSR
0xA1000003
In this example everything is on the internal memory except for 1 array which is not used until way further in the code. stack size is 0x4000
2017-11-21 12:22 PM
How do you expect to execute the function without initializing variables? By the way, you have a piece of code from the M0 device. This code is not optimal for M7, it should not work at all.
Use the code below - as a template..section .text.Reset_Handler
.weak Reset_Handler .type Reset_Handler, %functionReset_Handler: ldr sp, =_estack /* set stack pointer *//* Copy the data segment initializers from flash to SRAM */
__LOADdata: ldr r0, =_sidata ldr r1, =_sdata ldr r2, =_edata__LOADdatax: cmp r1, r2 ittt ne ldrne r3, [r0], #4 strne r3, [r1], #4 bne __LOADdatax__bss_zero:
mov r0, #0 ldr r1, =_sbss ldr r2, =_ebss__bss_zerox: cmp r1, r2 itt ne strne r0, [r1], #4 bne __bss_zerox/* Call the clock system initialization function.*/
bl SystemInit/* Call static constructors */__LOADSDRAM: ldr r0, =_sisdramdata ldr r1, =_sqsdramload ldr r2, =_eqsdramload__LOADSDRAMx: cmp r1, r2 ittt ne ldrne r3, [r0], #4 strne r3, [r1], #4 bne __LOADSDRAMx/* Call the application's entry point.*/
bl main bx lr.size Reset_Handler, .-Reset_Handler2017-11-21 01:28 PM
The OP is using Keil not GNU/GCC, and setting the SP is not that problematic, it allows you to move the SP to external memory(s) after reset where you put some arbitrary internal SRAM address in the vector table
The '__main' function is Keil's run time to initialize the statics, does the equivalent to all the code you have in your GNU startup.s
SystemInit() must run first to initialize the hardware the external memories rely upon.
2017-11-21 05:35 PM
What bothers me is that the issue is not consistent. Exactly the same initialization code works in some cases and not the others. How is that code change way farther down the line can cause a fault so early on?
Even more weird, it would sometimes run and sometimes fail without changing anything in the code at all!
Almost seems like some random stuff inside of a CPU like branch prediction or something. Any idea how to trouble shoot this further?
2017-11-21 07:17 PM
__main unpacks structures created by the linker, this can include compressed data. Sensitive to data and ordering.
Truly squirrely behaviour can be had if the cache or flash subsystem is misconfigured. Make sure you have sufficient wait states.
Is this your own hardware? Can odd behaviour be replicated on DISCO, NUCLEO or EVAL boards? Check voltages and capacitors on VCAP pins.
Things to try, remove all HSE/PLL code from SystemInit() paths. Let the part run off HSI as it currently does, check for stability.
Using ST-LINK, J-Link or U-Link debug pod?
I'd disassemble and sanity check the failing image, add code to output internal state via USART, and without debugger. Doing a CRC of the image prior to calling SystemInit() to confirm integrity of image in FLASH, and as read by CPU. Repeat after SystemInit() to confirm higher speeds/settings don't break things.
2017-11-21 07:33 PM
If I understood correctly, you mean that compiler will look ahead, for example if it finds a call to SystemClock_Config() where HSE/PLL are set it will execute that section before main()?