Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

ram initialization at reset

ram initialization at reset

2006-03-07 by ebarker123

Here is the scenario.

I have an MCB2138 eval board. I have a menu talking on a serial port.

Using the menu, I can set and print a variable called 'mytemp'.

I set the value to say, 456, and print that out.

I press reset and the value is changed to 0. 
Where/How is this variable getting changed. My application requires
that we be able to press reset, and the SRAM contents not change.

Any clues ?

ebarker123

Re: [lpc2000] ram initialization at reset

2006-03-07 by David Hawkins

ebarker123 wrote:
> Here is the scenario.
> 
> I have an MCB2138 eval board. I have a menu talking on a serial port.
> 
> Using the menu, I can set and print a variable called 'mytemp'.
> 
> I set the value to say, 456, and print that out.
> 
> I press reset and the value is changed to 0. 
> Where/How is this variable getting changed. My application requires
> that we be able to press reset, and the SRAM contents not change.
> 
> Any clues ?

The startup code zeros variables in the .data section.

If you want the startup code to leave your variable alone,
create a new section for it, and place it in that section.

This question has been asked before, so take a look in the
archives.

Another option is both reset and power-down preservation,
by writing the variable to flash when it changes.

Look in the archives for threads on using the flash as EEPROM,
there are a few discussions, and I believe there are examples
in the files area.

Dave

Re: [lpc2000] ram initialization at reset

2006-03-07 by Tom Walsh

ebarker123 wrote:

>Here is the scenario.
>
>I have an MCB2138 eval board. I have a menu talking on a serial port.
>
>Using the menu, I can set and print a variable called 'mytemp'.
>
>I set the value to say, 456, and print that out.
>
>I press reset and the value is changed to 0. 
>Where/How is this variable getting changed. My application requires
>that we be able to press reset, and the SRAM contents not change.
>
>  
>
Look in your crt0.s file, bss sections are zeroed there.  'bss' data is 
data which you declared globally and did not provide a value for.  *ALL* 
C code systems initialize the bss data section, all, this is a 
requirement of the C language.

If you want to create memory which is part of the code but is not 
initialized, add a section attribute to it and then place the section 
into the linker ld script.  For example:

char myString [8] __attribute__((section ("noinit")));

in the linker script, place a new section AFTER the bss.  You want to 
avoid placing this in front of "__bss_end__ = . ;"!

================= begin LPC2106ROM.ld ===============
  /* .bss section which is used for uninitialized data */
  .bss (NOLOAD) :
  {
    __bss_start = . ;
    __bss_start__ = . ;
    *(.bss)
    *(COMMON)
    . = ALIGN(4);
  } > RAM

  . = ALIGN(4);
  __bss_end__ = . ;
  PROVIDE (__bss_end = .);

   .myvars (NOLOAD) :
   {
    *(noinit)
   } > RAM

  .stack ALIGN(256) :
  {
    . += STACK_SIZE;
    PROVIDE (_stack = .);
  } > RAM

  _end = . ;
  PROVIDE (end = .);

================== snip ====================

Note the new region called ".myvars" in the script?  That is where I 
will put the "noinit" section.

To make sure that all is well, look at the symbol file produced by the 
linker.  In my case it is main2106.sym, in it I look at the memory 
location of '__bss_end__' and 'myString'.  Here is a snippet of my 
symbols file:

============= begin main2106.sym ===============
400092e2 B serial1ParityMode
400092e4 B tx1Buffer
40009ae8 B Words
40009dec B WordCnt
40009df0 A __bss_end__
40009df0 B myString
4000ae00 A end
4000ae00 A _end
4000ae00 B _stack

================= snip =====================

Actually, that is the very end of the symbol file.  The variable 
myString is placed at the end of the RAM.   Adding more data to this new 
section is quite easy now, simply assign the same attribute to each:

char myString [8] __attribute__((section ("noinit")));

struct BIG_DATA abort_info  __attribute__((section ("noinit")));

int timeAborted __attribute__((section ("noinit")));

...

Hope this helps,

TomW




-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Re: ram initialization at reset

2006-03-07 by Guillermo Prandi

Excellent walkthrough, Tom!

I don't get why you're recommending this:

>> in the linker script, place a new section AFTER the bss.
>> You want to avoid placing this in front of "__bss_end__ = . ;"!

