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.

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);
+};
+