Project logo

SimpleFS

Simple (sensor) File system.


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

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 values
    • file_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

Copyright 2022 Juraj Ďuďák

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributors 2

Juraj Ďuďák 94.44%

Dávid Jánosfalvi 5.56%


Links

Languages

  • C 99.6%
  • CMake 0.4%

  • Library
    Last update

    2022-05-10 14:58:32

    Created at

    18.06.2021