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.
9 years, 4 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!):