Uninitialized variable initialized to zero at power up?

cancel
Showing results for 
Search instead for 
Did you mean: 

Uninitialized variable initialized to zero at power up?

1,757 Views
shrikant_oak
Contributor II

Hello,

 

I am using CW  Version: 10.2 (Build Id:120126) for MPC5604P. I am in a need to place a variable in an uninitialized separate memory segment(mode_flag). For this i made following changes in my linker file

MEMORY
{
    resetvector:           org = 0x00000000,   len = 0x00000008
    init:                   org = 0x00000020,   len = 0x00000FE0
    exception_handlers:    org = 0x00001000,   len = 0x00001000
    internal_flash:        org = 0x00002000,   len = 0x0007E000

    internal_ram:          org = 0x40000000,   len = 0x00008000
    heap  :                org = 0x40008000,   len = 0x00001000
    stack :                org = 0x40009000,   len = 0x00000FFC
    mode_flag :                org = 0x40009FFC,   len = 0x00000004
}

 

    GROUP : {
       .mode_flag ALIGN (0x4) : {}
    } > mode_flag

 

& in  c file

 

#pragma section RW "mode_flag" ".mode_flag"
__declspec (section "mode_flag") uint32_t RespModeFlag;

With this modifications i am able to place the variable within the uninitialized segment created.

 

in .MAP file

 

.mode_flag section layout
  Starting        Virtual  File
  address  Size   address  offset
  ---------------------------------
  00000000 000004 40009ffc 000038a8  1 .mode_flag     Diag.obj
  00000000 000004 40009ffc 000038a8  4 RespModeFlag     Diag.obj

 

As mentioned earlier this is an uninitialized segment, but after power on this segment is initialized to zero in "__asm void INIT_Derivative()" function. When checked with this function, instruction "li r12,320" which loads a fixed count for a loop to initialize the RAM. When count changed from 320 to 319 it works (As uninitialized segment is placed at the top of RAM/ last 4 bytes of RAM), but then it gets initialized in one of the library function "__init_bss_section".

 

It will be a great help if anyone suggest how to proceed in order to not to initialize the RAM segment after Power up.

Thanks & Regards,
Shrikant

Labels (1)
7 Replies

241 Views
stanish
NXP Employee
NXP Employee

Hello shrikant.oak,

 

I've resolved this issue via Service Request. I'm posting the answer for others that might be facing same or similar issue.

 

Actually there are several things that may modify the RAM section:

 

  1.  INIT_Derivative() function initializes SRAM ( SRAM ECC check sum init)

By decreasing the counter from 320 to 319 it causes the 32x4 = 128 Bytes of SRAM (from top of the ram) are not initialized. In this case ECC check exception might occurs if in case ECC check does not match.

Other solution could be to initialize entire SRAM only in case you suspect SRAM content might be corrupted (e.g. RGM.DES != 0) 

e.g.:

 

__asm void INIT_Derivative(void)

