littlefs系列:重要的数据结构

1、文件类型

// File types
enum lfs_type {
    // file types
    LFS_TYPE_REG            = 0x001,
    LFS_TYPE_DIR            = 0x002,

    // internally used types
    LFS_TYPE_SPLICE         = 0x400,
    LFS_TYPE_NAME           = 0x000,
    LFS_TYPE_STRUCT         = 0x200,
    LFS_TYPE_USERATTR       = 0x300,
    LFS_TYPE_FROM           = 0x100,
    LFS_TYPE_TAIL           = 0x600,
    LFS_TYPE_GLOBALS        = 0x700,
    LFS_TYPE_CRC            = 0x500,

    // internally used type specializations
    LFS_TYPE_CREATE         = 0x401,
    LFS_TYPE_DELETE         = 0x4ff,
    LFS_TYPE_SUPERBLOCK     = 0x0ff,
    LFS_TYPE_DIRSTRUCT      = 0x200,
    LFS_TYPE_CTZSTRUCT      = 0x202,
    LFS_TYPE_INLINESTRUCT   = 0x201,
    LFS_TYPE_SOFTTAIL       = 0x600,
    LFS_TYPE_HARDTAIL       = 0x601,
    LFS_TYPE_MOVESTATE      = 0x7ff,

    // internal chip sources
    LFS_FROM_NOOP           = 0x000,
    LFS_FROM_MOVE           = 0x101,
    LFS_FROM_USERATTRS      = 0x102,
};

2、文件打开时的标志

// File open flags
enum lfs_open_flags {
    // open flags
    LFS_O_RDONLY = 1,         // Open a file as read only
    LFS_O_WRONLY = 2,         // Open a file as write only
    LFS_O_RDWR   = 3,         // Open a file as read and write
    LFS_O_CREAT  = 0x0100,    // Create a file if it does not exist
    LFS_O_EXCL   = 0x0200,    // Fail if a file already exists
    LFS_O_TRUNC  = 0x0400,    // Truncate the existing file to zero size
    LFS_O_APPEND = 0x0800,    // Move to end of file on every write

    // internally used flags
    LFS_F_DIRTY   = 0x010000, // File does not match storage
    LFS_F_WRITING = 0x020000, // File has been written since last flush
    LFS_F_READING = 0x040000, // File has been read since last flush
    LFS_F_ERRED   = 0x080000, // An error occured during write
    LFS_F_INLINE  = 0x100000, // Currently inlined in directory entry
    LFS_F_OPENED  = 0x200000, // File has been opened
};

3、文件seek时的标志

// File seek flags
enum lfs_whence_flags {
    LFS_SEEK_SET = 0,   // Seek relative to an absolute position
    LFS_SEEK_CUR = 1,   // Seek relative to the current file position
    LFS_SEEK_END = 2,   // Seek relative to the end of the file
};

4、lfs的配置参数

// Configuration provided during initialization of the littlefs
struct lfs_config {
    // Opaque user provided context that can be used to pass
    // information to the block device operations
    /* 这个参数主要是传递给block驱动代码 */
    void *context;

    /* 从设备读数据 */
    int (*read)(const struct lfs_config *c, lfs_block_t block,
            lfs_off_t off, void *buffer, lfs_size_t size);

    /* 向设备写入数据,block设备在写入前必须已经erase了 */
    int (*prog)(const struct lfs_config *c, lfs_block_t block,
            lfs_off_t off, const void *buffer, lfs_size_t size);

    /* 擦除block */
    int (*erase)(const struct lfs_config *c, lfs_block_t block);

    /* sync块设备的状态 */
    int (*sync)(const struct lfs_config *c);

    /* 最小的读取单元大小 */
    lfs_size_t read_size;

    /* 最小的写入数据单元大小,也是数据metadata pair中tag的对齐尺寸 */
    lfs_size_t prog_size;

    /* 最小的擦除单元大小。可以比flash的实际block尺寸大。但是对于ctz类型的文件,block size是最小的分配单元。同时block size必须是
    read size和program size的倍数,block size会存储在superblock中 */
    lfs_size_t block_size;

    /* 属于文件系统的block数量,block count会存储在superblock中 */
    lfs_size_t block_count;

    /* 文件系统进行垃圾回收时的block的擦除次数,推荐取值100-1000.值越大垃圾回收的次数越少,性能越好 */
    int32_t block_cycles;

    /* littlefs需要一个read cache,一个program cache,每个文件也需要一个cache。cache越大性能越好,会减少会flash的访问次数,
    cache必须是block的read size和program size的倍数,同时是block size的因数 */
    lfs_size_t cache_size;

    /* lookahead buffer的尺寸。lookahead buffer主要是block alloctor在分配块的时候用到。lookahead size必须是8的倍数,
    因为它是采用bitmap的形式存储的 */
    lfs_size_t lookahead_size;

    /* cache size大小的read buffer,可以静态分配也可以动态分配 */
    void *read_buffer;

    /* cache size大小的program buffer,可以静态分配也可以动态分配 */
    void *prog_buffer;

    /* lookahead_size大小的lookahead buffer,且是32-bit对齐的,即可以静态分配也可以动态分配 */
    void *lookahead_buffer;

    /* 文件名的最大长度,这个值会存储在superblock中 */
    lfs_size_t name_max;

    /* 文件的最大长度,存储在superblock中 */
    lfs_size_t file_max;

    /* 用户属性的最大长度 */
    lfs_size_t attr_max;
};

5、文件信息

// File info structure
struct lfs_info {
    // Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR 普通文件或者目录
    uint8_t type;

