simple FS
simple File System for embedded devices. Support fast append to file
operation. The type of FS is RA (Read-Append). It is optimized for FLASH-like types of memories, where write/erase operation is much time consuming that reading.
Suppored platforms:
- STM32
- ESP32 (in future)
- native C app (simulation mode)
Supported memories:
- SPI-like: FLASH memory. Winbond W32 compatible with high capacity (1-128Mbit)
- 1-wire: EEPROM memory. E.g. Maxim integrated DS28EC20 with maximum 20kB of capacity
Basic properies
- Access: Read/Append
- Write only to last file; read from any file.
- Maximum number of files: limited by memory size only.
- Filename is automaticaly generated based in memory ID
- File format: CSV like, but in binary representation
- Maximum columns in one file: configurable value
- Length of single value: variable length, from 1B to 128B
- Each file must has defined internal structure:
- number of column in file
- specification of each column type
Determination of use
- Storing data from sensors or datasources. Supported modules:
- Thermometer DS8B20
- RTC clock for precise time
- Internal Analog/Digital converter of used MCU
- Storing primitive datatypes (size 1-128B)
- Integers
- String
- Fixed point floating number
Basic configuration
In application, create a copy of default coniguration file:
- copy file
simpleefs_conig.h.default
to your application and rememe it to:simpleefs_conig.h
- in
simpleefs_conig.h
, set the correct parameters.
Preddefined memory variants:
variant | description | Max. files | Max. columns | overheads [B] |
---|---|---|---|---|
U | Ultra small | 1 | 4 | 112 |
X | eXtra small | 2 | 8 | 288 |
S | Small | 8 | 16 | 1824 |
L | Large | 22 | 42 | 11824 |
Example
Simulation mode (without MCU)
#include <stdio.h>
#include "sensor_FS.h"
typedef struct file_sensors{
SensorInterface_t *interfaces[10];
int count;
}FileSensors_t;
void fill_file(FileSensors_t data, int count_records){
SimpleFS_t *fs;
uint8_t sensor_index = 0;
file_add_sensor(sensor_index++, 0, data.interfaces[0]);
file_add_sensor(sensor_index++, 0, data.interfaces[1]);
file_add_sensor(sensor_index++, 0, data.interfaces[2]);
FS_state fst;
for (uint8_t i = 0; i < data.interfaces[3]->getSensorCount(); i++) {
fst = file_add_sensor(sensor_index++, i, data.interfaces[3]);
if (fst == STATE_ERR) {
printf("ERR: sensor not inserted in FS");
}
}
FS_commit_file_header();
fs = FS_open_last_file();
SensorInterface_t *sd;
SensorValue_t *sv;
if (fs) {
for (int k = 0; k < count_records; k++) {
file_data_row_begin(fs);
for (uint8_t p = 0; p < file_get_num_parts(fs); p++) {
RecordDescriptor_t ffd = file_column_format(fs, p);
sd = FS_sensor_driver(ffd.sensor_type);
if (sd != NULL) {
sv = sd->getValue();
int len = get_sensor_data_length(fs->file.format[p].value_format.meta_length);
file_store_data(fs, p, sv);
}
}
file_data_row_commit(fs);
}
}
}
int main(){
SensorInterface_t *driverOW = &owBus;
SensorInterface_t *driverADC = &adcSensor;
SensorInterface_t *driverTime = &timeSensor;
SensorInterface_t *driverData = &dataSensor;
driverOW->Init(NULL, 2);
driverADC->Init(NULL, DUMMY_VALUE);
driverTime->Init(NULL, FORMAT_META_FMT_SPECIAL_TIME);
Data_HandleTypeDef dataConfig;
dataConfig.data_type = SENSOR_TYPE_INTEGER;
dataConfig.data_format.meta_length = FORMAT_META_LENGTH_2B;
dataConfig.data_format.meta_format = FORMAT_META_FMT_UINT;
dataConfig.data_format.Q.m = Q_FORMAT_NONE;
dataConfig.data_format.Q.n = Q_FORMAT_NONE;
driverData->Init(&dataConfig, DUMMY_VALUE);
FS_init(NULL, NULL, 0);
FS_write_preamble();
FileSensors_t data;
data.interfaces[0] = driverTime;
data.interfaces[1] = driverADC;
data.interfaces[2] = driverData;
data.interfaces[3] = driverOW;
// 1st file
FS_create_file();
driverOW->Init(NULL, 1); // OW with 1 sensors
fill_file(data, 64);
// 2nd file
FS_create_file();
driverOW->Init(NULL, 2); // OW with 2 sensors
fill_file(data, 6);
file_dump_memory();
return 0;
High level API
- File system related functions
FS_init()
- Init the sensorFS filesystem.FS_create_file()
- Begin file creation procedure. No write to FLASH is perform.FS_open_file()
- Try open to file with given ID.FS_open_last_file()
- Open last file on sensorFS.FS_write_preamble()
- Write preamble aprt in sensorFS, if not exists.FS_num_files()
- Return number of files.FS_detect_num_files()
- Read number of files.FS_commit_file_header()
- Finish write information about created file.FS_is_empty()
- Check, that sensorFS/FLASH is empty.FS_sensor_driver()
- Return driver for attached sensor.
-
File related functions
file_add_sensor()
- Add new sensor to created file.file_get_num_parts()
- Return number parts of opened file.file_data_row_begin()
- Initialize internal data structures for new data record.file_store_data()
- Prepare measured value to file buffer.file_data_row_commit()
- Write prepared measured valuesfile_record_length()
- Return length of record.file_column_format()
- Return format of i-th sensor in datafile.file_size()
- Return file size in Bytes.file_data_prepare()
- Start value measure on all sensors.
Author
Juraj Ďuďák - https://gitlab.nsoric.com/juraj