{

    // if (RGM.DES.R) init SRAM;

    e_lis r8,0xc3fe

    e_lhz r0,16386(r8)

    se_cmpi r0,0

    se_beq dont_init

   

    /* MPC5602P SRAM initialization code                                 */

    lis r11,L2SRAM_LOCATION@h       /* Base of SRAM, 64-bit word aligned */

    ori r11,r11,L2SRAM_LOCATION@l

 

    li r12,256        /* Loops to cover 32K SRAM; 32k/4 bytes/32 GPRs = 384 */

    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 32k of SRAM                      */        

 

dont_init:

  blr

 

Also it would be good to service an ECC generated exception properly.

 

  1. __init_bss_section() init. bss (uninitialized) sections to 0.

 To avoid zeroing of the memory section you need to customize the startup routine __init_data().  Since __init_data() routine is part of the standard library you can copy&paste its source form __start.c from "c:\Freescale\CW MCU v10.2\MCU\PA_Support\ewl\EWL_Runtime\Runtime_PA\Source\__start.c" to your project source directory and adapt it. The __init_Data() is defined as a weak symbol so your customized version should be used by the linker instead of the library version.

Let's consider a linker section e.g.:

 

MEMORY

{

    resetvector:           org = 0x00000000,   len = 0x00000008

    ...

    my_uninit_ram :        org = 0x40004F00,   len = 0x00000100

}

SECTIONS

{

... 

.do_not_init  (BSS) : {} > my_uninit_ram

}

 

And use the custom uninited section in the code:

 

#pragma section RW ".dummy" ".do_not_init"

__declspec (section ".dummy") uint32_t RespModeFlag;

 

 

Then adapt the startup routine, __start.c e.g.:

 

extern char _f_do_not_init[];  //import the linker sybol - start address of .do_not_init

 

extern void __init_data(void)

{

__rom_copy_info *dci;

__bss_init_info *bii;

 

         /* Copy from ROM to RAM: */

 

dci = _rom_copy_info;

while (1) {

if (dci->rom == 0 && dci->addr == 0 && dci->size == 0) break;

                 __copy_rom_section(dci->addr, dci->rom, dci->size);

                 dci++;

}

 

         /* Initialize with zeros: */

 

bii = _bss_init_info;

while (1) {

  if (bii->addr == 0 && bii->size == 0) break;

  // do not init the ".do_not_init" section, zero all remaining bss sections

  if (bii->addr != _f_do_not_init) __init_bss_section(bii->addr, bii->size);

  bii++;

}

}

  1. Debugger Script (e.g. MPC650xP_VLE.tcl) inits. Entire SRAM - you can simply disable this by commenting the line:

 init_ram 0x40000000 0x5000

 

See below snippet of tcl. file:

 

#################################

# Initialization for MPC5602P

#################################

proc mpc5602P_init {} {

    reset hard

 

    # Explicitly stop the core

    stop

 

    # Disable SWT Watchdog Timer

    mem v:0xfff38010 = 0x0000c520

    mem v:0xfff38010 = 0x0000d928

    mem v:0xfff38000 = 0xff00000A

 

    # core init

    init_e200z0h

   

    # initialize MPC5602P ECC SRAM 20K:  0x40000000 - 0x40005000

    # comment this line to avoid ram init by the debugger init_ram 0x40000000 0x5000

}

 

  1. P&E Flash programming support routines/buffers that are transferred into MCU's SRAM -  may also overwrite the SRAM content. In order to disable flash programming routines to be transferred simply uncheck the Debugger Download configuration option - "Perform standard download". Without this option you are unable to program the MCU internal flash.

 

 

Stanish

241 Views
steffenrose
Contributor II

Thank you very much for sharing the code!

0 Kudos

241 Views
shrikant_oak
Contributor II

Hello Stanislav Sliva,

I am observing a strange behavior with the change in the  INIT_Derivative function. The changes has been made exactly same as suggested in prior conversation.

Behavior is as below:

  • Works fine when Debugger is physically connected.
  • When debugger is physically removed & POR is performed, after that MPC5604P starts resetting after every 10mSec.
  • When the value at instruction "li r12,256 (which is used to cover the 32K RAM out of 40K)" is changed to 320 (considering 40K RAM) it works fine after removing the debugger (Not generating the RESET behavior as that of previous point) but then uninitialized RAM gets initialized.

Is there anything else we need to take care of? Please suggest.

Thanks & Regards,

Shrikant

0 Kudos

241 Views
shrikant_oak
Contributor II

Hello Stanish,

 

This is exactly what i was looking for, & it's working fine at my end. :smileyhappy:

 

Thanks for in deatail suggestion!!

 

Regards,

Shrikant

0 Kudos

241 Views
J2MEJediMaster
Specialist I

It appears that your flag variable is a global, correct? Per the ELF and C specification, those wind up in the .bss section and get initialzed to zero. The dead giveway is that __init_bss_section gets involved. You might want to force the flag variable into the .data section. See this thread at Stackoverflow for more info:

 

http://stackoverflow.com/questions/3532334/how-about-bss-section-not-zero-initialized

 

---Tom

0 Kudos

241 Views
shrikant_oak
Contributor II

First of all thanks for the reply!!

 

Actually i am looking for a variable which should be placed in an uninitialized memory as well as this variable also uninitialized. The intention is after power up this RAM variable is not initialized to zero instead it should retain it's previous value before SW RESET.

 

Thanks & Regards,

Shrikant

0 Kudos

241 Views
CrasyCat
Specialist III

Hello

 

  The ANSI C standard expects all uninitialized variables to be set to 0 when function main is reached.

  So the startup code we are providing is performing this initialization.

 

  If you do not want this to happen the startup code needs to be modified.

  First question is do you want this to happen to all uninitialized variables or only some of them?

 

  Also if you decide to go this way you need to make sure your application does not assume some of the

  uninitialized variables are initialized with 0.

 

CrasyCat

0 Kudos