2015-06-26 01:35 AM
Dear community,
if I look for the contents of the startup.s file of e.g. a STM32F373RB firmware then I recognize following lines:
LDR R0, =SystemInit ; load a word into R0 e.g. the address of SystemInit
BLX R0 ; link and branch to address stored in R0
LDR R0, =__main ; load a word into R0 e.g. the address of main
BX R0 ; branch to address stored into R0
ENDP
If I understand this code correctly then SystemInit should be called first, followed by main. I introduced a USER_var into the SystemInit to see how it is executed. In the main – section I introduced a routine to output USER_var.
My findings are that USER_var can be initialized with a certain value e.g. int USER_var = 10; however if I assign other values e.g. inside the SystemInit() or SetClock() function to check what exactly happens there, I doubt this function is not called as expected. If I call SystemInit() from main then I can see that it is really executed as expected. Since I use the KEIL compiler it might be a specific problem with the compiler however maybe someone here knows what happens. I would be very happy if someone would post her/his opinion.
2015-06-26 03:35 AM
Step trough your code with the debugger to see what's going wrong.
What ide are you using?2015-06-26 07:52 AM
This is not your main() function, it's a function that initializes the C runtime space (statics), and then calls your main() function.
SystemInit() runs before that, and cannot rely on static variables being initialized in RAM. Things like ''static const'' which are in FLASH will be fine.Why does it run SystemInit() first, basically so you can get the processor, peripherals and external memory functional *before* you try to access or copy data to them.2015-06-26 01:01 PM
I did following:
//system_stm32fxxx.h
extern uint32_t USER_var;
//system_stm32fxxx.c
uint32_t USER_var = 0;
static void SetSysClock(void) {
USER_var |= 1;
// here comes the default code of SetSysClock
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
USER_var |= 255;
}
}
// main
Since the CPU is not reset after SystemInit I would expect the first bit of USER_var at least to be toggled but it is not the case. Only if I call this function from main I can see that the first bit is set. If it is not possible to relay e.g. a value from the initialization into main I also don’t know how to deal with STM’s recommendation to add an error handler to the SetSysClock() function. However it could also be that I did something wrong.
2015-06-26 01:10 PM
You calling __main causes the USER_var = 0; to occur
The suggested error handling is to switch to the HSI if the HSE doesn't start, and to bring the PLL up in a fall-back manner. You could also output state via a GPIO pin, or stop execution.You could create some variables out side the scope of the compiler/linker