Storing settings

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

Storing settings

4,117 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mhjerde on Thu Mar 04 13:52:21 MST 2010
Hi

What is the best strategy for storing non-volatile data for the LPC1343?

Preciously I've used 8-bit controllers and stored user settings to the onboard eeprom memory. It's not a lot of data, a few hundred bytes at most.

Should I add an eeprom chip to the board, or is there a better way?

M
0 Kudos
Reply
21 Replies

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fpg on Wed Oct 19 09:14:02 MST 2011

Quote: fpg
I'm using the free version of LPCXpresso IDE which limits code size 128kB and I have to use flash memory to store data. Can I assume that my code is in the lower 128k or do I have to make sure by modifying linker script?



I found the answer, the automatically generated linker script puts the code into the lower 128k.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fpg on Tue Oct 18 07:50:00 MST 2011

Quote: CodeRedSupport
If you want to reserve a specific area of flash for you code, you do it by creating you own linker script, an stopping the application from using it. Perhaps the simplest way is just to reduce the amount of flash available to the the application by subtracting it from the top of the flash region. See:
http://lpcxpresso.code-red-tech.com/LPCXpresso/node/31
For instructions on creating your own linker scripts.



I'm using the free version of LPCXpresso IDE which limits code size 128kB and I have to use flash memory to store data. Can I assume that my code is in the lower 128k or do I have to make sure by modifying linker script?
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by coryrc on Fri May 27 13:26:19 MST 2011

Quote: micrio
This is the flash writing code that I wrote. It works properly except for the problems noted in earlier posts.



I know this is an old thread, but it was the first to come up when I googled, so I'm going to add my findings here.

In addition to the above code, you also need to save the top 32 bytes of RAM for IAP:
http://support.code-red-tech.com/CodeRedWiki/ReserveIAPRam

