Author Topic: FLASH blocks  (Read 10382 times)

Offline twoerner

  • Newbie
  • *
  • Posts: 16
    • View Profile
FLASH blocks
« on: July 20, 2007, 08:32:22 PM »
I have just one more piece of the puzzle to understand: writing data to the flash.

As I understand it, if I wanted to write just 1 byte to flash I first need to erase the entire block in-which that 1 byte is found. How large is the size of the block that must be erased? So to write 1 byte would require me to save and entire block to RAM, modify the 1 byte in RAM, erase the entire block on FLASH, then write the entire block from RAM to FLASH, right?

I've so far been looking at fnEraseFlashSector() and fnWriteBytesFlash(). These are great, but I'll need to know the block size in order to use them correctly. I'm guessing uTasker probably has some functions and/or defines that make this easier?

Looking at uTasker's fnEraseFlashSector() it would appear that 1 flash block is 0x1000 bytes (given that the address is ANDed with ~0x3. But looking through the code that comes with Freescale's dBUG program there is a define in cfm_flash.h that appears as though the block size is 0x800. I guess there's a fair amount of confusion because different texts refer to "block page size", "block sector size", "flash block size", "flash logical block size", ...and several more permutations on what may or may not be the same concept.

I've been playing around with fnEraseFlashSector() and fnWriteBytesFlash() and can see that I can modify bytes of FLASH, but without understanding everything that is going on I can't use them effectively.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: FLASH blocks
« Reply #1 on: July 20, 2007, 09:21:48 PM »
First some facts about the FLASH in the M5223X.

The FLASH granularity is 2k (0x800). If you study the data sheet you will in fact find it very difficult to work this out - I believed that it was larger until really working with the chip!
The granularity (#define FLASH_GRANULARITY    (2*1024)  in m5223x.h) means that this is the smalled block or sector which can be individually erased.

The next thing to know is that it is always necessary to program a long word (32 bits) which must be on a long word boundary (0,4,8,0x0c, 0x10 etc) - this is in fact the &= ~3 which you have seen in the code.

The flash supports 'cumulative writes' which means that it is possible to program individual bits in a word from '1' to '0' (there may be some restrictions due to stresses in the chip when this is done but the technique has been very successful in the Coldfire - and its 'Super' FLASH) - comments welcome!

FLASH writes and deletes block the use of the entire FLASH in teh M5223X so the manipulation routines have to run from SRAM. Interrupts are blocked during the process.

The uTasker routines enable you to program any byte in FLASH once.
If you need to reprogram a byte in a sector (2k) to a value involving setting any bits from '0' to '1' the only possibility is to first delete the sector that it is in and then program everything back. This is called EEPROM emulation.

However the uTasker uses the FLASH normally as File System and Parameter System and in this use it is in fact never necessary to do EEPROM emulation. The parameter system generally uses a 'Swap block' and so changes are made in a second sector. Once complete, the old swap block is deleted and the new used as valid one (this is mostly invisible to the user). The main reason for this and not using EEPROM emulation is quite simple - what happens when you get a reset or power down while you are copying the data (you have copied the original block to RAM, you have changed the bytes you wanted and you are deleting the FLASH section to get ready for copying back. Then the power is pulled. Ooops - all gone and hopefully your device is not on board the next Mars mission and just updating some critical parameters to allow it to find its way back to its docking station...)?

The file system fits files (at least on chips with small granularity) in to the number of sectors needed (no two files ever share a single sector). When a new file is copied the algorithm knows which sectors must be deleted to remove any files which may be in the way (bull dozer method as described in the uFileSystem documentation).

It is of course possible to use the low level calls:
extern int  fnEraseFlashSector(unsigned char *ptrSector);
extern int  fnWriteBytesFlash(unsigned char *ucDestination, unsigned char *ucData, MAX_FILE_LENGTH Length);


but generally you find that you will be rewriting something that resembles either the parameter system routines (to avoid chance of data loss) or the file system, so it is best to be sure than the higher level calls really don't do what you want.

These calls are also processor independent (each processor supported by the uTasker will support them) but there are some processor-specific rules which have to be respected - the processor specific rules are also handled in the higher level routines for the parameter system and file system. For example you obviously need to know the size of the sector to use fnEraseFlashSector() - 2k on the M5223x, 512 byte on the NE64, 256 bytes on the SAM7X, 64K!! on the STR91XF (or 8k in bank 1) and I am not sure on the LPC23XX but it is also quiete big and has different values in different banks.
The M5223X supports cumulative writes - the low level routines should handle details about long word alignment (I think). The NE64, for example, doesn't support cumulative writes and always short words (16 bit) have to be written.

The FLASH is accurately simulated in the uTasker simulator so it is always much simpler to test the use of new FLASH manipulating code in the simulator first. It is also designed to throw an exception if you were to do things which the FLASH can't do to save strange behaviour later on the target, where debugging can be rather tedious..

Regards

Mark

Offline Renan

  • Newbie
  • *
  • Posts: 15
    • View Profile
Re: FLASH blocks
« Reply #2 on: September 18, 2009, 02:52:09 PM »
HI Mark,

I have to write data in flash and these data can not be changed when I make an upload.
I'm writing at the end of the boot loader (0x7FC) and I would like to know I have some problem in writing this region of the flash??
After I write in flash I can lock this block to prevent it from being modified?

Regards,

Renan.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: FLASH blocks
« Reply #3 on: September 19, 2009, 11:40:48 PM »
Hi Renan

The demo project doesn't protect any sections of FLASH and so all memory locations (also ones in te boot loader FLASH sector) can be written to.
Unfortunately there is a problem to protect only the boot loader sector since the FLASH is protectable only on an 8k block basis (which would protect also the first 6k of application). It would be possible to move the application start address to 0x2000 if this caused a difficulty

To protect the first 8k of FLASH, the FLASH configuration parameters need to be changed in the boot loader project (see flash_config.s).

/*
 * FLASH configuration
 */
FLASH_CONFIG:
_FLASH_CONFIG:
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
.end


The third long word entry contains the protected sections, so to protect the first it needs to be changed to .long 0x00000001

If you need to write to this section it is generally still possible by first clearing the protection in the CFMPROT register. (This can also be restricted by setting the LOCK bit in the CFMMCR register). Also the section can be protected by code setting the protection in the CFMPROT register on every start up.

Regards

Mark