Adding a constant at perticular location in program memory

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

Adding a constant at perticular location in program memory

2,523 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syed on Thu Dec 09 08:31:53 MST 2010
Hi All,
I am using LPC1114 with LPCXpresso environment. I have gone through the Code Red wiki but could not find the answer. I am trying to place a constant (eg. crc = 0x12345678) at a perticular location in program memory. I want to know the procedure to add this constant at say suppose 0x7FEC in the program memory.

I think we need to create a section and then reference in program memory
  __attribute__((section(".crc_fixup")))  unsigned int app_crc_fixup = 0x12345678;

So can anyone please provide me what changes need to be made in the linker script?

  Regards,
  Syed
0 Kudos
Reply
14 Replies

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by hardkrash on Mon Feb 21 01:00:48 MST 2011
Putting the CRC at the END of the flash is a poor implementation.  It may seem like a great idea, but it fails with two problems.

-Migrating binary images to parts of differing size.  You will have to have multiple images to support different parts, where the only difference is flash size.

-Your boot loader is now locked to a particular end point.

You are far better off to use the beginning of the text section.

example,  Your boot loader lives in the first 4k, so you use 4k+1 as the checksum storage, and 4k+4 as the length.

This way your boot loader only had to do two things at code verification.
Reads the checksum to verify and the length of the data to verify.

This is much more flexible than using the last bit of memory.
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rsmiech on Thu Feb 17 07:55:30 MST 2011
[FONT=Arial][SIZE=1]Hi All,[/SIZE][/FONT]
[FONT=Arial][SIZE=1]I was looking for the method to place consts at fixed location at the end of flash memory too.[/SIZE][/FONT]
[FONT=Arial][SIZE=1]I think that isn't unusual - CodeRedSupport ;).[/SIZE][/FONT]
[FONT=Arial][SIZE=1]This is very useful, especially if you want use onboard flash memory like EEPROM to store nonvolatile data. [/SIZE][/FONT]

[FONT=Arial][SIZE=1]My solution is:[/SIZE][/FONT]
[FONT=Arial][SIZE=1]ownlinkscripts adding (based on LPC1114):[/SIZE][/FONT]

[LEFT][FONT=Arial][SIZE=1]MEMORY[/SIZE][/FONT]
[FONT=Arial][SIZE=1]{[/SIZE][/FONT]
[FONT=Arial][SIZE=1]/* Define each memory region */[/SIZE][/FONT]
[FONT=Arial][SIZE=1]MFlash32 (rx) : ORIGIN = 0x0, LENGTH = 0x7000 /* 28k change avaiable flash to 32k - 4k*/[/SIZE][/FONT]
[FONT=Arial][SIZE=1]MFlash4 (rx): ORIGIN = 0x7000, LENGTH = 0x1000 /*declare 4k EEPROM used for store data at specified adress - here, last block of memory*/[/SIZE][/FONT]
[FONT=Arial][SIZE=1]RamLoc8 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x2000 /* 8k */[/SIZE][/FONT][/LEFT]
[FONT=Arial][SIZE=1]}[/SIZE][/FONT]

[LEFT][FONT=Arial][SIZE=1]/* Define a symbol for the top of each memory region */[/SIZE][/FONT]
[FONT=Arial][SIZE=1]__top_MFlash32 = 0x0 + 0x7000; /*change the top to 0x7000 */[/SIZE][/FONT][/LEFT]
[FONT=Arial][SIZE=1]__top_RamLoc8 = 0x10000000 + 0x2000;[/SIZE][/FONT]
[FONT=Arial][SIZE=1]/*[/SIZE][/FONT]
[LEFT][FONT=Arial][SIZE=1]/* place consts (EEPROM Data) at location */[/SIZE][/FONT]
[FONT=Arial][SIZE=1].eeprom : ALIGN(4)[/SIZE][/FONT]
[FONT=Arial][SIZE=1]{[/SIZE][/FONT]
[FONT=Arial][SIZE=1]KEEP(*(.eeprom*))[/SIZE][/FONT][/LEFT]
[FONT=Arial][SIZE=1]}>MFlash4[/SIZE][/FONT]

[FONT=Arial][SIZE=1]Example declaration in source code:[/SIZE][/FONT]

[FONT=Arial][SIZE=1]__attribute__ [/SIZE][/FONT][FONT=Arial][SIZE=1]((section(".eeprom"))) const struct structName = {init1,init2,init3,...} ;[/SIZE][/FONT]
[FONT=Arial][SIZE=1]or simply:[/SIZE][/FONT]
[FONT=Arial][SIZE=1]__attribute__ ((section(".eeprom"))) const type name = init;[/SIZE][/FONT]

[LEFT][FONT=Arial][SIZE=1]Regards[/SIZE][/FONT]
[FONT=Arial][SIZE=1]Rafal[/SIZE][/FONT][/LEFT]
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Dec 14 10:24:07 MST 2010
Only that, as the number of vectors change, so will your address. So as you move to another LPC part, your crc_fixup address will change. If you are not going to port your code to another LPC, then it won't be an issue.
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syed on Tue Dec 14 09:43:46 MST 2010
Is there any reason for not keeping the variable just after isr_vector ?

.text :
    {
        KEEP(*(.isr_vector))
        [B]KEEP(*(.crc_fixup*))   [/B] 
        *(.text*)
        *(.rodata*)
    } > MFlash32

Regards,
Syed
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Dec 14 06:59:48 MST 2010
If you just need your variable at a known, fixed lcation, I would suggest placing it just before the CRP (0x2f8).