Then, to avoid using magic constants, you need to modify the linker to name the sector(s) you want to use for storage. Unfortunately, each sector is 4kB :(. I still need to figure out how to do it with flash, but here's how to do it with RAM:
http://support.code-red-tech.com/CodeRedWiki/EnhancedManagedLinkScripts
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Sat Jul 17 09:07:26 MST 2010
If I understand you correctly; you specify the address in RAM that contains the data to be written to the FLASH_WR command. The flash write routine will copy the data from the RAM and write it into the flash. The length of the data is also specified but it must be rounded up to be a multiple of 256 bytes.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by JoeMoney on Fri Jul 16 16:34:26 MST 2010
How do you define the source RAM address? do you just state the variable name on the command?
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Mon Apr 19 07:43:44 MST 2010
If your code is larger then 4K then you have a real problem. You can never use erase in the normal way!

There are some tricks that you can use;

You can only write to flash memory in multiples of 256 byte blocks. Thus, you can define an array of 256 byte blocks that fill the rest of available flash. Each block can be written once. If you need to write the block again, you zero out the current block and move to the next. This gives you a fixed number of writes that you can do. If you can work with that number then you are OK. This uses the characteristic of flash that it is erased to 0xff and can only be written to zero. Thus, bits that contain a 1 can be written to 0 but not the reverse.

Alternatively you can copy the code that spills over into the second sector in to RAM (if you have enough available RAM). Then you erase the entire sector. Next copy the code back along with the data that you want to save to flash. This has obvious risks; what if you lose power during the process? Also, you must insure that the copied code is not used during this process.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by german on Mon Apr 19 00:08:35 MST 2010
Ok,

- debug_mem.ld -->

MEMORY
{
  /* Define each memory region */
  MFlash8 (rwx) : ORIGIN = 0x0, LENGTH = 0x0FFF /* 4k */
  RamLoc4 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x800 /* 2k */

}
  /* Define a symbol for the top of each memory region */
  __top_MFlash8 = 0x0 + 0x0FFF;
  __top_RamLoc4 = 0x10000000 + 0x800;

But  I get --> n/ld.exe: region MFlash8 overflowed by 2809 bytes
collect2: ld returned 1 exit status

I'm using te optimization tool to maximun level.

It's not possible to restrict the flash rom use to a minor area than a full sector?

This is the code i'm using-->

#define SystemFrequency SystemCoreClock
#define PREP_WR 50
#define FLASH_WR 51
#define ERASE_SEC 52
#define FLASHSEC 1;
#define FLASHDIR 0x00001F00
/* Call into embedded utility. */
#define IAP_LOCATION 0x1fff1ff1

void write_nonvolatile_parameters(void){
    /* First we will prepare the sector for erase. */
    command[0] = PREP_WR;
    command[1] = FLASHSEC;
    command[2] = FLASHSEC;
    iap_entry (command, result);
    if (result[0] != 0) {
    /* This is an error. */
    result[0] = 0xff;
    return;
    }
    /* Next we will erase the sector. */
    command[0] = ERASE_SEC;
    command[1] = FLASHSEC;
    command[2] = FLASHSEC;
    command[3] = SystemFrequency / 1000; /* Must be in terms of cycles per millisecond. */
    command[4] = 0;
    iap_entry (command, result);
    if (result[0] != 0) {
    /* This is an error. */
    result[0] = 0xff;
    return;
    }
    /* We will prepare the sector for write. */
    command[0] = PREP_WR;
    command[1] = FLASHSEC;
    command[2] = FLASHSEC;
    iap_entry (command, result);
    if (result[0] != 0) {
    /* This is an error. */
    result[0] = 0xff;
    return;
    }
    /* Then we will write the sector. */
    command[0] = FLASH_WR;
    command[1] = FLASHDIR;
    command[2] = vRef; //extern volatile uint32_t vRef = 3300;
    command[3] = 256;
    command[4] = SystemFrequency / 1000; /* Must be in terms of cycles per millisecond. */
    iap_entry (command, result);
    if (result[0] != 0) {
    /* This is an error. */
    result[0] = 0xff;
    return;
    }
}

uint32_t read_nonvolatile_parameters(void)
{

    unsigned long *add;
    uint32_t value=0;

    add=(unsigned long *)FLASHDIR;
    value=*add;
}

I get this --> HardFault_Handler(void)
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Sun Apr 18 15:24:40 MST 2010
In that chip you have exactly one chioce: 0x1000. There are only two "sectors" in that chip and your code must reside in the first sector. Therefore your erasable sector must be the second one.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by german on Sun Apr 18 09:35:05 MST 2010
Hi,

I'm working with an LPC1111/101 (8KB Flash- 2KB Ram)

I need to define a safe area in flash to read/write 8 uint32 data parameter after a calibration process when application program is running.

How i get the place or safe area to write the parameters? 
How i need to modify the link file to get it?
where is this information on .map file?

Thanks,
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Sat Mar 13 14:08:40 MST 2010
I had abug in my code, I forgot to set the SystemFrequency for the erase command. Here is the corrected code;

[LEFT][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* Next we will erase the sector. */[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#3f7f5f]
[/COLOR][/SIZE][SIZE=2]command[0] = ERASE_SEC;[/SIZE]
[SIZE=2]command[1] = page;[/SIZE]
[SIZE=2]command[2] = page;[/SIZE]
[SIZE=2]command[3] = SystemFrequency / 1000; [/SIZE][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* Must be in terms of cycles per millisecond. */[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#3f7f5f]
[/COLOR][/SIZE][SIZE=2]command[4] = 0;[/SIZE]
[SIZE=2]iap_entry (command, result);[/SIZE]
[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]if[/COLOR][/SIZE][/COLOR][/SIZE][/B][SIZE=2] (result[0] != 0) {[/SIZE]
[SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* This is an error. */[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#3f7f5f]
[/COLOR][/SIZE][SIZE=2]result[0] = 0xff;[/SIZE]
[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]return[/COLOR][/SIZE][/COLOR][/SIZE][/B][SIZE=2] (-1);[/SIZE]
[SIZE=2]}[/SIZE][/LEFT]

[LEFT][SIZE=2]Pete.[/SIZE][/LEFT]
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Wed Mar 10 07:54:29 MST 2010
The debugger does not use any flash and only programs what you request (i.e your application). I think there is a problem in your code.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Wed Mar 10 07:11:30 MST 2010
The reason that I think the debugger is doing things behind my back is that the write does work somewhat. If you pick a location that contains a 0xff in an upper area to write to, the write will work but you will notice that the erase did not seem to work. Erase sets the entire page to 0xff. If you write to a location that contains some number you will get the & (and) of the original number and your number.

By this I am assuming that the debugger, Code-Red environment, needs to occupy some space in the flash. I would like to know what to stay away from but I see nothing in the .map file. I have not seen any mention of this in the documentation.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mhjerde on Tue Mar 09 09:14:02 MST 2010
Thanks Pete
It works. But I experienced the same issue as you, writing to the higher addresses does not stick.
Thanks a ton!
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Mon Mar 08 16:33:59 MST 2010
This is the flash writing code that I wrote. It works properly except for the problems noted in earlier posts. I believe that the problem is that the Embedded Artists debugger is using some of the flash for it's own puropses.

I looked at the .map file and there is nothing listed above my code. This routine works properly when I stay away from the mysterious flash addresses. When I erase the mysterious data it magically re-appears. Clearly something is going on behind my back. I hope that when my own board design is done that I won't have these problems.

Pete.

Ps; I notice that my tabs got wiped out, sorry.


[FONT=Courier New]#define PREP_WR 50[/FONT]
[FONT=Courier New]#define FLASH_WR 51[/FONT]
[FONT=Courier New]#define ERASE_SEC 52[/FONT]
[FONT=Courier New]/* Call into embedded utility. */[/FONT]
[FONT=Courier New]#define IAP_LOCATION 0x1fff1ff1[/FONT]
[FONT=Courier New]void (*iap_entry)(unsigned long *, unsigned long *) = (void *)IAP_LOCATION;[/FONT]
[FONT=Courier New]unsigned long command[5];[/FONT]
[FONT=Courier New]unsigned long result[4];[/FONT]
[FONT=Courier New]/* state_sec is the location in flash to write. */[/FONT]
[FONT=Courier New]/* sys_state is the structure in RAM to write to flash. */[/FONT]
[FONT=Courier New]void[/FONT]
[FONT=Courier New]write_state(void){[/FONT]
[FONT=Courier New]/* First we will prepare the sector for erase. */[/FONT]
[FONT=Courier New]command[0] = PREP_WR;[/FONT]
[FONT=Courier New]command[1] = state_sec >> 12;[/FONT]
[FONT=Courier New]command[2] = state_sec >> 12;[/FONT]
[FONT=Courier New]iap_entry (command, result);[/FONT]
[FONT=Courier New]if (result[0] != 0) {[/FONT]
[FONT=Courier New]/* This is an error. */[/FONT]
[FONT=Courier New]result[0] = 0xff;[/FONT]
[FONT=Courier New]return;[/FONT]
[FONT=Courier New]}[/FONT]
[FONT=Courier New]/* Next we will erase the sector. */[/FONT]
[FONT=Courier New]command[0] = ERASE_SEC;[/FONT]
[FONT=Courier New]command[1] = state_sec >> 12;[/FONT]
[FONT=Courier New]command[2] = state_sec >> 12;[/FONT]
[FONT=Courier New]iap_entry (command, result);[/FONT]
[FONT=Courier New]if (result[0] != 0) {[/FONT]
[FONT=Courier New]/* This is an error. */[/FONT]
[FONT=Courier New]result[0] = 0xff;[/FONT]
[FONT=Courier New]return;[/FONT]
[FONT=Courier New]}[/FONT]
[FONT=Courier New]/* We will prepare the sector for write. */[/FONT]
[FONT=Courier New]command[0] = PREP_WR;[/FONT]
[FONT=Courier New]command[1] = state_sec >> 12;[/FONT]
[FONT=Courier New]command[2] = state_sec >> 12;[/FONT]
[FONT=Courier New]iap_entry (command, result);[/FONT]
[FONT=Courier New]if (result[0] != 0) {[/FONT]
[FONT=Courier New]/* This is an error. */[/FONT]
[FONT=Courier New]result[0] = 0xff;[/FONT]
[FONT=Courier New]return;[/FONT]
[FONT=Courier New]}[/FONT]
[FONT=Courier New]/* Then we will write the sector. */[/FONT]
[FONT=Courier New]command[0] = FLASH_WR;[/FONT]
[FONT=Courier New]command[1] = state_sec;[/FONT]
[FONT=Courier New]command[2] = &sys_state;[/FONT]
[FONT=Courier New]command[3] = 256;[/FONT]
[FONT=Courier New]command[4] = SystemFrequency / 1000; /* Must be in terms of cycles per millisecond. */[/FONT]
[FONT=Courier New]iap_entry (command, result);[/FONT]
[FONT=Courier New]if (result[0] != 0) {[/FONT]
[FONT=Courier New]/* This is an error. */[/FONT]
[FONT=Courier New]result[0] = 0xff;[/FONT]
[FONT=Courier New]return;[/FONT]
[FONT=Courier New]}[/FONT]
[FONT=Courier New]}[/FONT]
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mhjerde on Mon Mar 08 14:28:52 MST 2010
Thanks, that certainly makes things a lot clearer!

I see that the user manual has a section on IAP and it's pretty clear to me that I'm not ready to tackle the gory details of this including timing issues and whatnot. This is an area that cries out for library code, IMHO. Or some example code suitable for the less enlightened among us, like myself :-)
I'll have a go at this a bit further down the road.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Mon Mar 08 01:31:12 MST 2010
ARM define generic processors that they license to semiconductor manufacturers, such as NXP.

NXP, then take the generic design and turn it into a specific design that you can purchase - an LPC1343, for example. Each manufacturer adds its own flash/ram/peripherals to the generic design. The size of the flash/ram and the set of peripherals varies by manufacturer and by part.

The ARM documentation is generic (and common to EVERY semiconductor manufacturer).

If you are trying to program a specific part, then you need to read the documentation for that part.

So, while ARM specifies that Flash/RAM occupies a certain space in the address map, you need to look at the docs to see what is actually available in the part you are using.

Typically, code will be placed in Flash, and Data will be placed in RAM. However, you can place (read-only) data in Flash.

When you create an application, the amount of code/data you are using will depend entirely on your application... To see what is use, you need to look in the .map file (found in the Debug or Release directory after a build). This will show you exactly where each piece of code/data is placed in memory.

If you want to reserve a specific area of flash for you code, you do it by creating you own linker script, an stopping the application from using it. Perhaps the simplest way is just to reduce the amount of flash available to the the application by subtracting it from the top of the flash region. See:
http://lpcxpresso.code-red-tech.com/LPCXpresso/node/31
For instructions on creating your own linker scripts.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by mhjerde on Sun Mar 07 16:43:51 MST 2010
I guess there is some basic concept that I don't understand here...

My understanding is that on the ARM processors there is a single continuous memory space. Code and "data" is stored together. According to the Cortex tech ref manual, the area from 0 to 0x1FFF FFFF is the code area. Since the LPC1343 don't have half a gig of memory, but only 32K, the code area should be 0x0000 0000 to 0x0000 7FFF.

So I guess my question is: If I write to this area, how do I know that I'm not writing over my own code? Is it as simple as looking at the size of the code that is written to flash? If my code is 16k, I can safely store stuff anywhere between  0x000 4000 (16k) and 0x000 7FFF (32k)?




http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337e/DDI0337E_cortex_m3_r1p1_trm.pdf
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Fri Mar 05 06:44:21 MST 2010
There is still some problem. The LPC1343 on my LPCXpresso board says that I have 8 sectors and that I can write 256 bytes. That works if I write at 0x2400. However if I attempt it at 0x7f00 it does not work.

I prepare sector 7, then erase sector 7, then prepare sector 7, and finally write 0x7f00 for 256 bytes. Each command returns 0 (good status). However, the sector is not erased and the data is not written.

I tried it at 0x5e00 which was already erased and already contined 0xffffffff's. That worked, but the entire sector was not erased! There is text at 0x55c0 saying "Embedded Artists Welcome to the LPC-Xpresso demo program" etc. Is the LPCXpresso environment writing the flash with it's own stuff after I have erased it?
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Fri Mar 05 05:01:28 MST 2010
Anywhere is 'legal', but you can only program in certain block sizes, depending on the actual part you are using.
0 Kudos
Reply

4,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by micrio on Thu Mar 04 22:09:55 MST 2010
How can I know what are the legal areas to progam in flash? If I try to write at 0x7f00 in my LPC1343 no error codes are returned but the write does not work. If I try lower address like 0x2400 it does work. Is there a map available?
0 Kudos
Reply