RTT笔记-fal

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354