I would have put it *before*, and I can't think of a reason not to do 
so (not that putting it after would be harmful).

Guille

--- In lpc2000@yahoogroups.com, Tom Walsh <tom@...> wrote:
>
> ebarker123 wrote:
> 
> >Here is the scenario.
> >
> >I have an MCB2138 eval board. I have a menu talking on a serial 
port.
> >
> >Using the menu, I can set and print a variable called 'mytemp'.
> >
> >I set the value to say, 456, and print that out.
> >
> >I press reset and the value is changed to 0. 
> >Where/How is this variable getting changed. My application requires
> >that we be able to press reset, and the SRAM contents not change.
> >
> >  
> >
> Look in your crt0.s file, bss sections are zeroed there.  'bss' 
data is 
> data which you declared globally and did not provide a value for.  
*ALL* 
> C code systems initialize the bss data section, all, this is a 
> requirement of the C language.
> 
> If you want to create memory which is part of the code but is not 
> initialized, add a section attribute to it and then place the 
section 
> into the linker ld script.  For example:
> 
> char myString [8] __attribute__((section ("noinit")));
> 
> in the linker script, place a new section AFTER the bss.  You want 
to 
> avoid placing this in front of "__bss_end__ = . ;"!
> 
> ================= begin LPC2106ROM.ld ===============
>   /* .bss section which is used for uninitialized data */
>   .bss (NOLOAD) :
>   {
>     __bss_start = . ;
>     __bss_start__ = . ;
>     *(.bss)
>     *(COMMON)
>     . = ALIGN(4);
>   } > RAM
> 
>   . = ALIGN(4);
>   __bss_end__ = . ;
>   PROVIDE (__bss_end = .);
> 
>    .myvars (NOLOAD) :
>    {
>     *(noinit)
>    } > RAM
> 
>   .stack ALIGN(256) :
>   {
>     . += STACK_SIZE;
>     PROVIDE (_stack = .);
>   } > RAM
> 
>   _end = . ;
>   PROVIDE (end = .);
> 
> ================== snip ====================
> 
> Note the new region called ".myvars" in the script?  That is where 
I 
> will put the "noinit" section.
> 
> To make sure that all is well, look at the symbol file produced by 
the 
> linker.  In my case it is main2106.sym, in it I look at the memory 
> location of '__bss_end__' and 'myString'.  Here is a snippet of my 
> symbols file:
> 
> ============= begin main2106.sym ===============
> 400092e2 B serial1ParityMode
> 400092e4 B tx1Buffer
> 40009ae8 B Words
> 40009dec B WordCnt
> 40009df0 A __bss_end__
> 40009df0 B myString
> 4000ae00 A end
> 4000ae00 A _end
> 4000ae00 B _stack
> 
> ================= snip =====================
> 
> Actually, that is the very end of the symbol file.  The variable 
> myString is placed at the end of the RAM.   Adding more data to 
this new 
Show quoted textHide quoted text
> section is quite easy now, simply assign the same attribute to each:
> 
> char myString [8] __attribute__((section ("noinit")));
> 
> struct BIG_DATA abort_info  __attribute__((section ("noinit")));
> 
> int timeAborted __attribute__((section ("noinit")));
> 
> ...
> 
> Hope this helps,
> 
> TomW
> 
> 
> 
> 
> -- 
> Tom Walsh - WN3L - Embedded Systems Consultant
> http://openhardware.net, http://cyberiansoftware.com
> "Windows? No thanks, I have work to do..."
> ----------------------------------------------------
>

Re: ram initialization at reset

2006-03-07 by ebarker123

Thanks for you excellent reply. Is this for the GNU compiler ?
I failed to mention that I'm using the Keil compiler.
I've determined that the following directives do the trick.

#pragma NOINIT
char states[100];     /* Uninitialized Variable */

#pragma INIT
char array[100];      /* Initialized Variable */

Ed


