2021-07-01 07:41 PM
Hi :
I noticed bl SystemInit called before executing movs r1, #0 in STM32Cube_FW_F7_V1.16.1\Projects\STM32756G_EVAL\Examples\FMC\FMC_SDRAM_DataMemory\SW4STM32\startup_stm32f756xx.s while after executing LoopFillZerobss in STM32Cube_FW_F7_V1.16.1\Projects\STM32746G-Discovery\Examples\FMC\FMC_SDRAM_DataMemory\SW4STM32\startup_stm32f746xx.s.
Is there any difference between these two project?
In my project, application works fine when bl SystemInit called before executing movs r1, #0, but can't work when after executing LoopFillZerobss. I use 32 bit sdram IS42S328200D which almost same as STM32756G_EVAL.
2021-07-02 01:44 AM
Hello @周 剑强 ,
*Generally*, LoopFillZerobss should be called before SystemInit, as SystemInit is a C function, and it is required to have the .bss section zeroed and data loaded before executing them. As for your issue, how did you place your data sections for you applications? Could you provide the linker file?
Best regards,
@SBEN .2
2021-07-02 01:59 AM
SystemInit is supposed to be executed first in the preinitialization phase so it can get the processor clocking at the fastest speeds and bring the external memory interfaces up which the subsequent static initialization code can the unpack into.
In this regard the newer HAL/Cube stuff generally breaks the CMSIS expectations about the order in which things happen.
2021-07-02 02:01 AM
If global/static variables are placed into the SDRAM, FMC needs to be initialized (supposedly in SystemInit()) before the routine which initializes/zeroes them
in LoopFIllZerobss.
OTOH, asd SBEN.2 said above, SystemInit() may be a C function and if it uses global/static variables then you have sort of an egg/chicken problem.
At the end of the day, the startup code is part of the project, and if the project is not trivial - e.g. having non-continguous memory sections, and memories are not available without prior initialization as is in this case - the "standard" startup code is not sufficient. You then have to write/adjust the startup code according to your particular application and its needs.
JW
2021-07-02 02:21 AM
Hello @Community member,
Historically SystemInit initializes RCC to highest clock rate in SPL. In Cube, RCC is kept in its default state until it is explicitly configured. Even if you find some RCC configuration code, it is setting the register to their reset values.
Best regards,
@SBEN .2
2021-07-02 02:32 AM
Initialization in main() is too late, and not the order intended by ARM/Keil, where the memory subsystem are expected to be viable so the load regions can be unpacked properly.
This true for SDRAM and QSPI. Having the processor running at optimal speeds also mean the unpack or decompression processes complete the most quickly.
2021-07-02 02:48 AM
Hi SBEN:
Thanks for your answer, I attached my linker file.
Can you give me some advice?
And I have a question, the linker in STM32Cube_FW_F7_V1.16.1\Projects\STM32756G_EVAL\Examples\FMC\FMC_SDRAM_DataMemory and STM32Cube_FW_F7_V1.16.1\Projects\STM32746G-Discovery\Examples\FMC\FMC_SDRAM_DataMemory is almost same(expect the sdram size in memory area). so why they have difference in calling SystemInit?
2021-07-02 02:53 AM
More of a horse/cart issue to be honest.
SystemInit() is expected to run in a preinitialization state, it shouldn't be dependent on statics being initialized. The SPL authors understood this contract. You'll see very register centric code they had to bring up SDRAM on the EVAL boards, and examples I published for the F429I DISCO.
Also wonder how C++ constructors function properly if the code is mixed between Internal and External Flash, and data structures in SDRAM?
Using NOINIT or NOLOAD sections is a hack to cover the failure to get the system in to a viable state.
Ardunio has some better GNU/GCC startup.s examples where they make the linker build structures/tables describing the load regions, and space to copy or zero, so the process is automated and doesn't require dozens of symbols and duplicative code.
2021-07-02 02:56 AM
2021-07-02 03:41 AM
Either way, for MDK-ARM for example, scatter loading is done before SystemInit is called. I think it's he same for IAR too but I doubt loading to external memory is supported by those toolchains. Otherwise, having low boot time has its merits as you stated.