Skip to main content
Explorer
July 2, 2021
Question

bl SystemInit execution time in startup_stm32fxxxx.s

  • July 2, 2021
  • 5 replies
  • 4019 views

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.

    This topic has been closed for replies.

    5 replies

    Visitor II
    July 2, 2021

    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​ 

    Explorer
    July 2, 2021

    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?

    Graduate II
    July 2, 2021

    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.​

    Visitor II
    July 2, 2021

    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​ 

    Graduate II
    July 2, 2021

    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.

    Super User
    July 2, 2021

    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

    Graduate II
    July 2, 2021

    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?

    U​sing NOINIT or NOLOAD sections is a hack to cover the failure to get the system in to a viable state.

    A​rdunio 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.

    Explorer
    July 2, 2021

    Hi Tesla DeLorean:

    Can you explain more details about "U​sing NOINIT or NOLOAD sections is a hack to cover the failure to get the system in to a viable state"?

    Visitor II
    July 2, 2021

    Hello @周 剑强​ 

    I've already asked the question internally, once I have the answer I'll update you.

    Best regards,

    Walid

    Explorer
    July 7, 2021

    Hi ​Walid ZRELLI:

    Is there any update?​

    Graduate II
    July 18, 2021

    As for the intention of design...

    https://github.com/ARM-software/CMSIS_5/blob/ee79c2197e6529f5274893e3764d0ded04aff22e/Device/_Template_Vendor/Vendor/Device/Source/GCC/startup_Device.S#L95

    In their templates ARM is calling SystemInit() before the data/bss initialization. The function is meant to initialize the base peripherals - CPU, buses and memories, which need to be functional so that further code can initialize the necessary memory regions.

    Explorer
    July 20, 2021

    what confused me is that sometimes ST call SystemInit() before the data/bss initialization, but sometimes not. but according other member's reply,U​sing NOINIT or NOLOAD sections can call SystemInit() after the data/bss initialization