Bare-metal app launching from another

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Bare-metal app launching from another

1,338 Views
phstruong
Contributor I

Hi,

I'm having a problem when trying to run one bare-metal app from another by jumping to its entry point. Out of reset, there are 3 bare-metal applications (APP1, APP2 and APP3) running one after another. The problem only occurred when I tried to launch APP3. During its early execution, it failed after calling SystemInit() in the system_MCIMX6Y2.c, which is included in NXP's SDK 2.2 for MCIMX6ULL.

APP1 is the smallest application running out of reset and was created based on the "Hello world" sample program from the SDK with default startup and system initialisatin code. For APP2 (created in the same way) to be launched properly, I found that I had to skip the intial code to disable the cache, strict alignment, branch prediction and MMU in the default startup_MCIMX6Y2.s; otherwise, the execution would be immediately interrupted with an undefined exception. Similarly, during the SystemInit() execution, I had to to explicitly disable the cache first before invalidating and reenabling it.

While this additional arrangement allows APP1 to launch APP2 properly and reliably

...
Request display semaphore...
Ready to launch app @ 80000130


Open UART3 for debug
AMB04 SBC version 0.00.00 (Build 063) for CPU1
...

the same arrangement would not allow APP2 to launch APP3 as expected:

...
Ready to launch app @ 82000130

It appears APP3 encountered similar exception during its early execution; hence no startup messages were printed out.

I'm grateful to hear anyone experiencing similar problem and suggestion how to solve it.

Thanks in advance

 

 

0 Kudos
Reply
7 Replies

1,283 Views
phstruong
Contributor I

Hi Sanket,

Thanks for looking into this application hand-over issue. So far I find that the only way for a secondary application in DDRAM to be launched properly/successfully is not to disable the cache/strict alignment/branch prediction (in startup_MCIMX6Y2.S) at the entry point when control is handed over to the secondary app. I also have to skip disabling MMU/cache invalidation within SystemInit() (in system_MCIMX6Y2.c) and skip calling BOARD_InitMemory() in main(). The cache, MMU and board memory would have been set up when the very first application boots up from OCRAM (using SPI FLASH booting device).

Best regards,

Peter

 

0 Kudos
Reply

1,219 Views
Sanket_Parekh
NXP TechSupport
NXP TechSupport

Hi @phstruong,

I hope you are doing well
 
Please share the below information to debug the issue.
 
1)Please share the code of your application APP1, APP2, and APP3.
2)Kindly share the steps you followed using SDK to reproduce the issue at our end.
 
Thanks & Regards,
Sanket Parekh

0 Kudos
Reply

1,202 Views
phstruong
Contributor I

Hi Sanket,

Thanks for your reply for further information of APP1, APP2 and APP3. The general structure for all these applications is fairly similar to the sample "hello_world" application. I don't know what is the best way to share the source code for these applications as all my applications are built under Eclipse environment. 

All the applications have been compiled with the sample startup code provided in GCC\startup_MCIMX6Y2.s and the system initialization code provided in system_MCIMX6Y2.c. These two files have been modified slightly to avoid the handover issues and are shared among the three applications. I have attached these two files for your reference. I also have to modify the sample clock_config.c to skip setting up various clocks in APP2 and APP3 as this has already been setup in APP1.

After the startup code and system initialization code have been executed, it will eventually call the main() function as usual. The main() function for all three applications has the same layout as shown. 

int main(void)
{
#ifdef FBC_APP
    ClearCmSpc(); // Call this first to initialise shared common space
#endif // FBC_APP
    /* Init board hardware. */
    SystemInitIrqTable();
    BOARD_InitPins();
    BOARD_BootClockRUN();
#if (CACHE_MMU_TST_TYP == 0)
    BOARD_InitMemory();
#elif (CACHE_MMU_TST_TYP == 1)
#if (defined(FBC_APP) || defined(SBC_APP))
    BOARD_InitMemory();
#endif
#elif (CACHE_MMU_TST_TYP == 2)
#ifdef FBC_APP
    BOARD_InitMemory();     // Only allow this to be called for FBC 
#endif // FBC_APP
#endif // (CACHE_MMU_TST_TYP == x)
    OpenOSCritical();
    BOARD_InitDebugConsole();

    ShowVersionInfo();
    ShowClockGate();
    OpenOS();
    while (1)
    {
      OSMain();
    }
}

My APP1 is associated with FBC_APP (FBC stands for first boot code)

My APP2 is associated with SBC_APP and also SEC_APP (SBC and SEC stands for second boot code and secondary respectively)

My APP3 is associated with SEC_APP.

In my testing, I have found that the only way to allow APP2 and APP3 to boot properly is to also skip the BOARD_InitMemory() during APP2 and APP3 execution and this is done by setting CACHE_MMU_TST_TYP conditional compilation to 2.

APP1 is located at the beginning of serial FLASH and it would be loaded into OCRAM (@ 0x00907800) for execution on powered up by IMX6 native boot loader. I must say the startup sequence of APP1 is most similar to the sample "hello_world" app. Once APP1 is running, it will load APP2 from serial FLASH to DDRAM (@0x80000000) and control is then handed over to it by jumping to its entry point (ie. the reset vector).

