在 V4.1.0 中,将 fal 软件包重新定义为 RT-Thread 内部组件。
在使用方式上和以前有这些区别:原本使用 fal 需要在 RT-Thread 的包管理器中选择并进行下载;现在只需要在组件中打开使用即可。以下做详细介绍。
1、FAL介绍
FAL (Flash Abstraction Layer) Flash 抽象层,是对 Flash 及基于 Flash 的分区进行管理、操作的抽象层,对上层统一了 Flash 及 分区操作的 API (框架图如下所示),并具有以下特性:
-
支持静态可配置的分区表,并可关联多个 Flash 设备;
-
分区表支持 自动装载 。避免在多固件项目,分区表被多次定义的问题;
-
统一的操作接口。保证了文件系统、OTA、NVM(例如:EasyFlash) 等对 Flash 有一定依赖的组件,底层 Flash 驱动的可重用性;
-
自带基于 Finsh/MSH 的测试命令,可以通过 Shell 按字节寻址的方式操作(读写擦) Flash 或分区,方便开发者进行调试、测试;
1.1、打开 FAL
在组件中打开使用:
每个功能的配置说明如下:
-
开启调试日志输出(默认开启);
-
分区表是否在
fal_cfg.h
中定义(默认开启)。如果关闭此选项,fal 将会自动去指定 Flash 的指定位置去检索并装载分区表,具体配置详见下面两个选项; -
存放分区表的 Flash 设备;
-
分区表的 结束地址 位于 Flash 设备上的偏移。fal 将从此地址开始往回进行检索分区表,直接读取到 Flash 顶部。如果不确定分区表具体位置,这里也可以配置为 Flash 的结束地址,fal 将会检索整个 Flash,检索时间可能会增加。
-
启用 FAL 针对 SFUD 的移植文件(默认关闭);
-
应输入调用
rt_sfud_flash_probe
函数时传入的 FLASH 设备名称(也可以通过 list_device 命令查看 Block Device 的名字获取)。该名称与分区表中的 Flash 名称对应,只有正确设置设备名字,才能完成对 FLASH 的读写操作。
1.2、FAL 目录
1.3、FAL API
FAL 相关的 API 如图所示,点击此处查看 API 参数详解。(以下链接请复制至外部浏览器打开)
https://github.com/RT-Thread/rt-thread/blob/master/components/fal/docs/fal_api.md
2、使用 FAL
使用 FAL 的基本步骤如下所示:
1、打开 FAL:从 Env 中打开 fal 组件。
2、FAL 移植:定义 flash 设备、定义 flash 设备表、定义 flash 分区表。以下主要对步骤 2 展开讲解。
3、调用 fal_init() 初始化该库:移植完成后,可在应用层调用,如在 main 函数中调用。
2.1、定义 flash 设备
在定义 Flash 设备表前,需要先定义 Flash 设备。可以是片内 flash, 也可以是片外基于 SFUD 的 spi flash:
-
定义片内 flash 设备可以参考 fal_flash_stm32f2_port.c
-
定义片外 spi flash 设备可以参考 fal_flash_sfud_port.c
定义具体的 Flash 设备对象,用户需要根据自己的 Flash 情况分别实现 init
、 read
、 write
、 erase
这些操作函数:
-
static int init(void)
:可选 的初始化操作。 -
static int read(long offset, uint8_t *buf, size_t size)
:读取操作。
-
static int write(long offset, const uint8_t *buf, size_t size)
:写入操作。
-
static int erase(long offset, size_t size)
:擦除操作。
用户需要根据自己的 Flash 情况分别实现这些操作函数。在文件最底部定义了具体的 Flash 设备对象 ,如下示例定义了 stm32f2 片上 flash:stm32f2_onchip_flash
1conststructfal_flash_devstm32f2_onchip_flash=
2{
3.name="stm32_onchip",
4.addr=0x08000000,
5.len=1024*1024,
6.blk_size=128*1024,
7.ops={init,read,write,erase},
8.write_gran=8
9};
-
"stm32_onchip"
: Flash 设备的名字。 -
0x08000000
: 对 Flash 操作的起始地址。 -
1024*1024
:Flash 的总大小(1MB)。 -
128*1024
:Flash 块/扇区大小(因为 STM32F2 各块大小不均匀,所以擦除粒度为最大块的大小:128K)。 -
{init, read, write, erase}
:Flash 的操作函数。如果没有 init 初始化过程,第一个操作函数位置可以置空。 -
8
: 设置写粒度,单位 bit, 0 表示未生效(默认值为 0 ),该成员是 fal 版本大于 0.4.0 的新增成员。各个 flash 写入粒度不尽相同,可通过该成员进行设置,以下列举几种常见 Flash 写粒度: -
nor flash: 1 bit
-
stm32f2/f4: 8 bit
-
stm32f1: 32 bit
-
stm32l4: 64 bit
2.2、定义 flash 设备表
Flash 设备表定义在 fal_cfg.h
头文件中,定义分区表前需 新建 fal_cfg.h
文件 ,请将该文件统一放在对应 BSP 或工程目录的 port 文件夹下,并将该头文件路径加入到工程。fal_cfg.h 可以参考 示例文件 fal/samples/porting/fal_cfg.h 完成。
设备表示例:
1/*=====================FlashdeviceConfiguration=========================*/
2externconststructfal_flash_devstm32f2_onchip_flash;
3externstructfal_flash_devnor_flash0;
4
5/*flashdevicetable*/
6#defineFAL_FLASH_DEV_TABLE
7{
8&stm32f2_onchip_flash,
9&nor_flash0,
10}
Flash 设备表中,有两个 Flash 对象,一个为 STM32F2 的片内 Flash ,一个为片外的 Nor Flash。
2.3、定义 flash 分区表
分区表也定义在 fal_cfg.h
头文件中。Flash 分区基于 Flash 设备,每个 Flash 设备又可以有 N 个分区,这些分区的集合就是分区表。在配置分区表前,务必保证已定义好 Flash 设备 及 设备表。fal_cfg.h 可以参考 示例文件 fal/samples/porting/fal_cfg.h 完成。
分区表示例:
1#defineNOR_FLASH_DEV_NAME"norflash0"
2/*======================PartitionConfiguration==========================*/
3#ifdefFAL_PART_HAS_TABLE_CFG
4/*partitiontable*/
5#defineFAL_PART_TABLE
6{
7{FAL_PART_MAGIC_WORD,"bl","stm32_onchip",0,64*1024,0},
8{FAL_PART_MAGIC_WORD,"app","stm32_onchip",64*1024,704*1024,0},
9{FAL_PART_MAGIC_WORD,"easyflash",NOR_FLASH_DEV_NAME,0,1024*1024,0},
10{FAL_PART_MAGIC_WORD,"download",NOR_FLASH_DEV_NAME,1024*1024,1024*1024,0},
11}
12#endif/*FAL_PART_HAS_TABLE_CFG*/
上面这个分区表详细描述信息如下:
用户需要修改的分区参数包括:分区名称、关联的 Flash 设备名、偏移地址(相对 Flash 设备内部)、大小,需要注意以下几点:
-
分区名保证 不能重复;
-
关联的 Flash 设备 务必已经在 Flash 设备表中定义好 ,并且 名称一致 ,否则会出现无法找到 Flash 设备的错误;
-
分区的起始地址和大小 不能超过 Flash 设备的地址范围 ,否则会导致包初始化错误;
注意:每个分区定义时,除了填写上面介绍的参数属性外,需在前面增加
FAL_PART_MAGIC_WORD
属性,末尾增加0
(目前用于保留功能)
3、Finsh/MSH 测试命令
fal 提供了丰富的测试命令,项目只要在 RT-Thread 上开启 Finsh/MSH 功能即可。在做一些基于 Flash 的应用开发、调试时,这些命令会非常实用。它可以准确的写入或者读取指定位置的原始 Flash 数据,快速的验证 Flash 驱动的完整性,甚至可以对 Flash 进行性能测试。
具体功能如下:输入 fal 可以看到完整的命令列表
1msh/>fal
2Usage:
3falprobe[dev_name|part_name]-probeflashdeviceorpartitionbygivenname
4falreadaddrsize-read'size'bytesstartingat'addr'
5falwriteaddrdata1...dataN-writesomebytes'data'startingat'addr'
6faleraseaddrsize-erase'size'bytesstartingat'addr'
7falbench-benchmarktestwithperblocksize
8
9msh/>
3.1、指定待操作的 Flash 设备或 Flash 分区
当第一次使用 fal 命令时,直接输入 fal probe
将会显示分区表信息。可以指定待操作的对象为分区表里的某个分区,或者某个 Flash 设备。
分区或者 Flash 被成功选中后,还将会显示它的一些属性情况。大致效果如下:
1msh/>falprobe
2Noflashdeviceorpartitionwasprobed.
3Usage:falprobe[dev_name|part_name]-probeflashdeviceorpartitionbygivenname.
4[I/FAL]====================FALpartitiontable====================
5[I/FAL]|name|flash_dev|offset|length|
6[I/FAL]-------------------------------------------------------------
7[I/FAL]|bl|stm32_onchip|0x00000000|0x00010000|
8[I/FAL]|app|stm32_onchip|0x00010000|0x000b0000|
9[I/FAL]|ef|norflash0|0x00000000|0x00100000|
10[I/FAL]|download|norflash0|0x00100000|0x00100000|
11[I/FAL]=============================================================
12msh/>
13msh/>falprobedownload
14Probedaflashpartition|download|flash_dev:norflash0|offset:1048576|len:1048576|.
15msh/>
16
3.2、擦除数据
先输入 fal erase
,后面跟着待擦除数据的起始地址以及长度。以下命令为:从 0 地址(相对 Flash 或分区)开始擦除 4096 字节数据
注意:根据 Flash 特性,擦除动作将按扇区对齐进行处理。所以,如果擦除操作地址或长度未按照 Flash 的扇区对齐,将会擦除掉与其关联的整个扇区数据。
1msh/>falerase04096
2Erasedatasuccess.Startfrom0x00000000,sizeis4096.
3msh/>
3.3、写入数据
先输入 fal write
,后面跟着 N 个待写入的数据,并以空格隔开。以下命令为:从地址 8 的位置依次开始写入 1、2、3、4 、 5 这 5 个字节数据
1msh/>falwrite812345
2Writedatasuccess.Startfrom0x00000008,sizeis5.
3Writedata:12345.
4msh/>
3.4、读取数据
先输入 fal read
,后面跟着待读取数据的起始地址以及长度。以下命令为:从 0 地址开始读取 64 字节数据
1msh/>falread064
2Readdatasuccess.Startfrom0x00000000,sizeis64.Thedatais:
3Offset(h)000102030405060708090A0B0C0D0E0F
4[00000000]FFFFFFFFFFFFFFFF0102030405FFFFFF
5[00000010]FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
6[00000020]FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
7[00000030]FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
8
9msh/>
3.5、性能测试
性能测试将会测试 Flash 的擦除、写入及读取速度,同时将会测试写入及读取数据的准确性,保证整个 Flash 或整个分区的 写入与读取 数据的一致性。
先输入 fal bench
,后面跟着待测试 Flash 的扇区大小(请查看对应的 Flash 手册,SPI Nor Flash 一般为 4096)。由于性能测试将会让整个 Flash 或者整个分区的数据丢失,所以命令最后必须跟 yes
。
1msh/>falbench4096yes
2Erasing1048576bytesdata,waiting...
3Erasebenchmarksuccess,totaltime:2.674S.
4Writing1048576bytesdata,waiting...
5Writebenchmarksuccess,totaltime:7.107S.
6Reading1048576bytesdata,waiting...
7Readbenchmarksuccess,totaltime:2.716S.
8msh/>
4、常见应用
-
基于 FAL 分区的 fatfs 文件系统例程
https://github.com/RT-Thread/IoT_Board/tree/master/examples/15_component_fs_flash
-
基于 FAL 分区的 littlefs 文件系统应用笔记
https://www.rt-thread.org/document/site/application-note/components/dfs/an0027-littlefs/
-
基于 FAL 分区的 EasyFlash 移植说明
https://github.com/armink-rtt-pkgs/EasyFlash/tree/master/ports
审核编辑:汤梓红
-
FlaSh
+关注
关注
10文章
1633浏览量
147935 -
fal
+关注
关注
0文章
5浏览量
6750 -
RT-Thread
+关注
关注
31文章
1285浏览量
40077
原文标题:RT-Thread v4.1.0 特性解析之 FAL 探秘
文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论