Tiny storage(file) system on MCU internal flash memory for Nucleo F4xx. The purpose of SOFBlock class is to provide a way to write data on flash memory in the same way of file handling class in the file system.
Dependents: storage_on_flash_demo mbed_controller_demo mbed-os-example-blinky-2
March 26, 2015
Seeed Arch Max platform which is based on STM32-F407 is supported.
Diff: SOFBlock.h
- Revision:
- 0:7f4bc855cb46
- Child:
- 1:33afe074c8f8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SOFBlock.h Mon Jan 19 12:57:44 2015 +0000 @@ -0,0 +1,163 @@ +/** +* @file SOFBlock.h +* +* @author hillkim7@gmail.com +* @brief Simple storage implementation on internal MCU flash memory. + +The SOF in SOFBlock is abbreviation of "Storage On Flash". +The purpose of SOFBlock class is to provide a way to write data on flash memory +in the same way of file handling class in the file system. +It manages a chunk of data on the Flash memory efficiently by minimizing flash erase operation as little as possible. +Note: Currently I only support STM32F4xx series platforms. + +The STM32 F4xx series from ST have plenty of internal Flash memory inside MCU core. +For example STM32 401RE has 512Kbyts Flash. +Typical size of firmware file is less than 256KB, so remaining area is free to use. +The simplest way of flash utilization as data storage is to use a chunk of Flash area as an unit of storage. +A block of Flash is called sector in STM32 domain. It requires to erase a sector before update bits in Flash. + +Conceptually it is quite simple. +Here is write operation: +1) Erase sector #n +2) Write data to sector #n +Read operation: +1) Just read physical memory address of sector #n +The base address of STM32 Flash is 0x00000000. + +There may be inefficiency in this Flash usage scenario when size of data is too small compared with sector size. +The size of sectors from #5 to #7 of STM32 401RE Flash 128KB. If I only need to maintain 1KB data, +whenever I need to update data I need to erase whole 128KB of sector. +This produces two problems. +One is time consumption of erase operation. The operation of ERASE128KB takes 1~4 seconds long. +The other is lifetime of Flash memory. More you erase and write and lifetime of Flash is shorter. + +To overcome such problem, here simple flash management algorithm is used for. +By tracking data offset and size it can hold multiple data in a sector. Bear in mind that is impossible rewriting data on Flash. +Keeping tracking data along with data itself is crucial. +Data itself is growing from low address. On the other hand tracking data is growing down from high address. +Let's assume the size of data is 1KB and store it in sector #6 which address range is from 0x08040000 to 0x0805ffff. ++-------------+----------------------------------------------------------------------+-----+ +<data> <tracking data> ++-------------+----------------------------------------------------------------------+-----+ +data grows -> <- tracking data grows +Writing data will be placed at the end of data always and reading data will pick the last data. +It is like simple file system that only keep a file only. +*/ + +#pragma once + +#include "SOF_dev.h" + +/** SOF(Storage On Flash) usage example + * + * Example: + * @code +#include "mbed.h" +#include "SOFBlock.h" + +int main() +{ + const uint8_t sector_index = 7; + SOFBlock::format(sector_index); // Erase flash sector 7 and make structure for storage. + + SOFWriter writer; + SOFReader reader; + + writer.open(sector_index) ; + writer.write_data((uint8_t*)"First Data", 10); + writer.close(); + + reader.open(sector_index); + printf("data %d bytes at %p :\r\n", reader.get_data_size(), reader.get_physical_base_addr()); + printf("%.*s\r\n", reader.get_data_size(), reader.get_physical_base_addr()); + // "First Data" printed + reader.close(); + + writer.open(sector_index) ; + // Overwrite previous data without erasing flash. + writer.write_data((uint8_t*)"Second Data", 11); + writer.close(); + + reader.open(sector_index); + printf("data %d bytes at %p :\r\n", reader.get_data_size(), reader.get_physical_base_addr()); + printf("%.*s\r\n", reader.get_data_size(), reader.get_physical_base_addr()); + // "Second Data" printed + reader.close(); +} + +*/ + +/** +* Base class of SOF(Storage On Flash) +*/ +class SOFBlock +{ +public: + SOFBlock(); + + virtual ~SOFBlock(); + + void close(); + +public: + bool is_open() const { return hblock_ != NULL; } + +public: + /*** erase flash sector and put signature to setup struct */ + static bool format(uint8_t sector_index); + +protected: + SOF_BlockHandle_t hblock_; +}; + + +/** +* It provides interface for writing data to flash memory. +*/ +class SOFWriter : public SOFBlock +{ +public: + SOFWriter(); + virtual ~SOFWriter(); + + /*** Open for writing mode */ + SOF_Error_t open(uint8_t sector_index); + + /*** Return max available for writing */ + size_t get_free_size(); + + /*** Write one byte of data */ + bool write_byte_data(uint8_t c); + + /*** Write n bytes of data */ + size_t write_data(const uint8_t *p, size_t p_size); +}; + + +/** +* It provides interface for reading data from flash memory. +* It can read data directly by accessing physical flash address or +* calling function like traditional file API style. +*/ +class SOFReader : public SOFBlock +{ +public: + SOFReader(); + virtual ~SOFReader(); + + /*** Open for read mode */ + SOF_Error_t open(uint8_t sector_index); + + /*** Return flash physical address of data for direct access */ + uint8_t *get_physical_base_addr(); + + /*** Return data size */ + size_t get_data_size(); + + /*** Return one byte of data */ + bool read_byte_data(uint8_t *c); + + /*** Return n bytes of data */ + size_t read_data( uint8_t *p, size_t p_size); +}; +