URGENT: __init_data not working

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

URGENT: __init_data not working

2,712 Views
mahermalak
Contributor III

Hi all,

 

I am working using CW_for_MPC55xx_and_MPC56xx_2.10

 

I have an initialized variable "numOfTests" that is mapped to RAM. As you can see in the attached linker file (XPC560XB_flash.lcf).

 

As it is an initialized variable, then it will be mapped to the ".sdata" section (small data with read/write permission).

uint16 numOfTests = 14;

So after flashing the ECU using a debugger, the value of "numOfTests" will be in ROM.

And to get the correct value, during startup, I need to copy that value from ROM and store it at the address of the variable "numOfTests" in RAM.

The variable "numOfTests" has an address "0x40000f08" as you can see in the attached map file (PA_XPC560XB_FLASH_ConTest_Standard.MAP).

 

I looked up in the example codes provided by Freescale, and I found the function "__init_data" in the "__start.c" file.

I added this file to my project, alongside other dependent files (__mem.h__ppc_eabi_init.c__ppc_eabi_init.h__ppc_eabi_linker.h -> all attached) and it compiles.

 

As I understood from the code, there is a table "_rom_copy_info" that is mapped to the section ".init": 

__declspec(section ".init") extern __rom_copy_info _rom_copy_info[]; /* An array of all initialized (data, text or mixed) sections */

As i guess and I don't know how, but this table is generated by the compiler.

 

 

When debugging :

The table "_rom_copy_info" has wrong values.

As we see below the rom is equal to addr (ram)

164766_164766.pngpastedImage_10.png

having this case and the condition in the function "__copy_rom_section" :

if (size && (dst != src)) {
memcpy(dst, src, size);
__flush_cache( dst, size );
}

where :

  • dst = addr
  • src = rom
  • size = size

Then the values of section ".sdata" will never be copied from ROM to RAM.

 

My questions are:

  1. Am I using correctly the example code?
  2. Am I defining correctly the sections in the linker file?
  3. How the compiler generates the variable "_rom_copy_info"?
  4. How can I know where are the values of the ".sdata" section are flashed in ROM, so I can manually copy them to RAM?
  5. is there a solution to my problem ?

 

PS: I also attached the compiler's options (PA_XPC560XB_mwerks_cfg.mak)

 

Thank you

Maher

Original Attachment has been moved to: PA_XPC560XB_mwerks_cfg.mak.zip

Original Attachment has been moved to: XPC560XB_flash.lcf.zip

Original Attachment has been moved to: __start.c.zip

Original Attachment has been moved to: __ppc_eabi_linker.h.zip

Original Attachment has been moved to: __ppc_eabi_init.h.zip

Original Attachment has been moved to: __ppc_eabi_init.c.zip

Original Attachment has been moved to: __mem.h.zip

Original Attachment has been moved to: PA_XPC560XB_FLASH_ConTest_Standard.MAP.zip

Labels (1)
10 Replies

2,159 Views
martin_kovar
NXP Employee
NXP Employee

Hi Maher,

Unfortunately, I do not know all your project, because you use your own settings (startup, linker, etc.), but from the files you shared, I am not able to find any misconfiguration, but I am not sure about your linker file.

When you look at the map file, you should see that sdata in ROM are flashed at address 36b0.

I am sharing very simple project created in CW2.10 (default project), so please look at it and focus on the following points:

I have created global variable int numOfTests = 14;

This variable is places in sdata section, address 40001340.

pastedImage_1.png

If you look at the another part of map file you should see following:

pastedImage_2.png

Section sdata starts at address 4001340 in RAM and at address 2800 in ROM.

Variable rom_copy_info looks like this:

pastedImage_3.png

The "project" or the files you shared here are too complex to looking for what is wrong. So if I find a bug, please create as simplest project as possible, which demonstrates your issue and share it here. Then I will be able to tell you, what can be wrong.

From my point of view, the best way is to take my project and try it on your side. If it works, do the small changes with linker and startup code and watch, if it still works. This could help to discover the source of your problem.

Regards,

Martin

0 Kudos
Reply

2,159 Views
mahermalak
Contributor III

Hi b55689‌,

Thank you for your reply.

Concerning creating a project using the IDE, I am not sure if it can help because I am using the compiler via command line.