.text :
    {
        KEEP(*(.isr_vector))
.= 0x2f8 ;
        [B]KEEP(*(.crc_fixup*))   [/B] 
        *(.text*)
        *(.rodata*)
    } > MFlash32
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syed on Tue Dec 14 03:29:42 MST 2010
Hi All,

          Thanks for your replies. I am using the variable to do a background check of flash memory. The reason to place it at the end was to avoid having gaps in memory. The application note describing CRP saves the variable at 0x2fc, which is near the beginning of the flash but still there might be some gaps in the memory i.e. after the isr_vector till 0x2fc.

Another way I think would be to add it just after the isr_vector so that it lies at 0xc0, but we have to make sure that isr_vector is of fixed size.
    .text :
    {
        KEEP(*(.isr_vector))
        [B]KEEP(*(.crc_fixup*))   [/B] 
        *(.text*)
        *(.rodata*)
    } > MFlash32


Also the solution provided by CodeRedSupport should contain [B]0x7ff0[/B] not 0x7fff0
    .crc_fixup :
    {
        . = [B]0x7ff0[/B] - (LOADADDR(.text) + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.ARM.extab) + SIZEOF(.ARM.exidx));
        KEEP(*(.crc_fixup))
    } >MFlash32
    Regards,
    Syed
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by curtvm on Fri Dec 10 14:11:23 MST 2010
I think you could also just add a MCU Linker-Miscellaneous- other options-
--section-start=.crc_fixup=0x7FF0
then not have to deal with a linker script.
Unless its not accessed by your code, then the garbage collector may eat it.
(although another added option to the same place may fix that->  --undefined=name_of_var )
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Fri Dec 10 08:42:37 MST 2010
This is an unusual things to do. Can I ask why you want to place the variable at the end of your flash?

However, you can do it by adding a new section after your .data section.
    .crc_fixup :
    {
        . = 0x7fff0 - (LOADADDR(.text) + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.ARM.extab) + SIZEOF(.ARM.exidx));
        KEEP(*(.crc_fixup))
    } >MFlash32
You have to do it like this as the Flash not only contains your code, but also your initialized data. The location counter is relative to a section, so we have to use the complex assignment above to set the location counter to the address you want.
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syed on Fri Dec 10 05:40:36 MST 2010
Thanks for the reply. I have tried that but it still fails.

e:/nxp/lpcxpresso_3.5/tools/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: ..\..\image\app.axf
section .data will not fit in region MFlash32
e:/nxp/lpcxpresso_3.5/tools/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: region MFlash32 ove
rflowed by 4 bytes
collect2: ld returned 1 exit status


Below is the part from my linker script

    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)
        *(.rodata*)
        . = 0x7ff0;                 /* <== The start location of CRC Fixup     */
        KEEP(*(.crc_fixup))     /* <== The section which stores the Fixup  */
    } > MFlash32


    /* for exception handling/unwind - some Newlib functions (in common with C++ and STDC++) use this. */
   
    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > MFlash32

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > MFlash32
    __exidx_end = .;
    _etext = .;

    _etext = .;
.
.
.

Is this due to .ARM.extab and .ARM.exidx  ?? Can anyone please provide me a sloution?

Regards,
Syed
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Fri Dec 10 05:20:03 MST 2010
The post by TheFallGuy is the way to do it.

Without going too far into the details of linker scripts... The linker has a 'current location' which is referred to as ".". When code/data is added to a section, it is added at the current location, and the current location is incremented. The current location cannot be decremented or set to a value lower than current location. Thus if you set the current location (".") to be near the end of memory, then you will quickly overflow it. The application note describes CRP, which is at a fixed at 0x2fc, which near the beginning of the flash. You want to place you value near the end of flash, hence the difference.
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syed on Fri Dec 10 02:59:47 MST 2010
Thanks for your reply. Yeah, thats what I thought but was using the procedure as described in http://ics.nxp.com/support/documents/microcontrollers/pdf/an10968.pdf

Can anyone please provide me a correct way to store the constant at say 0x7ff0 in program memory.

Thanks,
Syed
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Thu Dec 09 10:34:23 MST 2010
The effect of your change is to place your data at 0x7ff0 and then everything else AFTER it! Place your changes at the end of the section. e.g.
.text :
    {
        KEEP(*(.isr_vector))
       *(.text*)
        *(.rodata*)
    [B][COLOR=Black]    . = 0x7ff0;        [/COLOR][/B]                  /* <== The start location of CRC Fixup  */
         [B]KEEP(*(.crc_fixup))       [/B] /* <== The section which stores the Fixup */
         } > MFlash32

0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syed on Thu Dec 09 10:28:17 MST 2010
Hi,

     Thanks for your reply. I have tried this but it gives me the following error
    .text :
    {
        KEEP(*(.isr_vector))
       [B][COLOR=Black]. = 0x7ff0;                                     [/COLOR][/B]                                 /* <== The start location of CRC Fixup  */
        [B]KEEP(*(.crc_fixup))                        [/B] /* <== The section which stores the Fixup */
        *(.text*)
        *(.rodata*)
    } > MFlash32


e:/nxp/lpcxpresso_3.5/tools/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: ..\..\image\app.axf
section .text will not fit in region MFlash32
e:/nxp/lpcxpresso_3.5/tools/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: region MFlash32 overflowed by 11108 bytes
collect2: ld returned 1 exit status

Any clues whats happenning.

             Regards,
             Syed
0 Kudos
Reply

2,398 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by whitecoe on Thu Dec 09 08:45:59 MST 2010
Have you looked at the CRP example that ships with LPCXpresso ??

In my install it is inside the following zip:

<install_dir>\Examples\NXP\LPC1000\LPC11xx\examples.lpc11xx.new.zip

There is also an apps note on the NXP website that you might want to look at:

http://ics.nxp.com/support/documents/microcontrollers/pdf/an10968.pdf

Hope this helps :)
0 Kudos
Reply