--- In lpc2000@yahoogroups.com, Tom Walsh <tom@...> wrote:
>
> ebarker123 wrote:
> 
> >Here is the scenario.
> >
> >I have an MCB2138 eval board. I have a menu talking on a serial port.
> >
> >Using the menu, I can set and print a variable called 'mytemp'.
> >
> >I set the value to say, 456, and print that out.
> >
> >I press reset and the value is changed to 0. 
> >Where/How is this variable getting changed. My application requires
> >that we be able to press reset, and the SRAM contents not change.
> >
> >  
> >
> Look in your crt0.s file, bss sections are zeroed there.  'bss' data is 
> data which you declared globally and did not provide a value for. 
*ALL* 
> C code systems initialize the bss data section, all, this is a 
> requirement of the C language.
> 
> If you want to create memory which is part of the code but is not 
> initialized, add a section attribute to it and then place the section 
> into the linker ld script.  For example:
> 
> char myString [8] __attribute__((section ("noinit")));
> 
> in the linker script, place a new section AFTER the bss.  You want to 
> avoid placing this in front of "__bss_end__ = . ;"!
> 
> ================= begin LPC2106ROM.ld ===============
>   /* .bss section which is used for uninitialized data */
>   .bss (NOLOAD) :
>   {
>     __bss_start = . ;
>     __bss_start__ = . ;
>     *(.bss)
>     *(COMMON)
>     . = ALIGN(4);
>   } > RAM
> 
>   . = ALIGN(4);
>   __bss_end__ = . ;
>   PROVIDE (__bss_end = .);
> 
>    .myvars (NOLOAD) :
>    {
>     *(noinit)
>    } > RAM
> 
>   .stack ALIGN(256) :
>   {
>     . += STACK_SIZE;
>     PROVIDE (_stack = .);
>   } > RAM
> 
>   _end = . ;
>   PROVIDE (end = .);
> 
> ================== snip ====================
> 
> Note the new region called ".myvars" in the script?  That is where I 
> will put the "noinit" section.
> 
> To make sure that all is well, look at the symbol file produced by the 
> linker.  In my case it is main2106.sym, in it I look at the memory 
> location of '__bss_end__' and 'myString'.  Here is a snippet of my 
> symbols file:
> 
> ============= begin main2106.sym ===============
> 400092e2 B serial1ParityMode
> 400092e4 B tx1Buffer
> 40009ae8 B Words
> 40009dec B WordCnt
> 40009df0 A __bss_end__
> 40009df0 B myString
> 4000ae00 A end
> 4000ae00 A _end
> 4000ae00 B _stack
> 
> ================= snip =====================
> 
> Actually, that is the very end of the symbol file.  The variable 
> myString is placed at the end of the RAM.   Adding more data to this
new 
Show quoted textHide quoted text
> section is quite easy now, simply assign the same attribute to each:
> 
> char myString [8] __attribute__((section ("noinit")));
> 
> struct BIG_DATA abort_info  __attribute__((section ("noinit")));
> 
> int timeAborted __attribute__((section ("noinit")));
> 
> ...
> 
> Hope this helps,
> 
> TomW
> 
> 
> 
> 
> -- 
> Tom Walsh - WN3L - Embedded Systems Consultant
> http://openhardware.net, http://cyberiansoftware.com
> "Windows? No thanks, I have work to do..."
> ----------------------------------------------------
>

Re: [lpc2000] Re: ram initialization at reset

2006-03-07 by Tom Walsh

ebarker123 wrote:

>Thanks for you excellent reply. Is this for the GNU compiler ?
>I failed to mention that I'm using the Keil compiler.
>I've determined that the following directives do the trick.
>
>#pragma NOINIT
>char states[100];     /* Uninitialized Variable */
>
>#pragma INIT
>char array[100];      /* Initialized Variable */
>
>  
>
Yes, it is for the GNU gcc, I've tried this under the gcc-4.0.2 + 
binutils-2.16.1.

TomW



-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Re: [lpc2000] Re: ram initialization at reset

2006-03-07 by Tom Walsh

Guillermo Prandi wrote:

>Excellent walkthrough, Tom!
>
>I don't get why you're recommending this:
>
>  
>
>>>in the linker script, place a new section AFTER the bss.
>>>You want to avoid placing this in front of "__bss_end__ = . ;"!
>>>      
>>>
>
>I would have put it *before*, and I can't think of a reason not to do 
>so (not that putting it after would be harmful).
>
>  
>
Your choice, I just added it after.  Consideration is this, I am using 
newlib stubs and the sbrk() function references the first free memory 
from the "end" or "_end" location specified in the linker script.  Thus, 
the new section is "protected" from being part of the heap.

TomW




