Code Monkey home page Code Monkey logo

norfat's Introduction

norFAT

FAT style wear leveling NOR flash flat file system with posix like calls.

Goals

The goal of this project is a fail-safe, wear leveling file system built on NOR flash. However, the file system is not full featured nor thread safe. It is primarily intended to ease configuration management in higher level 32 bit embedded MCU's like the STM32 or PIC32 series. On file overwrites, the implementation attempts to preserve the old file until the newer file is closed, then atomically swap and delete.

Wear leveling

Because the primary goal is reliablity rather than perfect wear leveling, files are never moved. New files or rewritten files will always choose a randomly selected free sector. The tables are cycled through, so table size and crc count should roughly match the application.

Integration

Add your block IO routines etc.

/* Setup for 8MB NOR flash */
#define NORFAT_SECTORS 2048
#define NORFAT_SECTOR_SIZE 4096
#define NORFAT_TABLE_SECTORS 3 // Table size
#define NORFAT_TABLE_COUNT 6   // 3 fat table pairs carved from flash space

  /* Statically allocated buffers */
  uint8_t workingBuffer[NORFAT_SECTOR_SIZE * NORFAT_TABLE_SECTORS];
  uint8_t fatTableBuffer[NORFAT_SECTOR_SIZE * NORFAT_TABLE_SECTORS];
  norFAT_FS fs = {
    .addressStart = 0,
    .tableCount = NORFAT_TABLE_COUNT,
    .flashSectors = 1024,
    .sectorSize = NORFAT_SECTOR_SIZE, // Erase block size
    .programSize = 256,               // Program page size
    .erase_block_sector = erase_block_sector,
    .program_block_page = program_block_page,
    .read_block_device = read_block_device,
    .buff = workingBuffer,
    .fat = fatTableBuffer
  };
  int res = norfat_mount(&fs);

Details

Dynamic allocation is not used after from V1.04 on.

Each FAT table is ordered as follows:

typedef union {
  struct {
    uint32_t next : 28;
    uint32_t active : 1;
    uint32_t sof : 1;
    uint32_t available : 1;
    uint32_t write : 1;
  };
  uint32_t base;
} _sector;

typedef struct {
  _commit commit[NORFAT_CRC_COUNT];
  /* Number of times _Fat tables have been swapped. */
  uint32_t swapCount;
  /* Number of times garbage collected, never more than swapCount */
  uint32_t garbageCount;
  union {
    struct {
      uint32_t future : 32;
    };
    uint32_t flags;
  };
  /* Undefined length, fills remaining table length */
  _sector sector[]; 
} _FAT; /* must equal a multiple of sector size */

There are two copies of this in NOR at any time, with each one saved atomically on commit. _sector is used in such a way that only 1's are turned to 0's until garbage collection happens.
After each commit, the old crc is 0'd, and a new entry calculated based on its new offset, then entered using ascii to denote the new commit. Once either we are out of commit entries, or garbage needs to be collected, then we refresh and copy new entries to the next two locations while deleting old.

NORFAT_CRC_COUNT should be chosen to match typical use. For example, a choice of 256 will cost 2048 sector bytes, but give up to 256 file commits that happen on fclose. So this could be matched with tableSectors to roughly match rotation on the file sectors. swapCount tracks the number of times the fat sector is swapped to the next in line. garbageCount tracks the number of collections that have happened. Essentially swapCount is the number of erases / tableCount that have happened to the tables.

Tables are managed in groups of two, grouped as 2x2 when mounting, thus cycling through the possible sequences and managing each one as needed. All possible options should be listed here, although the inverse options may not be, for example 0x3022 is essentially the same as 0x2230 for a 4 table system.

Commit sequences
[00] 0x0022 |GOOD |GOOD |EMPTY|EMPTY|
[01] 0x3022 | BAD |GOOD |EMPTY|EMPTY|  Partial erase #1
[02] 0x2022 |EMPTY|GOOD |EMPTY|EMPTY|  Full erase #1
[03] 0x3022 | BAD |GOOD |EMPTY|EMPTY|  Partial write #1
[04] 0x0122 |GOOD | OLD |EMPTY|EMPTY|  Halfway through
[05] 0x0322 |GOOD | BAD |EMPTY|EMPTY|  Partial erase #2
[06] 0x0222 |GOOD |EMPTY|EMPTY|EMPTY|  Full erase #2
[07] 0x0322 |GOOD | BAD |EMPTY|EMPTY|  Partial write #2
[00] 0x0022 |GOOD |GOOD |EMPTY|EMPTY|  Completed  

Table Swapping sequences
[00] 0x0022 |GOOD |GOOD |EMPTY|EMPTY|
[01] 0x3022 | BAD |GOOD |EMPTY|EMPTY|  Partial Erase #1 old block
[02] 0x2022 |EMPTY|GOOD |EMPTY|EMPTY|  Full Erase #1 old block
[03] 0x2032 |EMPTY|GOOD | BAD |EMPTY|  Partial program #1 new block
[04] 0x2002 |EMPTY|GOOD |GOOD |EMPTY|  Full program #1 new block
[05] 0x2302 |EMPTY| BAD |GOOD |EMPTY|  Partial Erase #2 old block
[06] 0x2202 |EMPTY|EMPTY|GOOD |EMPTY|  Full Erase #2 old block
[07] 0x2203 |EMPTY|EMPTY|GOOD | BAD |  Partial program #1 new block
[00] 0x2200 |EMPTY|EMPTY|GOOD |GOOD |  Full program #1 new block

Options

/* CRC table count, this is the number of commits before garbage
 * is collected and tables are swapped to next pair
 */
NORFAT_CRC_COUNT 255

/* max file name length.  Changing this length will break the file system */
NORFAT_MAX_FILENAME 64

/* define for file CRC checking on fread eof */
NORFAT_FILE_CHECK

/* define for sequence coverage test */
NORFAT_COVERAGE_TEST

/* Print details, sprintf whatever */
NORFAT_DEBUG(x) // printf x
NORFAT_ERROR(x) // printf x
NORFAT_INFO_PRINT(x) printf x 

/* Random number generator, used for wear leveling */
NORFAT_RAND

/* uint32_t crc32(void *buf, int len, uint32_t Seed) */
NORFAT_CRC crc32 /* Or user supplied crc routine */

norfat's People

Contributors

friesendrywall avatar

Stargazers

Eason Wang avatar Arti Zirk avatar André van Schoubroeck avatar

Forkers

liming2013

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.