美文网首页
RTT笔记-fal

RTT笔记-fal

作者: lissettecarlr | 来源:发表于2020-10-08 17:47 被阅读0次

    该笔记类别主要是在自己学习时做的一些记录,方便自己很久不用忘掉时进行快速回忆

    1 使用

    1.1 导入文件

    文件名 位置
    fal.c ./src/
    fal_flash.c ./src/
    fal_partition.c ./src/
    fal_rtt.c ./src/
    fal_flash_stm32l1_port.c(移植文件) ./samples/porting

    然后导入头文件地址

    目录
    ./samples/porting
    ./inc

    1.2 添加宏定义

    在rtconfig.h文件中添加宏定义

    // fal
    #define PKG_USING_FAL
    #define FAL_PART_HAS_TABLE_CFG
    

    1.3建立分区表

    根据在移植文件中定义的存储空间名字来分区,例如在fal_flash_stm32l1_port.c中定义了

    const struct fal_flash_dev stm32l_eeprom = { "stm32l_eeprom", 0, 2*1024, 2048, {NULL, read, write, erase} };
    

    则在fla_cfg.h中可用如下划分区域

    #define FAL_PART_TABLE                                                          \
    {                                                                               \
         {FAL_PART_MAGIC_WROD, "eeprom",    "stm32l_eeprom", 0, 1024+512, 0},        \
           {FAL_PART_MAGIC_WROD, "eeprom2",    "stm32l_eeprom", 1024+512,512 , 0},      \
    }
    

    注意的是头文件中必须使用宏(FAL_PART_HAS_TABLE_CFG),才会使用这里定义的分区方式

    1.3 例程

    • 添加头文件
    #include "fal.h"
    
    • 初始化fla组件
    fal_init();
    
    • 打印分区表
    fal_show_part_table();
    

    输出结果:


    image.png
    • 选择一个操作分区
    const struct fal_partition * bli = fal_partition_find("eeprom2") ;
    if (bli ==RT_NULL)
    {
        rt_kprintf("flash not find\n");
    }
    
    • 读写测试
     static uint8_t reg[3] ={0,0,0};
    static uint8_t data[3] ={1,2,3};
    fal_partition_read(bli,0,reg,3);
    rt_kprintf("##%d %d %d",reg[0],reg[1],reg[2]); 
    rt_thread_mdelay(1000);
    fal_partition_erase(bli,0,3);
    fal_partition_write(bli,0,data,3);
    fal_partition_read(bli,0,reg,3);
    rt_kprintf("##%d %d %d",reg[0],reg[1],reg[2]); 
    

    先读取3个寄存器,然后写入新数据1,2,3,再次读取显示出来。串口打印结果在第一次读取时输出为零,在擦除写入后读取出来便是数据1,2,3. 复位模块后第一次读取出的数据也为1,2,3. 表示掉电保存成功了。

    2 通用API

    2.1查找 Flash 设备

    失败返回NULL

    const struct fal_flash_dev *fal_flash_device_find(const char *name)
    

    2.2 查找 Flash 分区

    const struct fal_partition *fal_partition_find(const char *name)
    

    2.3 获取分区表

    led:分区表长度

    const struct fal_partition *fal_get_partition_table(size_t *len)
    

    2.4 临时设置分区表

    FAL 初始化时会自动装载默认分区表。使用该设置将临时修改分区表,重启后会 丢失 该设置

    void fal_set_partition_table_temp(struct fal_partition *table, size_t len)
    

    2.5 从分区读取数据

    返回实际读取大小

    int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size)
    

    2.6 往分区写入数据

    int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size)
    

    2.7 擦除分区数据

    int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size)
    

    2.8 擦除整个分区数据

    int fal_partition_erase_all(const struct fal_partition *part)
    

    2.9 打印分区表

    void fal_show_part_table(void)
    

    2.10 根据分区名称,创建对应的块设备

    该函数可以根据指定的分区名称,创建对应的块设备,以便于在指定的分区上挂载文件系统

    struct rt_device *fal_blk_device_create(const char *parition_name)
    
    参数 描述
    parition_name 分区名称
    return 创建成功,则返回对应的块设备,失败返回空

    2.11 根据分区名称,创建对应的 MTD Nor Flash 设备

    该函数可以根据指定的分区名称,创建对应的 MTD Nor Flash 设备,以便于在指定的分区上挂载文件系统

    struct rt_device *fal_mtd_nor_device_create(const char *parition_name)
    
    参数 描述
    parition_name 分区名称
    return 创建成功,则返回对应的 MTD Nor Flash 设备,失败返回空

    2.12 根据分区名称,创建对应的字符设备

    该函数可以根据指定的分区名称,创建对应的字符设备,以便于通过 deivice 接口或 devfs 接口操作分区,开启了 POSIX 后,还可以通过 oepn/read/write 函数操作分区

    struct rt_device *fal_char_device_create(const char *parition_name)
    
    参数 描述
    parition_name 分区名称
    return 创建成功,则返回对应的块设备,失败返回空

    3 MSH命令

    命令 说明
    fal 显示fal的相关命令
    fal probe 显示并用于指定分区
    fal read addr size 例如 fal read 0 64
    fal write addr data1 ... dataN 例如fal write 8 1 2 3 4 5
    fal erase addr size 例如 fal erase 0 4096
    fal bench <blk_size> 例如 fal bench 4096 yes

    4 移植

    使用一节中提到的samples\porting目下便是移植需要修改的文件,例如源码只提供了fal_flash_sfud_port.c和fal_flash_stm32f2_port.c两个文件,我想在芯片stm32L151上使用它的eeprom,则自己新建立一个文件,实现初始化、读、写、擦即可,最后在同目录下的fal_cfg.h中进行分区,就想下面这样

    #define FAL_PART_TABLE                                                          \
    {                                                                               \
         {FAL_PART_MAGIC_WROD, "eeprom",    "stm32l_eeprom", 0, 1024+512, 0},        \
         {FAL_PART_MAGIC_WROD, "eeprom2",    "stm32l_eeprom", 1024+512,512 , 0},      \
    }
    

    fal_flash_stm32l1_port.c

    #include <fal.h>
    #include "rtthread.h"
    
    #define EEPROM_BASE_ADDR    0x08080000 
    
    static int read(long offset, uint8_t *buf, size_t size)
    {
        uint8_t *wAddr;
          size_t i;
        wAddr=(uint8_t *)(EEPROM_BASE_ADDR+offset);  
           
          for (i = 0; i < size; i++, wAddr++, buf++)
          {
               *buf = *(uint8_t *) wAddr;
            }
                
    //    while(size--){  
    //        *buf++=*wAddr++;  
    //    }   
        return size;
    }
    
    
    static int write(long offset, const uint8_t *buf, size_t size)
    {
           size_t i;
           uint32_t read_data;
           uint32_t addr = EEPROM_BASE_ADDR + offset;
           HAL_FLASHEx_DATAEEPROM_Unlock();
    
           for (i = 0; i < size; i++, buf++, addr++)
           {
              // HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_BYTE,addr);
               HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE , addr, *buf);
               read_data = *(uint8_t *) addr;
              /* check data */
              if (read_data != *buf)
              {
                return -1;
              }
           }        
           HAL_FLASHEx_DATAEEPROM_Lock();   
           return size; 
    }
    
    static int erase(long offset, size_t size)
    {
        size_t i;
        uint32_t addr = EEPROM_BASE_ADDR + offset;
        HAL_FLASHEx_DATAEEPROM_Unlock();
        for(i=0;i<size;i++ , addr++)
        {
           HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_BYTE,addr);
        }
        HAL_FLASHEx_DATAEEPROM_Lock();  
    
        return size;
    }
    const struct fal_flash_dev stm32l_eeprom = { "stm32l_eeprom", 0, 2*1024, 2048, {NULL, read, write, erase} };
    
    

    同理无论任何存储,只需要实现对于接口后,上层使用便没有任何区别

    5 参考

    https://github.com/RT-Thread-packages/fal

    相关文章

      网友评论

          本文标题:RTT笔记-fal

          本文链接:https://www.haomeiwen.com/subject/oesgyqtx.html