Stores data on the flash memory of stm32f4xx
Dependents: DISCO-F429ZI_LCDTS_demo_richard
Fork of storage_on_flash by
SOFBlock.h
00001 /** 00002 * @file SOFBlock.h 00003 * 00004 * @author hillkim7@gmail.com 00005 * @brief Simple storage implementation on internal MCU flash memory. 00006 * 00007 * The SOF in SOFBlock is abbreviation of "Storage On Flash". 00008 * The purpose of SOFBlock class is to provide a way to write data on flash memory 00009 * in the same way of file handling class in the file system. 00010 * It manages a chunk of data on the Flash memory efficiently by minimizing flash erase operation as little as possible. 00011 * Note: Currently it only supports STM32F4xx series platforms. 00012 * - NUCLEO-F401RE, NUCLEO-F411RE, Seeed Arch Max 00013 * The STM32 F4xx series from ST have plenty of internal Flash memory inside MCU core. 00014 * For example STM32 401RE has 512Kbyts Flash. 00015 * Typical size of firmware file is less than 256KB, so remaining area is free to use. 00016 * The simplest way of flash utilization as data storage is to use a chunk of Flash area as an unit of storage. 00017 * A block of flash is called sector in STM32F4xx domain. It requires to erase a sector before update bits in flash. 00018 * 00019 * Conceptually it is quite simple. 00020 * Here is typical write operation: 00021 * 1) Erase sector #n 00022 * 2) Write data to sector #n 00023 * Read operation: 00024 * 1) Just read physical memory address of sector #n 00025 * The base physical address of STM32 flash is 0x08000000. 00026 * 00027 * There may be inefficiency in this flash usage scenario when size of data is too small compared with sector size. 00028 * The size of sectors from #5 to #7 of STM32-F4xx Flash is 128KB. For example, if I only need to maintain 1KB data, 00029 * whenever I need to update data I need to erase whole 128KB of sector. 00030 * This produces two problems. 00031 * One is time consumption of the erase operation. The operation of ERASE128KB takes 1~4 seconds long. 00032 * The other is related to lifetime of Flash memory. 00033 * More you erase and write and lifetime of flash is shorter. 00034 * 00035 * To overcome such problems, here simple flash management algorithm is used for. 00036 * By tracking data offset and size it can hold multiple data in a sector. 00037 * Bear in mind that is impossible rewriting data on Flash. 00038 * Keeping tracking data along with data itself without frequent erase operation is crucial. 00039 * To do this, data itself is growing from low address. 00040 * On the other hand tracking data is growing down from high address. 00041 * Let's assume the size of data is 1KB and store it in sector #6 which address range is from 0x08040000 to 0x0805ffff. 00042 * +-------------+----------------------------------------------------------------------+-----+ 00043 * <data> <tracking data> 00044 * +-------------+----------------------------------------------------------------------+-----+ 00045 * data grows -> <- tracking data grows 00046 * Writing data will be placed at the end of data always and reading data will pick the last data. 00047 * It is like simple file system that only keep a file only. 00048 * 00049 * Unlike file manipulation operation, there is caution you need to check if write operation fails 00050 * or need to check free size before you start to write data. 00051 * It is required to format flash sector when there is no more free space. 00052 */ 00053 00054 #pragma once 00055 00056 #include "SOF_dev.h" 00057 00058 /** SOF(Storage On Flash) usage example 00059 * 00060 * Example: 00061 * @code 00062 * #include "mbed.h" 00063 * #include "SOFBlock.h" 00064 * 00065 * int main() 00066 * { 00067 * const uint8_t sector_index = 7; 00068 * SOFBlock::format(sector_index); // Erase flash sector 7 and make structure for storage. 00069 * 00070 * SOFWriter writer; 00071 * SOFReader reader; 00072 * 00073 * writer.open(sector_index); 00074 * writer.write_data((uint8_t*)"First Data", 10); 00075 * writer.close(); 00076 * 00077 * reader.open(sector_index); 00078 * printf("data %d bytes at %p :\r\n", reader.get_data_size(), reader.get_physical_base_addr()); 00079 * printf("%.*s\r\n", reader.get_data_size(), reader.get_physical_base_addr()); 00080 * // "First Data" printed 00081 * reader.close(); 00082 * 00083 * SOF_Statics_t statics; 00084 * if (!SOFBlock(sector_index, statics) || statics.free_size < 11) { // check available byte 00085 * SOFBlock::format(sector_index); 00086 * } 00087 * writer.open(sector_index); 00088 * // Overwrite previous data without erasing flash. 00089 * writer.write_data((uint8_t*)"Second Data", 11); 00090 * writer.close(); 00091 * 00092 * reader.open(sector_index); 00093 * printf("data %d bytes at %p :\r\n", reader.get_data_size(), reader.get_physical_base_addr()); 00094 * printf("%.*s\r\n", reader.get_data_size(), reader.get_physical_base_addr()); 00095 * // "Second Data" printed 00096 * reader.close(); 00097 * } 00098 */ 00099 00100 /** 00101 * Base class of SOF(Storage On Flash) 00102 */ 00103 class SOFBlock 00104 { 00105 public: 00106 SOFBlock(); 00107 00108 virtual ~SOFBlock(); 00109 00110 void close(); 00111 00112 public: 00113 /*** Returns whether instance of SOFBlock is currently associated to flash storage. */ 00114 bool is_open() const { 00115 return hblock_ != NULL; 00116 } 00117 00118 public: 00119 /*** Erase flash sector and put signature to setup file system struct */ 00120 static bool format(uint8_t sector_index); 00121 00122 /*** Get statistics of storage */ 00123 static bool get_stat(uint8_t sector_index, SOF_Statics_t &statics); 00124 00125 protected: 00126 SOF_BlockHandle_t hblock_; 00127 }; 00128 00129 00130 /** 00131 * It provides interface for writing data to flash memory. 00132 */ 00133 class SOFWriter : public SOFBlock 00134 { 00135 public: 00136 SOFWriter(); 00137 virtual ~SOFWriter(); 00138 00139 /*** Open for writing mode */ 00140 SOF_Error_t open(uint8_t sector_index); 00141 00142 /*** Return max available for writing */ 00143 size_t get_free_size(); 00144 00145 /*** Write one byte of data. 00146 * Note: in case of storage full, it can't write data any more. 00147 * It is required to format sector and write it again. 00148 */ 00149 bool write_byte_data(uint8_t c); 00150 00151 /*** Write n bytes of data */ 00152 size_t write_data(const uint8_t *p, size_t p_size); 00153 }; 00154 00155 00156 /** 00157 * It provides interface for reading data from flash memory. 00158 * It can read data directly by accessing physical flash address or 00159 * calling function like traditional file API style. 00160 */ 00161 class SOFReader : public SOFBlock 00162 { 00163 public: 00164 SOFReader(); 00165 virtual ~SOFReader(); 00166 00167 /*** Open for read mode */ 00168 SOF_Error_t open(uint8_t sector_index); 00169 00170 /*** Return flash physical address of data for direct access */ 00171 uint8_t *get_physical_data_addr(); 00172 00173 /*** Return data size */ 00174 size_t get_data_size(); 00175 00176 /*** Return one byte of data */ 00177 bool read_byte_data(uint8_t *c); 00178 00179 /*** Return n bytes of data */ 00180 size_t read_data( uint8_t *p, size_t p_size); 00181 }; 00182 00183 00184
Generated on Wed Jul 13 2022 22:53:56 by 1.7.2