APP2 would execute similar startup code and system initialization code as those for APP1, but conditional compilation within startup_IMX6Y2.s, system_IMX6Y2.C, clock_config.c and main.c would force APP2 to skip certain things (eg. for cache, MMU, clock, memory management) so that it can boot properly. Similar to APP1, APP2 will load APP3 from serial FLASH to DDRAM (@0x82000000) and control is then handed over to it by jumping to its entry point or the reset vector.

Typically, if I don't modify the startup code in startup_IMX6Y2.s, APP2 execution will cease/hang as soon as the mcr instruction below is executed.

Reset_Handler:
    cpsid i /* Mask interrupts */

    /* Reset SCTlr Settings */
#ifndef SEC_APP
    mrc p15, 0, r0, c1, c0, 0 /* Read CP15 System Control register */
    bic r0, r0, #(0x1 << 12) /* Clear I bit 12 to disable I Cache */
    bic r0, r0, #(0x1 << 2) /* Clear C bit 2 to disable D Cache */
    bic r0, r0, #0x2 /* Clear A bit 1 to disable strict alignment */
    bic r0, r0, #(0x1 << 11) /* Clear Z bit 11 to disable branch prediction */
    bic r0, r0, #0x1 /* Clear M bit 0 to disable MMU */
    mcr p15, 0, r0, c1, c0, 0 /* Write value back to CP15 System Control register */
#endif // !SEC_APP

Similar, APP2 and APP3 execution would cease/hang when it executes the instructions in SystemInit() in the system_IMX6Y2.c.

    L1C_InvalidateInstructionCacheAll();
    L1C_InvalidateDataCacheAll();
    actlr = __get_ACTLR();
    actlr = (actlr | ACTLR_SMP_Msk); /* Change to SMP mode before enable DCache */
    __set_ACTLR(actlr);

    sctlr = __get_SCTLR();
    sctlr = (sctlr & ~(SCTLR_V_Msk | /* Use low vector */
    SCTLR_A_Msk | /* Disable alignment fault checking */
    SCTLR_M_Msk)) /* Disable MMU */
    | (SCTLR_I_Msk | /* Enable ICache */
    SCTLR_Z_Msk | /* Enable Prediction */
    SCTLR_CP15BEN_Msk | /* Enable CP15 barrier operations */
    SCTLR_C_Msk); /* Enable DCache */
    __set_SCTLR(sctlr);

If there is anything else you want me to clarify further, please let me know.

Regards,

Peter

 

 

0 Kudos
Reply

1,124 Views
Sanket_Parekh
NXP TechSupport
NXP TechSupport

Hi @phstruong 

I hope you are doing well
My sincere apology for the delayed response.

We gone through your code and the changes you made.

The reason for this problem could as below.

The purpose of the default source code is to run one bare-metal application at a time. As it is the custom application and we are calling more than one application, the changes you made are required.

-> To skip the calling BOARD_InitMemory() in main() is required for APP2 and APP3 because it is done already by APP1 and the board is not reset so no need to init the memory again.

-> The process of disabling the cache/strict alignment/branch prediction/disabling the MMU etc is done through the register bit settings. While running the APP2 or APP3, the register is in use. Also, these bits are already configured from APP1. If the coprocessor cannot run the 'mcr' or 'bic' command operation successfully at the register level, an undefined instruction abort is generated. This can cause the issue of undefined behaviour.

I hope this information helps you.

Thanks & Regards,
Sanket Parekh

0 Kudos
Reply

1,115 Views
phstruong
Contributor I

Hi Sanket,

Thank you very much for your time looking into this specific issue and I fully understand it is not possible to get a quick response when you have to deal with many support requests from the whole NXP community.

Your answer is assuring in that the steps I have taken in APP2 and APP3 are the right ones. This helps me feel more confident working with the iMX6 processor. I also appreciate your explanation about undefined behaviour with unsuccessful coprocessor register bits manipulation as this information is more difficult to find.

Is there a safe way to manipulate the coprocessor register bits for the listed purposes? It sounds logical that if the register is in use, it should not be changed. The question is whether its usage can be temporarily suspended. The reason why I ask this question is because our APP3 may be eventually developed as a RTOS application. I'm not sure if there is any need for it to reconfigure the coprocessor register bits.

Best regards,

Peter

 

 

0 Kudos
Reply

1,092 Views
Sanket_Parekh
NXP TechSupport
NXP TechSupport

HI @phstruong 

I hope you are doing well
 
I feel glad to help you in this case.
 
 whether its usage can be temporarily suspended. 
=> NXP does not have any information in this regard as these registers have many architectural dependencies. One can refer to the ARM community for the same.
 
One can find some more information regarding Coprocessor 15 from the below link.
 
Thanks & Regards
Sanket Parekh

0 Kudos
Reply

1,306 Views
Sanket_Parekh
NXP TechSupport
NXP TechSupport

Hi @phstruong 

I hope you are doing well
 
Thank you for your patience. 
I am working on your query. I will update you soon on this case.
 
Thanks & Regards
Sanket Parekh

0 Kudos
Reply