And I am not what does the IDE do in the background (ex: list of compiler's options, entry point...).

I opened your project and I saw that you are using the linker's flags : -rambuffer & -romaddr.

And I saw that you used the address of internal flash : 0x3000.

So i did the same and I put the init section outside of the group "mtextboot" and now I have the impression that the variable "__copy_rom_section"  has the correct values:

pastedImage_2.png

and at the address 0x5848 we can see the initial value of "numOfTests" 14 = 0xE

pastedImage_5.png

which is great.

But my problem now is that by using these two flags I got compilation warning:

### mwldeppc.exe Linker Warning:
# multiply-defined: '__start' in Runtime.PPCEABI.V.UC.a in the file __start.o
# Previously defined in __start.o
# ignored: '__start' in Runtime.PPCEABI.V.UC.a from the file __start.o
### mwldeppc.exe Linker Warning:
# multiply-defined: '__copy_rom_section' in Runtime.PPCEABI.V.UC.a in the file __start.o
# Previously defined in __start.o
# ignored: '__copy_rom_section' in Runtime.PPCEABI.V.UC.a from the file __start.o
### mwldeppc.exe Linker Warning:
# multiply-defined: '__init_bss_section' in Runtime.PPCEABI.V.UC.a in the file __start.o
# Previously defined in __start.o
# ignored: '__init_bss_section' in Runtime.PPCEABI.V.UC.a from the file __start.o
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .intctab section with executable address of .text section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .text section with executable address of .sdata2 section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .data section with executable address of .sdata2 section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .sdata section with executable address of .sdata2 section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .text section with executable address of .fls_driver section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .text section with ROM image address of .data section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .sdata section with ROM image address of .data section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .text section with ROM image address of .sdata section.
### mwldeppc.exe Linker Warning:
# Overlap of the ROM image address of .data section with ROM image address of .sdata section.

And more so, after calling the first C function "BoardInit" the ECU jumps to an "unknown" address:

before the jump: 

pastedImage_9.png

and after the jump:

pastedImage_10.png

You can see attached my new :

  • linker file.
  • generated MAP file.*
  • compiler's options (including the rambuffer and romaddr flags)

Thank you again for your support.

Maher

0 Kudos
Reply

2,159 Views
martin_kovar
NXP Employee
NXP Employee

Hi Maher,

you have definitely misconfigured the linker file.  Definition of sbss2 and sdata2 should be only placed in RAM (mdata) section. Also .fsl_driver should be placed in RAM section.

Please look at the following document especially at the chapter 14, which shows describes linker for Power Architecture processors.

Regards,

Martin

2,159 Views
mahermalak
Contributor III

hi b55689‌,

Thank you for your response.

It works now :smileyhappy:

But using the startup code __init_data, I have another problem.

Using it, I no longer know exactly how the memory is initialized.

What we need:

a section that shall not be initialized after reset (during startup) so the variables in this section shall keep their values before the reset.

this section is called ".noinit".

Problem: 

But using the __init_data function, this section is also initialized !

This function uses the variable "_rom_copy_info" which is generated by the compiler.

And it adds the information of the ".noinit" section as well !

So it copies the data from ROM to RAM for this section!

pastedImage_10.png

And here is an extract of the MAP file :

.noinit section layout
Starting Virtual File
address Size address offset
---------------------------------
00000000 000004 40003f00 00001694 1 .noinit Platforms_ConTest_RamNoInit.o
00000000 000004 40003f00 00001694 4 ubRamNoInit Platforms_ConTest_RamNoInit.o

What I tried:

I added BSS in the declaration of the section in the linker file:

    .noinit (BSS): {} > section_noinit /* RAM no init */

And in the source file, I defined a variable in this section :

#pragma push
#pragma section data_type ".noinit" ".noinit"

u32 ubRamNoInit;

#pragma pop

The variable is no longer mapped to the section ".noinit" but to ".sbss" and is always initialized.

Question:

  • Is there any flag or option that I should add to the declaration of the section or the variable in order to not initialize them during startup ?
  • Am I declaring correctly the section and the variable ?
  • Is there more documentation on the use or the generation of the variable "_rom_copy_info"

Thank you

Maher

0 Kudos
Reply

2,159 Views
martin_kovar
NXP Employee
NXP Employee

Hello Maher,

I do not have much experience with this topic, but my colleague has already solved this problem.

Here is his answer:

See please attached document – FAQ27500. It describes all steps that are necessary to skip the initialization of variables placed to certain segment.
It is also necessary to change the ECC initialization of SRAM function. I have already answered similar question from another customer, so I will copy the text below. It was written for MPC5604P and classic CodeWarrior but principle is the same (sample project is attached). There’s also code that skips the initializations on the basis of reset flags (change this as per your needs).
If you have any questions, please let me know.

***

Then we have to take startup code into account. There’s a function INIT_Derivative() in file MPC5604P_M26V_HWInit.c which initializes whole SRAM memory – it writes some data into whole SRAM. This is necessary because of ECC. After power-on the SRAM contains random values and ECC is not valid. If we access uninitialized SRAM after power-on then it leads to ECC error exception. If the data was not corrupted during reset (as mentioned in reference manual) then we can access SRAM without this initialization. So, it would be possible to check RGM_DES and RGM_FES registers for different reset reasons. In case of reset (not power-on), you can just skip portion of SRAM in ECC init.


Function INIT_Derivative() is called every time after reset. Even if you reset the microcontroller by reset button in debugger, reset script do the same – in order to initialize SRAM it writes some data into whole SRAM. If it is not done after power on reset then SRAM contains random values. ECC contains random (that means invalid) values too. And access to SRAM cell which has no valid ECC will trigger error exception.

I wrote this example how to check the RGM_DES and RGM_FES register and F_SWT flag. If F_SWT is set then it skips the initialization:

__asm void INIT_Derivative(void)
{
nofralloc

      //check if F_SWT is set to "1"
   //if yes, skip RAM initialization    
   
   //load address of FES and DES
   lis r8,0xC3FE
   ori r8,r8,0x4000
   //load FES and DES to r8
   lwz r8,0(r8)
   
   //load mask of F_SWT
   lis r9,0x0000
   ori r9,r9,0x0004        
   
   //mask all bits except F_SWT
   and r7,r8,r9
   
   //is F_SWT set?
   cmpwi r7,0
   
   //if set, skip RAM inititalization
   bne skip_init            
   
   //if not set, init RAM    
   /* SRAM initialization code                                 */
   lis r11,L2SRAM_LOCATION@h       /* Base of SRAM, 64-bit word aligned */
   ori r11,r11,L2SRAM_LOCATION@l

   li r12,320        /* Loops to cover 40K SRAM; 40k/4 bytes/32 GPRs = 320 */
   mtctr r12

   init_l2sram_loop:
       stmw r0,0(r11)        /* Write 32 GPRs to SRAM                     */
       addi r11,r11,128      /* Inc the ram ptr; 32 GPRs * 4 bytes = 128B */
       bdnz init_l2sram_loop /* Loop for 40k of SRAM                      */


skip_init:        

   blr
}

Regards,

Martin

0 Kudos
Reply

2,159 Views
mahermalak
Contributor III

Hi b55689‌,

Can we please schedule a meeting (TeamViewer or WebEx) in order to debug the problem ?

Our project is blocked because of this problem and we need to fix this issue as soon as possible.

Maybe if I show you the problem, you may find the solution directly.

Thank you

Maher 

0 Kudos
Reply

2,159 Views
martin_kovar
NXP Employee
NXP Employee

Hi Maher,

if you want to do a meeting, please contact your local NXP representative assigned to your company. Distributor Network|NXP. Otherwise I will try to solve your problem tomorrow.

Regards,

Martin

0 Kudos
Reply

2,159 Views
mahermalak
Contributor III

Hi b55689‌,

Any news on this issue? 

Thank you for your support!

Maher

0 Kudos
Reply

2,159 Views
mahermalak
Contributor III

Hi b55689‌,

Thanks for the reply.

Actually that's exactly our use case, we check the FES & DES registers and if we detect a SW then we skip the initialization of a ram section ".noinit" during startup.

And using your colleague's code and after sw reset, we actually skip the initialization but the problem occurs afterwards, when we call the function __init_data (you can refer to the file I attached cstartup.s).

The problem as I mentioned above is that the section ".noinit" is considered as "data" section that's why it's added the variable "_rom_copy_info" which means that data from rom will be copied to the section ".noinit" inside the function "__init_data".

In my opinion, the solution is that we need to declare the section in the linker file as "bss" so it won't be initialized during startup and to map correctly the varibales to this section in the source coded.

But I don't know how to do it !! :s

when adding the attribute "BSS" in the declaration of this section in the linker, like this :

  .noinit (BSS): {} > section_noinit /* RAM no init */

But the variable mapped to this section are mapped to the "sbss" section !!!!

#pragma push
#pragma section data_type ".noinit" ".noinit"

u32 ubRamNoInit;

#pragma pop

Is there a way to declare the section as BSS and also map the variable "ubRamNoini" in this section ?

Thank you

Maher

0 Kudos
Reply

2,159 Views
martin_kovar
NXP Employee
NXP Employee

Hi Maher,

it seems the pragma is not entirely correct. Use the following code instead of yours:

#pragma push
#pragma section data_type sdata_type ".noinit" ".noinit"

u32 ubRamNoInit;

#pragma pop

u32 ubRamNoInit is 4 byte integer and this is placed to sbss section. If you add the sdata_type to your pragma, linker should be able to place also sdata to your section .noinit.

Please let me know, if it works.

Regards,

Martin

0 Kudos
Reply