cancel
Showing results for 
Search instead for 
Did you mean: 

is there a need for early initialization, SystemInit ?

mete
Senior II

So the startup code first sets the stack pointer, and then jumps to SystemInit for early initialization, then copies the initial values of data and zeroes bss region and then kickstarts C startup. Is there anything hardware related that has to be done as early as possible, which cannot be or should not be done after the C application main is started ? or is it just to setup the system freq. so the data and bss region initialization completes faster ?

7 REPLIES 7
STTwo-32
ST Employee

Hello @mete

as you have seen SystemInit setup the system frequency so the data and bss region initialization completes faster. For the hardware needs, we have to relocate the Vector table in internal Flash (or SRAM) and set the  FPU.

Best regards.

STTwo-32

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Why is there a need to relocate the vector table ? VTOR etc. should already have the correct value since Reset_Handler is already working.

About the FPU initialization, that is I guess because it has to be done if the application is compiled for hard floating point and FPU has to be initialized before any FP instruction. That is a valid point and a good example but assuming the C startup runtime does not use floating point it can still be done in main I think.

gbm
Lead III

The original goal behind SystemInit() was to initialize the possible external memory interface, so that the memory sections could be initialized before the main() is invoked. In microcontrollers without external memories, it is just a placeholder. Many vendors feel obliged to put something to SystemInit(), which usually doesn't make sense (like setting the clock control registers to their default values, which they already contain) or spoils something (like the setting of VTOR). Between these, the FPU setup in SystemInit() looks outstandingly reasonable.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Thanks @gbm , that makes sense.

VTOR typically resets to ZERO and relies on the zero address mapping via BOOTx pins to establish initial real address of code being executed. You can set SCB->VTOR to the vector table symbol, saves #define nonsense and allows the linker to do it's job.

ARM CMSIS expects SystemInit() to bring the system, related clocks, pins, and external memories up sufficiently for the C run-time code to be able to initialize all statics, constructors, etc. Doing a lot of this stuff in main() isn't really appropriate, and some halfassery that ST gets away with some of the time. Honestly if I'm breakpointed to the beginning of main() I'd like to be able to see ALL the memory and breakpoint other code or memory accesses without stepping further. Perhaps my expectations are too high?

Constructors might reasonably expect the FPU, stack and heap to all be functional already. And the MCU not be running at slowest speed as memory is cleared/copied.

If you have a boot loader you might see different vector table addresses, and you might want to address clocks, pins, and memories there once, before handing off to the application code, and not repeating any of that later causing delay and instability. Say your want the app running from QSPI/OSPI memory, and max MCU speed/performance.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks @Tesla DeLorean for the detailed answer. I understand there wont be a single answer to this, and I should have put a boundary on the system for my question, which would be a single MCU (no external memory) and a C application. In addition to external memory, I understand the point regarding FP. I did not have C++ in mind so I was not expecting anything else in the application to run before main, in the case of C++, I definitely understand FPU init to run before ctors.

I am not saying to do all these things (clocks etc. other than external mem init, and probably FPU) very late in the application, but what would it be different to do this before data and bss initialized and after. Only thing I can think of is initialization speed (which I am not saying not important). What I was actually wondering is what is essential and must to do, not just nice to do or best to do, and external mem and FPU init definitely fits to essentials list.

I am not sure I understand the point regarding VTOR. AFAIK, when Cortex-M33 initializes, VTOR has an implementation defined initial value which on STMH5 is supplied by I believe sbs_init_vbr_ns and _s for TZ, and before jumping Reset_Handler, it has VTOR already in place. If I remember right, I checked this and VTOR contains NSBOOTADD just after jumping to Reset_Handler.

 

Pavel A.
Evangelist III

@Tesla DeLorean 

> if I'm breakpointed to the beginning of main() I'd like to be able to see ALL the memory and breakpoint other code or memory accesses without stepping further. Perhaps my expectations are too high?

Yep, too high. Setup of external flash, RAM... you know. External parts depend on clock config, FMC, and what not. Too complicated for SystemInit. (your earlier advice to initialize clocks and external memories in bootloader so that the "main app" sees them ready, resolves this chicken/egg dilemma in elegant way)