Why does the startup_mimxrt685s.c force debug level optimization (Og)?

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

Why does the startup_mimxrt685s.c force debug level optimization (Og)?

682 Views
scott-kooy
Contributor III

We noticed the following lines in that file:

#if defined (DEBUG)
#pragma GCC push_options
//#pragma GCC optimize ("Og")
#endif // (DEBUG)

When we tried to disable the DEBUG define so that it used our project optimization level which was none (O0), our firmware would no longer work, so we have a DEBUG define in our release code so that it runs.  Which is confusing. We would like to remove that requirement.

0 Kudos
7 Replies

668 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @scott-kooy ,

  Normally, this related to the complier, some complier optimize the code very strong, then it will influence the code function.

  So, if you already influence the code function, I think you can use that code, just don't do optimize operation for that code.

 

Wish it helps you!

Best Regards,

kerry

0 Kudos

626 Views
jgilles
Contributor II

@kerryzhou 

We've done more investigation into this and the startup code does not work properly if it is not optimized.  If it is built with -O0, then the variable used for iterating through the data and bss sections gets corrupted after the first call to data_init().  Using stack variables in ResetISR() does not work properly and stack only seem to work a after a function call.

In ResetISR:

//
// Copy the data sections from flash to SRAM.
//
unsigned int LoadAddr, ExeAddr, SectionLen;
unsigned int *SectionTableAddr;

// Load base address of Global Section Table
SectionTableAddr = &__data_section_table;

// Copy the data sections from flash to SRAM.
while (SectionTableAddr < &__data_section_table_end) {
LoadAddr = *SectionTableAddr++;
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
data_init(LoadAddr, ExeAddr, SectionLen);
}

// At this point, SectionTableAddr = &__bss_section_table;
// Zero fill the bss segment
while (SectionTableAddr < &__bss_section_table_end) {
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
bss_init(ExeAddr, SectionLen);
}

 When data_init() is first called and execution returns back to ResetISR(), SectionTableAddr is now overwritten with the value of pulDest in data_init().  This causes any other calls to data_init() and bss_init() to be skipped and therefore the application fails to run properly.

If the above code is moved into a separate function and called from ResetISR(), then initialization happens correctly because the stack variables are preserved properly.

When the code is optimized with -Og, then the stack variables get optimized out and registers operations are used instead without accessing the stack.  This causes the code to execute as intended.

This is very confusing because the preprocessor macro DEBUG leads one to believe that it is only used for optimizing the code for debugging, not that it is essential to the startup code operating correctly.

This should really be addressed...either so the start up code's use of stack is fixed or at least so that the startup code is always optimized (not through defining DEBUG).

0 Kudos

603 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jgilles ,

   Thanks so much for your question.

   So, when you set your customer project to release version, and the optimize level to 0

kerryzhou_0-1680855759954.png

 

Your application function is failed, right?

I also test the RT685 SDK mcuxpresso project, after test, the code function still works:

kerryzhou_1-1680855806407.png

 

So, do you reproduce the issues on the SDK project? Or just your own customer project?

If it is your own customer project, can you delete the important code, and share me the simple project which can reproduce the issues?

BTW, do you try to download your release project to the flash, and reset the board, check the function? whether that works? I mean, don't use debug to check it. As I think the tool debug limit the optimization, not the startup code need optimization.

Best Regards,

Kerry

 

0 Kudos

600 Views
jgilles
Contributor II

I reproduced the basic behavior with the hello_world example on the RT685EVK using the 2.9.0 SDK.  In the hello_world app, the app starts because data_init() works correctly since there is only one data section in the memory table -- the first call to data_init() always works.  But I found that bss_init() is not called in the SDK example (since SectionTableAddr is wrong after returning from data_init() ).  Can you confirm that with your testing?

Our custom application fails to start because the first entry in the data section table refers to a memory region with no code/data in it, so it is length 0. If there are multiple entries in the data section, only the first is copied/handled correctly in my testing.  The second entry in our data section table does have data that needs to be copied, but since data_init() only gets called once, it does not get copied and so our app does not start up)  We could change our memory map to fix this, but I think not having bss_init() get called is a problem regardless.  And even if we workaround it, the startup code is not functioning as written with O0.  It should be able to iterate through the whole data section table and handle 0 length entries and also call bss_init too.

BTW, do you try to download your release project to the flash, and reset the board, check the function? whether that works? I mean, don't use debug to check it. As I think the tool debug limit the optimization, not the startup code need optimization.

Yes, our app does not startup correctly when run this way either.

Thanks,
Jesse

0 Kudos

551 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jgilles ,

  Please help to check, use the newest SDK SDK_2_13_0_EVK-MIMXRT685, whether you still can reproduce the issues or not?

  Please also tell me, your MCUXPresso IDE version.

   You reproduce the issues, just:

1. disable the DEBUG 

2. Set project optimization level to none (O0)

Right?

I will find time to test it.

Best Regards,

kerry

0 Kudos

538 Views
jgilles
Contributor II

I tested by importing hello_world from SDK 2.13 and I cannot reproduce the issue.  It appears to be fixed by the addition of the "naked" attribute for the ResetISR() function.  The startup code from 2.9 did not have this attribute.  This attribute causes SectionTableAddr to be placed in a register instead of the stack and all of the init code works propery.

__attribute__ ((naked, section(".after_vectors.reset")))
void ResetISR(void) {

Using MCUXpresso 11.7.0.

Thanks,

Jesse

0 Kudos

530 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @jgilles ,

  Good!

   Thanks for letting me know your issue is solved.

   Next time, when you meet issues, check the newest SDK, as the new SDK may fix some bugs.

    Any new issues, welcome to create the new case!

Wish it helps you!

Best Regards,

Kerry

0 Kudos