Skip to main content
aamirali641989
Associate III
September 8, 2014
Question

using a block of flash as eeprom

  • September 8, 2014
  • 4 replies
  • 957 views
Posted on September 08, 2014 at 08:36

I want to use block of flash(16KB) as eeprom.

I am using STM32F205RBT6 & keil 4.

What I have to do:

1. Store 5Kb of user data & retrieve it on startup.

2. Flash endurance of 10000 cycles is good for my project & I have fixed 16Kb block for it.

What I have done is :

1. OPtion for target-> target-> (check)IROM1 ; Start 0x8000000 ; size 0x4000 OPtion for target-> target-> (check)IROM2 ; Start 0x8008000 ; size 0x18000

i.e fixing flash block 0x80004000 fix for eeprom whose size is 16Kb

2. Flah write code for 5Kb data:

void flash_write(void)
{
uint32_t address = 0x08004000;
uint32_t data;
uint32_t cnt = 0;
/* read entire sector */
while(address < 0x08008000)
{
data = *(__IO uint32_t*)address;
flah_union.data_u32[cnt++] = data;
address = address + 4;
}
/* fill the array */
for( cnt = 0 ; cnt < 5120 ; cnt++ )
{
flah_union.data_u8[cnt] = g_ft232_arr_data[cnt];
}
/* unlock flash */
FLASH_Unlock();
/* Clear pending flags (if any) */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
/* erase the entire sector */
if (FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3) != FLASH_COMPLETE)
{
/* Error occurred while sector erase.
User can add here some code to deal with this error */
while (1)
{
}
}
/* write back array */
address = 0x08004000;
cnt = 0;
while(address < 0x08008000)
{
if (FLASH_ProgramWord(address, flah_union.data_u32[cnt++]) == FLASH_COMPLETE)
{
address = address + 4;
}
else
{
while (1)
{
}
}
}
FLASH_Lock();
}

3. Flash read code for 5Kb data:

void flash_read(void)
{
uint32_t address = 0x08004000;
uint32_t data;
uint32_t cnt = 0;
/* read entire sector */
while(address < 0x08008000)
{
data = *(__IO uint32_t*)address;
flah_union.data_u32[cnt++] = data;
address = address + 4;
}
/* fill the array */
for( cnt = 0 ; cnt < 5120 ; cnt++ )
{
g_ft232_arr_data[cnt] = flah_union.data_u8[cnt];
}
}

My queries:

1. Do I need to disable interrupts before reading or writing to flash even if I had defines separate block for eeprom, as I said earlier.

2. Since I am writing to flash & also while write to flash, code is getting executing from flash i.e code for reading/writing flash. Do I need to move the code to Ram?

If yes how

Edit: All the flash function inside write/read functions are called from standard peripheral library provided by ST.

    This topic has been closed for replies.

    4 replies

    waclawek.jan
    Super User
    September 8, 2014
    Posted on September 08, 2014 at 11:46

    Attempt to read (= fetch code) from flash during erase and program causes the processor to stall.

    Read the relevant chapter from UM.

    All code you want to run during flash program/erase (including ISRs) should go to RAM. Read the manual of your toolchain to learn how to do that.

    JW
    aamirali641989
    Associate III
    September 8, 2014
    Posted on September 08, 2014 at 13:38

    Hi,

    1. I have disabled interrupts before entering the flash read/write functions.

    2. Also the sector which I had defines is FLASH_Sector_1, this is not where ISR are located. 

    3. Since I had done settings in keil compiler such that it don't put any flash code in sector which I had selected for eeprom eemulation.

    Do I still need to put code in RAM.

    4. I was looking at AN3390, ST didn't put their code in RAM while emulating SRAM.

    5. Any example code??

    waclawek.jan
    Super User
    September 8, 2014
    Posted on September 08, 2014 at 14:03

    > Do I still need to put code in RAM.

    You never needed to do that if you don't mind that the mcu is ''frozen'' until erasing/programming finishes.

    JW

    Tesla DeLorean
    Guru
    September 8, 2014
    Posted on September 08, 2014 at 17:26

    1. I have disabled interrupts before entering the flash read/write functions.

    Unless you have contention between read/write (ie read in an interrupt) this doesn't seem necessary, you could use a mutex, or have a RAM copy of the current content, and then write that to flash, and not read the flash version.

     

    2. Also the sector which I had defines is FLASH_Sector_1, this is not where ISR are located. 

    The system doesn't care, it is in the same BANK, on the same flash controller.

    3. Since I had done settings in keil compiler such that it don't put any flash code in sector which I had selected for eeprom emulation. Do I still need to put code in RAM.

     

    You don't but the process WILL stall, and the ERASE can take a LONG TIME which can exceed the service window of peripherals, and make real time operation problematic.

    4. I was looking at AN3390, ST didn't put their code in RAM while emulating SRAM.

    It's also a pretty lame library, understand how FLASH works, it's limits/expectations, and code something that does the job you actually need.

    5. Any example code??

    Putting all the code in RAM is a non-trivial task, you're getting a bit over your skis here. Getting code into RAM is not hard, the system/coding choices require you to understand what you're actually trying to achieve and why.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..