    // Size of the file, only valid for REG files. Limited to 32-bits. 对于普通文件才有意义
    lfs_size_t size;

    // Name of the file stored as a null-terminated string. Limited to
    // LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to
    // reduce RAM. LFS_NAME_MAX is stored in superblock and must be
    // respected by other littlefs drivers.
    /* 字符串形式的文件名 */
    char name[LFS_NAME_MAX+1];
};

6、用户属性

struct lfs_attr {
    /* 属性类型 */
    uint8_t type;

    /* 存储属性的buffer */
    void *buffer;

    /* 属性的长度,最大值为LFS_ATTR_MAX */ 
    lfs_size_t size;
};

7、文件open时的配置

struct lfs_file_config {
    /* cache size长度的buffer,可以静态分配也可以动态分配 */
    void *buffer;

    /* 用户属性,读文件时,attr存储从flash上读取的文件用户属性,写入文件时,attr存放用户指定的文件属性并会写入到flash中 */
    struct lfs_attr *attrs;

    /* 用户属性的长度 */
    lfs_size_t attr_count;
};

8、lfs_cache结构

typedef struct lfs_cache {
    lfs_block_t block;    // cache中的数据属于的block
    lfs_off_t off;        // cache中的数据在block上的偏移地址
    lfs_size_t size;      // cache的大小
    uint8_t *buffer;      // cache数据的存放地址
} lfs_cache_t;

9、lfs_mdir结构,代表metadata pair,dir本身所在的block

typedef struct lfs_mdir {
    lfs_block_t pair[2];    // dir的metadata pair所在的block
    uint32_t rev;           // metadata pair的revision
    lfs_off_t off;          // tag的偏移地址
    uint32_t etag;          
    uint16_t count;
    bool erased;
    bool split;             // metadata pair是否是链表
    lfs_block_t tail[2];    // 用于metadata pair链表
} lfs_mdir_t;

10、lfs目录结构

// littlefs directory type
typedef struct lfs_dir {
    struct lfs_dir *next;    // 指向子目录
    uint16_t id;
    uint8_t type;            // LFS_TYPE_DIR
    lfs_mdir_t m;            // 代表dir的metadata pair
    lfs_off_t pos;           // 在目录中的当前位置,主要用在seek,tell和rewind操作中
    lfs_block_t head[2];
} lfs_dir_t;

11、lfs文件类型

// littlefs file type
typedef struct lfs_file {
    struct lfs_file *next;
    uint16_t id;     // metadata tag中的id,在文件open时获取
    uint8_t type;    // LFS_TYPE_REG 或者 LFS_TYPE_DIR
    lfs_mdir_t m;    // 文件所在的目录的metadata pair

    struct lfs_ctz {
        lfs_block_t head;
        lfs_size_t size;
    } ctz;    // 指向大文件的CTZ skip-list。对于小文件则直接inline了,无需CTZ skip-list

    uint32_t flags;      // lfs_open_flags中的值
    lfs_off_t pos;       // 文件访问时的偏移
    lfs_block_t block;   // file当前的block
    lfs_off_t off;       // 在block内的offset
    lfs_cache_t cache;    // 文件访问时的cache

    const struct lfs_file_config *cfg;    // 文件open时的配置参数,包含一个buffer以及用户属性
} lfs_file_t;

12、lfs superblock结构

typedef struct lfs_superblock {
    uint32_t version;        // 文件系统的版本号
    lfs_size_t block_size;   // 文件系统的block size,和flash的block size不一定相同
    lfs_size_t block_count;  // 文件系统包含的block数量,每个block的大小等于上面的block size
    lfs_size_t name_max;     // 文件名的最大长度
    lfs_size_t file_max;     // 文件的最大长度
    lfs_size_t attr_max;     // 用户属性的最大长度
} lfs_superblock_t;

13、lfs文件系统类型结构

// The littlefs filesystem type
typedef struct lfs {
    lfs_cache_t rcache;             // read cache
    lfs_cache_t pcache;             // program cache
    lfs_block_t root[2];            // 根目录所在的block
    struct lfs_mlist {
        struct lfs_mlist *next;      // 指向下一个节点
        uint16_t id;                 // metadata pair的id
        uint8_t type;                // metadata pair的类型
        lfs_mdir_t m;               // metadata pair
    } *mlist;                       // metadata pair list
    uint32_t seed;                  // block alloctor的随机数生成的seed

    struct lfs_gstate {
        uint32_t tag;
        lfs_block_t pair[2];
    } gstate, gpending, gdelta;      // 用于目录操作sync的global state,

    struct lfs_free {
        lfs_block_t off;             // 记录lookahead buffer中起始block的偏移
        lfs_block_t size;            // lookahead buffer中block的数量,注意lookahead采用的是bitmap的形式,因此size=8*lookahead_size 
        lfs_block_t i;               // lookahead buffer内部的偏移地址
        lfs_block_t ack;             // 剩余block的数量,初始值为block count,如果该值为0,表示已经没有free block了
        uint32_t *buffer;            // buffer的长度为lookahead size
    } free;                          // lookahead buffer,用于分配free block

    const struct lfs_config *cfg;    // 文件系统的配置参数
    lfs_size_t name_max;             // 文件名的最大长度,和superblock中的name_max值相同
    lfs_size_t file_max;             // 文件的最大长度,和superblock中的file_max值相同
    lfs_size_t attr_max;             // 用户属性的最大长度,和superblock中的attr_max值相同
} lfs_t;

 

 

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值