This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM2432: Do we need to use "--ram_model" option as an initialization model in linker runtime environment?

Part Number: AM2432
Other Parts Discussed in Thread: UNIFLASH

Hi Expert,

When I checked linker option in SDK examples, they are using --ram_model as an initialization model in linker option. I guess it is because gMpuConfig variable should be initialized before MPU_init().  In the example, in "boot_armv7r_asm.S", code branched to bypass_auto_init skipping __TI_auto_init. Can we use "--rom_model" option as well?

Regards,

Moonil

  • Hi Moonil,

    Choose a startup model based on the needs of your application. The ROM model performs more work during the boot routine. The RAM model performs more work while loading the application.

    If your application is likely to need frequent RESETs or is a standalone application, the ROM model may be a better choice, because the boot routine will have all the data it needs to initialize RAM variables. However, for a system with an operating system, it may be better to use the RAM model.

    Refer to 8.3. Run-Time Initialization — TI Arm Clang Compiler Tools User's Guide for details.

    Best regards,

    Ming

  • Hi Ming,

    I tried "empty example" in SDK with only changing RAM model to ROM model in linker option. It went to assert as below.

    Could you let me know the reason? This was my question mentioning MPU_init. I was wondering if there is any limitation to using the linker option in SDK due to the working with code generated by syscfg. 

    Regards,

    Moonil

  • Hi Moonil,

    I made the same change (RAM model to ROM model) and re-built the "/empty_am243x-evm_r5fss0-0_nortos_ti-arm-clang" of the MCU+ SDK 08.01.00.36 for AM243x and tested the it on the AM243x EVM. It worked fine.

    Which MCU+ SDK version you used and what platform were you using AM243x EVM or LP?

    Best regards,

    Ming

  • Hi Moonil,

    I also made the same change in "/empty_am243x-lp_r5fss0-0_nortos_ti-arm-clang" and tested on AM243x LP. It works fine also.

    Make sure you did flash the SBL_NULL into the OSPI or SD card. AM243x MCU+ SDK: EVM Setup (ti.com)

    Best regards,

    Ming

  • Hi Ming, 

    I found that SBL_NULL was overwritten by another one during the test. Issue was resolved.

    Is there a way to flash SBL from CCS to target directly?

    Thanks,

    Moonil

  • Hi Moonil,

    You can set the bootmode to UART, then follow the instructions in AM243x MCU+ SDK: EVM Setup (ti.com). It will overwritten the current boot image with the SBL NULL.

    Best regards,

    Ming

  • Hi Ming, 

    My question was about the way using CCS menu like "Run->Load Program" in order to write SBL to NOR Flash directly but not using the command line in CMD window. Please let me know if there is such a way.

    I have another question about "--ram_model". When I try "restart" in CCS, malloc fails happened as below,

    I guess it is because heap memory (".sysmem") is not initialized when "restart". Could you clarify the reason? "--ram_model" does not allow "restart"?  FYI, when using "--rom_model", there is no such problem.

    Regards,

    Moonil

  • I guess it is because heap memory (".sysmem") is not initialized when "restart". Could you clarify the reason? "--ram_model" does not allow "restart"?

    When using --ram_model then Initializing Variables at Load Time (–ram_model) is performed. That means when CCS downloads the program the initialisation of variables is done at load time, and if "restart" is done after the restart variables in initialised sections will have their values from the previous run.

    Whereas --rom_model has extra code and copy tables to initialise the variables each time the program is reset, and that allows use of "restart".

  • Hi Chester,

    Thank you for clarifying the difference between the initialization of both models. From your explanation, I understood, for use of CCS, only --rom_model must be used to avoid any confusing situation caused by "values from the previous run" when using --ram_model. Is it correct?

    How about the case not using CCS, that binary built with "--ram_model" is flashed to target by using uart_uniflash.py and target is "warm" reset? I guess the same with "values from the previous run" could happen. Could you clarify this case as well?

    This question is about whether or not the release version of the product including "warm reset" can be built with "--ram_model" and additional initialization implementation is required on ".sysmem".

    Regards,

    Moonil

  • Hi Moonil,

    There is a JTAG version of the uniflash program which can write a boot image into the OSPI flash, but it is not included in the MCU+ SDK yet. It is planned to be included in the next MCU+ SDK 08.02.00 for AM243x. I can send you the CCS project.

    As of why the "restart" does not work for you, it is purely depend on how do you initialize your variables during the initialization phase. If your program depends on the initial value of RAM at the "cold reset", then you most likely will have problem with the "restart", even with the "warm reset" (which will not reset the RAM).

    The rule of the thumb is that you will need to initialize all your important variables/buffers in your program with either extra code (ROM model) or load time memory copy (RAM model).

    Best regards,

    Ming 

  • Hi Ming,

    Please send JTAG version of the uniflash program. Do you need my email to send it?

    I still found issues for both, --ram_model and --rom_model. 

    1) --ram_model : I tried putting the code initializing heap(".sysmen") as below, but malloc() still failed when "restart" with "--ram_model". Could you let me know if this is the way you mentioned for initialization? Otherwise, please share any example.

    _system_pre_init() in "boot_armv7r.c"

    extern uint32_t __BSS_START;
    extern uint32_t __BSS_END;
    extern uint32_t __SYSMEM_START;
    extern uint32_t __SYSMEM_END;

    int _system_pre_init()
    {
        uint32_t bss_size = ((uintptr_t)&__BSS_END - (uintptr_t)&__BSS_START);
        uint32_t sysmem_size = ((uintptr_t)&__SYSMEM_END - (uintptr_t)&__SYSMEM_START);

        memset((void*)&__BSS_START, 0x00, bss_size);
        memset((void*)&__SYSMEM_START, 0x00, sysmem_size);
        return 1;
    }

    "linker.cmd"

    GROUP {
        .bss: {} palign(8) /* This is where uninitialized globals go */
        RUN_START(__BSS_START)
        RUN_END(__BSS_END)
        .sysmem: {} palign(8) /* This is where the malloc heap goes */
        RUN_START(__SYSMEM_START)
        RUN_END(__SYSMEM_END)
        .stack: {} palign(8) /* This is where the main() stack goes */
    } > MSRAM

    2) --rom_model : I found an issue in "--rom_model". After flashing SBL_NULL, "empty example" in SDK with ROM model in linker option does not assert but MPU is not correctly configured as below. I think the reason is, SRAM(gMpuConfig) has all zero by reset but gMpuConfig is not initialized yet by "__TI_auto_init" when __mpu_init is called in "boot_armv7r_asm.S". I think MPU must be configured with correct gMpuConfig values generated by syscfg. Can you reproduce this at your end? I think __mpu_init function should be call after __TI_auto_init fucation. What is your opinion?

      

     

    Regards

    Moonil

  • Hi Moonil,

    I do need your email for sending you the JTAG version of uniflash CCS project. I will also follow up your ROM model and RAM model questions with our software team.

    Best regards,

    Ming

  • Hi Ming,

    my email is "moonil.heo@se.com".

    Regards

    Moonil

  • Hi Moonil,

    I have sent the CCS project to your email address.

    Best regards,

    Ming

  • With regard to how the CCS restart feature fails when you link with --ram_model ...  The reply posted by Chester Gillon is correct.  I can only explain a few more details.

    When --ram_model is used, the linker treats the .data section as yet another initialized section.  The presumption is the loader copies the .data section into the appropriate address in memory, just like any other initialized section, such as .text (which contains the code).  When CCS performs restart, it sets the PC to the starting address of the program.  Any changes to the variables in the .data section during program execution are not affected.

    When --rom_model is used, the .data section is an uninitialized section.  There is an additional section named .cinit.  The startup code is configured, by the linker, to expect .cinit.  The startup code uses .cinit to initialize all the variables in the .data section.  When CCS performs restart, as always, the PC is set to the starting address of the program.  The startup code runs again, and it then uses the contents of the .cinit section to initialize the variables in the .data section.

    As for your problem with --rom_model ... I can tell that you do not use the startup code supplied with the compiler RTS library.  That said, it is likely this startup code uses the same boot hook functions as the startup code supplied with the compiler RTS library.  To see the documentation of those functions, please search the TI ARM compiler manual for the sub-chapter titled Boot Hook Functions for System Pre-Initialization.  It is likely the solution to your problem is by making changes to your implementation of these functions.

    Thanks and regards,

    -George

  • Hi George,

    Thank you for your kind explanation in detail. I seem to understand both models from your comments and the TI ARM compiler.

    However, I cannot find a solution to correctly run your SDK example with --rom_model. Should I modify some code or change any linker options for the empty example?

    Please let me know if the issue I captured in "2) --rom_model" is not reproduced at your end.

    fyi, after importing the empty example from SDK into CCS, I changed only the linker option from --ram_model to --rom_model without any other modification.

    Regards,

    Moonil

  • Hi Moonil,

    How about the case not using CCS, that binary built with "--ram_model" is flashed to target by using uart_uniflash.py and target is "warm" reset? I guess the same with "values from the previous run" could happen. Could you clarify this case as well?

    This question is about whether or not the release version of the product including "warm reset" can be built with "--ram_model" and additional initialization implementation is required on ".sysmem".

    [MW] First of all, when you use the CCS to load the code, the .data section will be initialized by either the load time (RAM model) or by the .cinit code (ROM model), so if you restart for the RAM model built code, you will have problem. If you use ROM model built code, then the restart works fine for you.

    In the ROM boot case, the "warm reset" will trigger a ROM boot, which  in turn will load the SBL_OPSI from OSPI flash, it will load the application code from flash. In this case, both ROM model and RAM model built application code should work. If you pause the application code and do a restart (just set the PC to 0), then the ROM model built application code should work OK, while the RAM built application code will not run.

    Best regards,

    Ming

  • Hi Ming,

    In my understanding of the ROM and RAM model from you 

    1. rom_model is recommended when using "restart" in CCS.
    2. rom_model and ram_model are okay for "warm reset".

    as a result, rom_model is commonly safe to use in both cases.

    so, for using rom_model, I think my previous question about the mpu_init hook function should be clarified. Please share your opinion on this issue, "global variable is not initialized before mpu_init hook function is called. It causes incorrect or garbage initialization of MPU".

    Regards,

    Moonil

  • Hi Moonil,

    As George and I said before, the the only difference between the ROM model and the RAM model is "Autoinitialization of Variables at Run Time" (.cinit section for ROM model). It auto initialize the variables every time when restarted. While the RAM model, the variables are only initialized at the load time/boot time, so the restart will not re-initialize the variables. 

    "global variable is not initialized before mpu_init hook function is called. It causes incorrect or garbage initialization of MPU" is correct.

    Best regards,

    Ming

  • Hi Ming, 

    Thank you for kindly repeating the explanation.

    "global variable is not initialized before mpu_init hook function is called. It causes incorrect or garbage initialization of MPU" is correct.

    Do you mean rom model has a problem with MPU initialization? do I have only one choice, ram model for now? Please correct me again if I still misunderstand something.

    Regards,

    Moonil

  • Hi Moonil,

    I did more investigation on the variable initialization for RAM and ROM model. Here is what I found:

    Both RAM and ROM model use the following code:

    _c_int00 (PC=0x0)                                                          boot_armv7r_asm.S
        __mpu_init                                                                  ti_dpl_config.c
        _system_pre_init
        __TI_auto_init_nobinit_nopinit
        main()

    The key difference is the __TI_auto_init_nobinit_nopinit. It initialize the global variables when ROM model is used. When RAM model is used it does not do anything. As you can see the global variable initialization is done after __mpu_init, but before main();

    In conclusion the ROM model is safe for both "warm reset (System Reset)" and "restart (CPU reset)", but RAM model is only safe for "warm reset".

    Best regards,

    Ming 

  • Hi Ming,

    I traced the same and attached the CCS screen capture to this discussion thread before. You have to check the global value used in __mpu_init in rom model.

    Please see my previous captured image "2) --rom_model : " and my point, "__mpu_init is not initialized by values from ti_dpl_config.c" in any reset type. It has only zero values as you can see in captured image. Do you think it is the correct value?

    In conclusion the ROM model is safe for both "warm reset (System Reset)" and "restart (CPU reset)", but RAM model is only safe for "warm reset".

    We can say still ROM model is safe? 

    Regards,

    Moonil

  • Hi Moonil,

    You are correct. I missed the "warm reset" case for ROM model. gMpuConfig was set to 0 initially and then set to the correct value by  __TI_auto_init_nobinit_nopinit. It will cause incorrect setting for __mpu_init.

    " __mpu_init function should be call after __TI_auto_init fucation" is a logical solution, but the I am not sure the __TI_auto_init fucation can run correctly before the __mpu_init (it sets the MPU and Cache).

    In conclusion, The ROM model will not work for "warm reset" unless the above change works.

    Best regards,

    Ming

  • Hi Ming,

    Finally, we are on the same page. Could you please check this with your team and share a patch code including the change works you mentioned?

    Regards,

    Moonil

  • Hi Moonil,

    Yes, I will discuss with software development team for the fix to provide the patch code. Meanwhile, to unblock you quickly, can you make the suggested change in boot_armv7r_asm.S and let us know your experiment result? 

    Best regards,

    Ming

  • Hi Ming,

    As you mentioned a logical solution, I think we can change it as below. It seems to work in my test, but I am still concerned about any issue of cache or performance unknown to me. Please review this workaround and let me know the perfect solution from your team.

    Regards,

    Moonil

  • Hi Moonil,

    Thank you so much for doing the experiment. As it suggested in the comment. The only possible side effect of doing __mpu_init after the  __TI_auto_init is the performance concern. My guess is that it will not cause any incorrect result other than slow execution. I will definately discuss with our software team and hopefully come up with a better solution.

    Best regards,

    Ming

  • Hi Moonil,

    I have filed a ticket against this problem. It was accepted and it is scheduled to be fixed in next MCU+ SDK release 08.03.00 (end of May 2022). Meanwhile, you can use the workaround suggested above. Please close this thread. Thanks!

    Best regards,

    Ming