Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
10 years, 3 months ago.
NUCLEO-F401RE writing to flash from program?
I had this simple class for reading/writing to flash. It worked fine until the program grew. Now it overwrites the program in flash, crashing the whole thing. Is there any way I can access bank number 2? The NUCLEO-F401RE has 512KB flash, so there should be plenty of space. I could also leave 'a hole' in my program (with a magic marker at the beginning), in case the whole flash will always be overwritten eventually. Btw., FLASH_SECTOR_5 doesn't seem to be working either. I didn't find much on accessing flash. Therefore, this was the best I could come up with:
persiststor.h
class PersistentStorage {
public:
static const int StorageSize = 64;
static unsigned int storage[ StorageSize ] __attribute__((aligned(32)));
enum StorageOffsets { RandomSeed = 0 };
static void readStorageFromFlash();
static bool writeStorageToFlash();
static inline unsigned int get( int offs ) { return offs >= StorageSize ? 0x77777777 : storage[ offs ]; }
static inline void set( int offs, unsigned int x ) { offs < StorageSize ? storage[ offs ] = x : true; }
private:
PersistentStorage();
};
persiststor.cpp
#include "mbed.h"
#include "persiststor.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal_flash.h"
#include <stdlib.h>
struct Sector {
uint32_t address, sector;
};
Sector FlashMem[ 7 ] = {
{ 0x08000000, FLASH_SECTOR_0 }, // 16 KB
{ 0x08004000, FLASH_SECTOR_1 }, // 16 KB
{ 0x08008000, FLASH_SECTOR_2 }, // 16 KB
{ 0x0800C000, FLASH_SECTOR_3 }, // 16 KB
{ 0x08010000, FLASH_SECTOR_4 }, // 64 KB
{ 0x08020000, FLASH_SECTOR_5 } // 128 KB
};
const int USE_FLASH_SECTOR = 4;
unsigned int PersistentStorage::storage[ StorageSize ] __attribute__((aligned(32)));
void PersistentStorage::readStorageFromFlash() {
HAL_FLASH_Unlock();
memcpy( (uint32_t*)storage, (uint32_t*)FlashMem[ USE_FLASH_SECTOR ].address, StorageSize );
HAL_FLASH_Lock();
}
bool PersistentStorage::writeStorageToFlash() {
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_EOP | FLASH_FLAG_OPERR |FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR );
FLASH_EraseInitTypeDef eraser;
eraser.TypeErase = TYPEERASE_SECTORS;
eraser.Banks = FLASH_BANK_1;
eraser.Sector = FlashMem[ USE_FLASH_SECTOR ].sector;
eraser.NbSectors = 1;
eraser.VoltageRange = VOLTAGE_RANGE_3;
uint32_t sectorerr = 0;
if( HAL_OK != HAL_FLASHEx_Erase( &eraser, §orerr ) || sectorerr != 0xFFFFFFFF ) {
HAL_FLASH_Lock();
return false;
}
for( int i = 0; i < StorageSize; ++i ) {
if( HAL_OK != HAL_FLASH_Program( TYPEPROGRAM_WORD, FlashMem[ USE_FLASH_SECTOR ].address + i * sizeof( storage[ i ] ), storage[ i ] ) ) {
HAL_FLASH_Lock();
return false;
}
}
HAL_FLASH_Lock();
return true;
}
I found this library for reading/writing to flash:
I rewrote my code to use this library and read/write to sector 7 (the last flash sector of the NUCLEO-F401RE). It now works nicely. Thank you Hill Kim for your library! The NUCLEO-F401RE doesn't have a second bank. Here's the flash layout in case anybody wonders:
Flash layout of NUCLEO-F401RE (note: everything is in hexadecimal!):