Saving to Flash for Dummies - MCF52235

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

Saving to Flash for Dummies - MCF52235

2,773 Views
cmag
Contributor I
Howdy all,
 
I'm almost done with this **** project, and then I should be out of y'alls hair forever.  I'm using ColdFire lite for everything (TCP, UARTs, I2C, etc) and am completely done, except saving configuration variables such as system IP and such to flash so they'll still be there when my system craps out and needs a reboot.
 
I have a general idea of what I need to do in the linker file, at least in the Memory and Sections part.  My project is called "informs so it looks a lil something like this:
 
MEMORY
{
    flash   (RX)   : ORIGIN = 0x00000000, LENGTH = 0x0001FFBF
    informs_vars (RX) : ORIGIN = 0x0001FFC0,  LENGTH = 0x00000040
    vectorram(RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
    sram (RWX)  : ORIGIN = 0x20000400, LENGTH = 0x00007C00
    ipsbar  (RWX)  : ORIGIN = 0x40000000, LENGTH = 0x0
}

and
 
SECTIONS
{
 yadda yadda
} > flash
 .informsArraySection :
    {
     *(.informsArrayZone)
    } > informs_vars
   
    .data : AT(___DATA_ROM)
 {
  yadda yadda
 }
 
 
Anyway, that's fantastic, now what?  I can't find any clear cut explination for morons as to what I do next.  Is there anyway someone can dumb this down for me.  It's beyond me as to why I can figure out how to create RTOS tasks that utilize non-blocking TCP sockets, and I can't for the life of me figure this thing out.
 
BTW, I'm using the education version of codewarrior so even though I really have 256k of flash, I don't think the software is going to let me use the upper 128.  I'm not sure if that has any relivance here, but just FYI.
 
Thanks as always, you guys have rocked.
cmag


Message Edited by cmag on 2008-04-28 07:14 PM
Labels (1)
0 Kudos
5 Replies

454 Views
RichTestardi
Senior Contributor II
Hi Cmag,
 
Not to be a broken record, but did you try just erasing and writing a flash page (especially one above 128k that you can't use anyway!) with the code here:
 
 
I'm doing that all the time and it sure seems easy...
 
-- Rich
 
0 Kudos

454 Views
cmag
Contributor I
"Not to be a broken record"
 
Not at all Rich.  I guess the problem is, the area of memory/flash/etc is one that I think I have too little understanding, and unfortunatly, I don't have time to  understand because I'm pushing a hard deadline. 
 
So, I'll ask you a couple of questions and please feel free to call me an idiot when I'm done if I present myself as such because I'm fairly open to anything anyone has to say at this point.  Please bear with me while I try to work this out in my head. :smileywink:
 
I've got my linker file set up, although you're recommending I end flash at 128k, and start informs_vars immediatly after it.  I have to erase and write by the page size so I may as well make informs_vars 0x800 bytes.  I presume this should be appropriate:
 
MEMORY
{
    flash   (RX)   : ORIGIN = 0x00000000, LENGTH = 0x00020000
    informs_vars (RX) : ORIGIN = 0x00020000,  LENGTH = 0x00000800
    vectorram(RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
    sram (RWX)  : ORIGIN = 0x20000400, LENGTH = 0x00007C00
    ipsbar  (RWX)  : ORIGIN = 0x40000000, LENGTH = 0x0
}

 
Next, say the end user has run through the configuration program and all of his/her answers have been stored temporarily to an array (I'm assuming the variables also have to be uint32 for simplicity so we'll say I have 20 variables to save and have them in uint32 temp[20]).  He/she is ready to save the variables, I first want to run a lil something like this :
 
flash_erase_pages(0x20000, 1)             <--- actually I'm pretty sure I'm misinterpreting what npages is.
                                                                       I was assuming it was the number of pages I want to erase
                                                                      (just one) but probably not since it's also a uint32.  That
                                                                     would be pretty serious overkill.
 
Next I would want to write them into the page I just erased using the function
 
flash_write_words(uint32 *addr, uint32 *data, uint32 nwords)
I'm guessing I could do something like
 
flash_write_words(0x20000, temp, 20)                 <-- again, with the last one, I'm unsure
 
 
Barring the couple of errors I'm sure I've made, is it just that simple?  If so, I really am a moron. 
 
Where does flash_initialize(void) come in.  Also, in my linker file, I've created a section like this:
 
.informsArraySection :
    {
     *(.informsArrayZone)
    }

Am I ever going to have anything explicitly in my code that's going to call that or do anything with that, or is it just implied when I'm doing my erase and write functions.

Thanks again Rich.

cmag


 
 
0 Kudos

454 Views
RichTestardi
Senior Contributor II
Hi cmag,
 
Yes, what Mark said! :smileyhappy:
 
A few clarifications for you:
 
> actually I'm pretty sure I'm misinterpreting what npages is.
 
npages is the number of 2k pages -- yes, a uint32 is overkill!  Set it to 1 to erase a
single 2k page.
 
Also, as Mark has mentioned in a few posts, the other thing you might want to do
is swap a pair of pages, in case you ever lose power during the flash update.
 
What I do is always have "two banks" of whatever I am writing, and I use the last
uint32 of the page as a "generation number"...  Then I decide which bank is
"current" (for reading) by comparing the two with a statement like:
 
  if (generation(page1)+1 > generation(page2)+1) {
    // page1 is current
  } else {
    // page2 is current
  }
 
The "+1" lets the erased page (0xffffffff) always be considered the oldest generation.
 
Then, when it is time to update a variable, I figure out which page is current and
write the *other* page with the new values, and then set the other page's generation
number to the current page's generation plus one, thus making the "other page"
now be the "current page".
 
That might be overkill if you only update flash infrequently, but if you do it often, it
can protect you from waking up with an erased page (if say you lost power between
the flash_erase_pages() and flash_write_words() of an update).
 
Good luck!
 
-- Rich
 
0 Kudos

454 Views
mjbcswitzerland
Specialist V
Hi cmag

>>Where does flash_initialize(void) come in

The flash initialisation needs to be performed once before the FLASH routines are called, otherwise the controller is not correctly configured. Therefore call is once as soon as your program starts and then it doesn't need to be used again.

I don't know why you are defining space in the linker since the position of the FLASH based variables is completely controlled by code (0x20000 in this case). Therefore to save your array of user data (temp) use
flash_write_words(0x20000, temp, 20);
Then to load them back use
memcpy(temp, 0x20000, (20*sizeof(uint32));
And, to delete them (set to 0xffffffff) use
flash_erase_pages(0x20000, 1);

It does therefore look to be as simple as you have depicted. I haven't actually understood what is not working. The routines have been proven and the use is quite clear - can you explain what is going wrong?

Regards

Mark

www.uTasker.com


0 Kudos

454 Views
cmag
Contributor I
Hey there Mark,
 
It's not that it's not working.  Actually I haven't been to the lab in a couple of days to work on this particular issue, it's just that I believe I was over analyzing the situation.  A couple of weeks ago when this was in the back of my mind I decided to start on an "information gathering" mission so I would be prepared when I was to start dealing with the process.  My first several searches always brought up little pieces of the puzzle but never put anything together, and frankly probably steered me in the wrong direction (hence the separate section for informs_vars).  I assumed I needed to create a small "safe haven" for my variables so they wouldn't be overwritten, but obviously if I look at my memory map I can figure out where these are anyway so I guess it's not necessary.  As I said earlier, I don't think I was grasping how all the flash/memory/etc fit together, but I'm pretty sure I've got it now.
 
Anyways, thanks for the help guys.
 
Scholars and gentlemen you are:smileyhappy:
 
cmag
0 Kudos