-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Re: [lpc2000] Re: ram initialization at reset

2006-03-07 by Tom Walsh

ebarker123 wrote:

>Thanks for you excellent reply. Is this for the GNU compiler ?
>I failed to mention that I'm using the Keil compiler.
>I've determined that the following directives do the trick.
>
>#pragma NOINIT
>char states[100];     /* Uninitialized Variable */
>
>#pragma INIT
>char array[100];      /* Initialized Variable */
>
>  
>
Well, that would work with Kiel, I guess.  I don't use a Keil dev 
system, my system is GNU compiled from source.  YMMV.

TomW


>Ed
>
>
>--- In lpc2000@yahoogroups.com, Tom Walsh <tom@...> wrote:
>  
>
>>ebarker123 wrote:
>>
>>    
>>
>>>Here is the scenario.
>>>
>>>I have an MCB2138 eval board. I have a menu talking on a serial port.
>>>
>>>Using the menu, I can set and print a variable called 'mytemp'.
>>>
>>>I set the value to say, 456, and print that out.
>>>
>>>I press reset and the value is changed to 0. 
>>>Where/How is this variable getting changed. My application requires
>>>that we be able to press reset, and the SRAM contents not change.
>>>
>>> 
>>>
>>>      
>>>
>>Look in your crt0.s file, bss sections are zeroed there.  'bss' data is 
>>data which you declared globally and did not provide a value for. 
>>    
>>
>*ALL* 
>  
>
>>C code systems initialize the bss data section, all, this is a 
>>requirement of the C language.
>>
>>If you want to create memory which is part of the code but is not 
>>initialized, add a section attribute to it and then place the section 
>>into the linker ld script.  For example:
>>
>>char myString [8] __attribute__((section ("noinit")));
>>
>>in the linker script, place a new section AFTER the bss.  You want to 
>>avoid placing this in front of "__bss_end__ = . ;"!
>>
>>================= begin LPC2106ROM.ld ===============
>>  /* .bss section which is used for uninitialized data */
>>  .bss (NOLOAD) :
>>  {
>>    __bss_start = . ;
>>    __bss_start__ = . ;
>>    *(.bss)
>>    *(COMMON)
>>    . = ALIGN(4);
>>  } > RAM
>>
>>  . = ALIGN(4);
>>  __bss_end__ = . ;
>>  PROVIDE (__bss_end = .);
>>
>>   .myvars (NOLOAD) :
>>   {
>>    *(noinit)
>>   } > RAM
>>
>>  .stack ALIGN(256) :
>>  {
>>    . += STACK_SIZE;
>>    PROVIDE (_stack = .);
>>  } > RAM
>>
>>  _end = . ;
>>  PROVIDE (end = .);
>>
>>================== snip ====================
>>
>>Note the new region called ".myvars" in the script?  That is where I 
>>will put the "noinit" section.
>>
>>To make sure that all is well, look at the symbol file produced by the 
>>linker.  In my case it is main2106.sym, in it I look at the memory 
>>location of '__bss_end__' and 'myString'.  Here is a snippet of my 
>>symbols file:
>>
>>============= begin main2106.sym ===============
>>400092e2 B serial1ParityMode
>>400092e4 B tx1Buffer
>>40009ae8 B Words
>>40009dec B WordCnt
>>40009df0 A __bss_end__
>>40009df0 B myString
>>4000ae00 A end
>>4000ae00 A _end
>>4000ae00 B _stack
>>
>>================= snip =====================
>>
>>Actually, that is the very end of the symbol file.  The variable 
>>myString is placed at the end of the RAM.   Adding more data to this
>>    
>>
>new 
>  
>
>>section is quite easy now, simply assign the same attribute to each:
>>
>>char myString [8] __attribute__((section ("noinit")));
>>
>>struct BIG_DATA abort_info  __attribute__((section ("noinit")));
>>
>>int timeAborted __attribute__((section ("noinit")));
>>
>>...
>>
>>Hope this helps,
>>
>>TomW
>>
>>
>>
>>
>>-- 
>>Tom Walsh - WN3L - Embedded Systems Consultant
>>http://openhardware.net, http://cyberiansoftware.com
>>"Windows? No thanks, I have work to do..."
>>----------------------------------------------------
>>
>>    
>>
>
>
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>  
>


-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.