From e9dbcd31516cd10197565d0883e6440140f553a5 Mon Sep 17 00:00:00 2001 From: Nils Hasenbanck Date: Sat, 15 Sep 2018 09:05:08 +0200 Subject: [PATCH 1/2] [EEPROM emulation] Rework for buffered access The current EEPROM emulation didn't had any buffered access to the data on the flash. Every access to a byte would trigger a whole page read / write. For writes it would mean, that the whole page would be erased. For backward compability we will keep the current functions as they are, but will add functions to fill/flush the buffer and read from it. The buffer size is static and is one page in size. Fixes: #296 Signed-off-by: Nils Hasenbanck --- cores/arduino/stm32/stm32_eeprom.c | 64 ++++++++++++++++++------------ cores/arduino/stm32/stm32_eeprom.h | 9 ++++- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/cores/arduino/stm32/stm32_eeprom.c b/cores/arduino/stm32/stm32_eeprom.c index 99de58b26a..4fc3725ff4 100644 --- a/cores/arduino/stm32/stm32_eeprom.c +++ b/cores/arduino/stm32/stm32_eeprom.c @@ -136,7 +136,7 @@ static inline uint32_t get_flash_end(void) { /** @addtogroup STM32F4xx_System_Private_Variables * @{ */ -static uint8_t tmpEE[E2END] = {0}; +static uint8_t eeprom_buffer[E2END] = {0}; /** * @} @@ -145,58 +145,72 @@ static uint8_t tmpEE[E2END] = {0}; /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes * @{ */ -void get_data_from_flash(void); -void set_data_to_flash(void); /** * @} */ /** - * @brief Function read a byte from eeprom - * @param __p : address to read + * @brief Function reads a byte from emulated eeprom (flash) + * @param pos : address to read * @retval byte : data read from eeprom */ -uint8_t eeprom_read_byte(const uint16_t __p) +uint8_t eeprom_read_byte(const uint16_t pos) { - uint8_t byte = 0; + eeprom_buffer_fill(); + return eeprom_buffered_read_byte(pos); +} - get_data_from_flash(); - byte = tmpEE[__p]; +/** + * @brief Function writes a byte to emulated eeprom (flash) + * @param pos : address to write + * @param value : value to write + * @retval none + */ +void eeprom_write_byte(uint16_t pos, uint8_t value) +{ + eeprom_buffered_write_byte(pos, value); + eeprom_buffer_flush(); +} - return byte; +/** + * @brief Function reads a byte from the eeprom buffer + * @param pos : address to read + * @retval byte : data read from eeprom + */ +uint8_t eeprom_buffered_read_byte(const uint16_t pos) +{ + return eeprom_buffer[pos]; } /** - * @brief Function write a byte to eeprom - * @param __p : address to write - * @param __value : value to write + * @brief Function writes a byte to the eeprom buffer + * @param pos : address to write + * @param value : value to write * @retval none */ -void eeprom_write_byte(uint16_t __p, uint8_t __value) +void eeprom_buffered_write_byte(uint16_t pos, uint8_t value) { - tmpEE[__p] = __value; - set_data_to_flash(); + eeprom_buffer[pos] = value; } /** - * @brief The function read into the flash. + * @brief This function copies the data from flash into the buffer * @param none * @retval none */ -void get_data_from_flash(void) +void eeprom_buffer_fill(void) { - memcpy(tmpEE, (uint8_t*)(FLASH_BASE_ADDRESS), E2END); + memcpy(eeprom_buffer, (uint8_t*)(FLASH_BASE_ADDRESS), E2END); } /** - * @brief The function write into the flash. + * @brief This function writes the buffer content into the flash * @param none * @retval none */ -void set_data_to_flash(void) +void eeprom_buffer_flush(void) { - //copy in flash FLASH_EraseInitTypeDef EraseInitStruct; uint32_t offset = 0; uint32_t address = FLASH_BASE_ADDRESS; @@ -240,12 +254,12 @@ void set_data_to_flash(void) if(HAL_FLASHEx_Erase(&EraseInitStruct, &pageError) == HAL_OK) { while(address < address_end) { #if defined(STM32L0xx) || defined(STM32L1xx) - memcpy(&data, tmpEE + offset, sizeof(uint32_t)); + memcpy(&data, eeprom_buffer + offset, sizeof(uint32_t)); if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data) == HAL_OK) { address += 4; offset += 4; #else - data = *((uint64_t*)(((uint8_t*)tmpEE + offset))); + data = *((uint64_t*)(((uint8_t*)eeprom_buffer + offset))); if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data) == HAL_OK) { address += 8; @@ -273,7 +287,7 @@ void set_data_to_flash(void) if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) == HAL_OK) { while(address < address_end) { - memcpy(&data, tmpEE + offset, sizeof(uint32_t)); + memcpy(&data, eeprom_buffer + offset, sizeof(uint32_t)); if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data) == HAL_OK) { address += 4; offset += 4; diff --git a/cores/arduino/stm32/stm32_eeprom.h b/cores/arduino/stm32/stm32_eeprom.h index 75b373fc4c..9670d85c9c 100644 --- a/cores/arduino/stm32/stm32_eeprom.h +++ b/cores/arduino/stm32/stm32_eeprom.h @@ -58,8 +58,13 @@ /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ -uint8_t eeprom_read_byte(const uint16_t __p); -void eeprom_write_byte(uint16_t __p, uint8_t __value); +uint8_t eeprom_read_byte(const uint16_t pos); +void eeprom_write_byte(uint16_t pos, uint8_t value); + +void eeprom_buffer_fill(); +void eeprom_buffer_flush(); +uint8_t eeprom_buffered_read_byte(const uint16_t pos); +void eeprom_buffered_write_byte(uint16_t pos, uint8_t value); #ifdef __cplusplus } From 7f15089767ad2f871f124926d2ed4409a00886ca Mon Sep 17 00:00:00 2001 From: Nils Hasenbanck Date: Sat, 15 Sep 2018 09:11:33 +0200 Subject: [PATCH 2/2] [EEPROM emulation] Clean up code Clean up also the old references to the original author/version/date since we already refactored this code quite well. The copyright notice of course is still intact. Signed-off-by: Nils Hasenbanck --- cores/arduino/stm32/stm32_eeprom.c | 107 +++++------------------------ cores/arduino/stm32/stm32_eeprom.h | 7 +- 2 files changed, 19 insertions(+), 95 deletions(-) diff --git a/cores/arduino/stm32/stm32_eeprom.c b/cores/arduino/stm32/stm32_eeprom.c index 4fc3725ff4..1cc8c55b06 100644 --- a/cores/arduino/stm32/stm32_eeprom.c +++ b/cores/arduino/stm32/stm32_eeprom.c @@ -1,11 +1,7 @@ /** ****************************************************************************** - * @file eeprom.c - * @author WI6LABS - * @version V1.0.0 - * @date 01-August-2016 - * @brief provide emulated eeprom from flash - * + * @file stm32_eeprom.c + * @brief Provides emulated eeprom from flash ****************************************************************************** * @attention * @@ -35,17 +31,7 @@ * ****************************************************************************** */ -/** @addtogroup CMSIS - * @{ - */ -/** @addtogroup stm32f4xx_system - * @{ - */ - -/** @addtogroup STM32F4xx_System_Private_Includes - * @{ - */ #include "stm32_eeprom.h" #include @@ -53,22 +39,8 @@ extern "C" { #endif -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Defines - * @{ - */ -// We use the last page of the flash to store data (to prevent code overwritten). +/* Use the last page of the flash to store data in order to prevent overwritting + program data */ #if defined (STM32F0xx) || defined (STM32F1xx) || defined(STM32L1xx) #if defined (FLASH_BANK2_END) #define FLASH_BASE_ADDRESS ((uint32_t)((FLASH_BANK2_END + 1) - FLASH_PAGE_SIZE)) @@ -76,7 +48,7 @@ #define FLASH_BASE_ADDRESS ((uint32_t)((FLASH_BANK1_END + 1) - FLASH_PAGE_SIZE)) #else #define FLASH_BASE_ADDRESS ((uint32_t)((FLASH_END + 1) - FLASH_PAGE_SIZE)) -#endif // FLASH_BANK2_END +#endif /* FLASH_BANK2_END */ #elif defined (STM32F2xx) || defined (STM32F4xx) || defined (STM32F7xx) #define FLASH_BASE_ADDRESS ((uint32_t)(FLASH_END + 1) - FLASH_PAGE_SIZE) #define FLASH_DATA_SECTOR ((uint32_t)(FLASH_SECTOR_TOTAL - 1)) @@ -116,47 +88,20 @@ static inline uint32_t get_flash_end(void) { #define FLASH_BANK_NUMBER FLASH_BANK_1 #else #define FLASH_BANK_NUMBER FLASH_BANK_2 -#endif // FLASH_BANK_2 -// Flash base address +#endif /* FLASH_BANK_2 */ +/* Flash base address */ #define FLASH_PAGE_NUMBER ((uint32_t)((FLASH_SIZE / FLASH_PAGE_SIZE) - 1)) #define FLASH_BASE_ADDRESS ((uint32_t)(FLASH_BASE + (FLASH_PAGE_NUMBER * FLASH_PAGE_SIZE))) #endif -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_Macros - * @{ - */ - -/** - * @} - */ -/** @addtogroup STM32F4xx_System_Private_Variables - * @{ - */ static uint8_t eeprom_buffer[E2END] = {0}; -/** - * @} - */ - -/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - /** * @brief Function reads a byte from emulated eeprom (flash) * @param pos : address to read * @retval byte : data read from eeprom */ -uint8_t eeprom_read_byte(const uint16_t pos) -{ +uint8_t eeprom_read_byte(const uint16_t pos) { eeprom_buffer_fill(); return eeprom_buffered_read_byte(pos); } @@ -167,8 +112,7 @@ uint8_t eeprom_read_byte(const uint16_t pos) * @param value : value to write * @retval none */ -void eeprom_write_byte(uint16_t pos, uint8_t value) -{ +void eeprom_write_byte(uint16_t pos, uint8_t value) { eeprom_buffered_write_byte(pos, value); eeprom_buffer_flush(); } @@ -178,8 +122,7 @@ void eeprom_write_byte(uint16_t pos, uint8_t value) * @param pos : address to read * @retval byte : data read from eeprom */ -uint8_t eeprom_buffered_read_byte(const uint16_t pos) -{ +uint8_t eeprom_buffered_read_byte(const uint16_t pos) { return eeprom_buffer[pos]; } @@ -189,8 +132,7 @@ uint8_t eeprom_buffered_read_byte(const uint16_t pos) * @param value : value to write * @retval none */ -void eeprom_buffered_write_byte(uint16_t pos, uint8_t value) -{ +void eeprom_buffered_write_byte(uint16_t pos, uint8_t value) { eeprom_buffer[pos] = value; } @@ -199,8 +141,7 @@ void eeprom_buffered_write_byte(uint16_t pos, uint8_t value) * @param none * @retval none */ -void eeprom_buffer_fill(void) -{ +void eeprom_buffer_fill(void) { memcpy(eeprom_buffer, (uint8_t*)(FLASH_BASE_ADDRESS), E2END); } @@ -209,8 +150,7 @@ void eeprom_buffer_fill(void) * @param none * @retval none */ -void eeprom_buffer_flush(void) -{ +void eeprom_buffer_flush(void) { FLASH_EraseInitTypeDef EraseInitStruct; uint32_t offset = 0; uint32_t address = FLASH_BASE_ADDRESS; @@ -220,12 +160,12 @@ void eeprom_buffer_flush(void) uint32_t pageError = 0; uint64_t data = 0; - // ERASING page + /* ERASING page */ EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; #ifdef STM32L4xx EraseInitStruct.Banks = FLASH_BANK_NUMBER; EraseInitStruct.Page = FLASH_PAGE_NUMBER; -#else // STM32F4xx +#else #ifdef STM32F1xx EraseInitStruct.Banks = FLASH_BANK_1; #endif @@ -276,7 +216,7 @@ void eeprom_buffer_flush(void) uint32_t SectorError = 0; uint32_t data = 0; - // ERASING page + /* ERASING page */ EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; EraseInitStruct.Sector = FLASH_DATA_SECTOR; @@ -284,8 +224,7 @@ void eeprom_buffer_flush(void) HAL_FLASH_Unlock(); - if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) == HAL_OK) - { + if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) == HAL_OK) { while(address < address_end) { memcpy(&data, eeprom_buffer + offset, sizeof(uint32_t)); if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data) == HAL_OK) { @@ -300,18 +239,6 @@ void eeprom_buffer_flush(void) #endif } - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ #ifdef __cplusplus } #endif diff --git a/cores/arduino/stm32/stm32_eeprom.h b/cores/arduino/stm32/stm32_eeprom.h index 9670d85c9c..fb52027978 100644 --- a/cores/arduino/stm32/stm32_eeprom.h +++ b/cores/arduino/stm32/stm32_eeprom.h @@ -1,9 +1,6 @@ /** ****************************************************************************** * @file stm32_eeprom.h - * @author WI6LABS - * @version V1.0.0 - * @date 01-August-2016 * @brief Header for eeprom module ****************************************************************************** * @attention @@ -50,8 +47,8 @@ /* Exported constants --------------------------------------------------------*/ #if defined (STM32F2xx) || defined (STM32F4xx) || defined (STM32F7xx) -//FLASH_SECTOR_SIZE -#define FLASH_PAGE_SIZE ((uint32_t)(16*1024)) //16kB page +/* FLASH_SECTOR_SIZE */ +#define FLASH_PAGE_SIZE ((uint32_t)(16*1024)) /* 16kB page */ #endif #define E2END FLASH_PAGE_SIZE