之前做了一些关于 Flash 的开源组件,比如:EasyFlash,SFUD, EasyLogger(内部的 Flash 插件),经常会有些网友问我一些关于 Flash 的问题,比如:在 Flash 的使用过程相信大家会经常遇到 OTA 升级时如何对 Flash 进行分区,多个 Flash 如何集中管理,片外的 fatfs 文件系统能否跑在片内等。
今天跟大家分享一个运行在MCU上的 Flash 管理工具,名为 FAL(Flash 抽象层),它是 RT-Thread 开源的一个通用软件包,能够运行在裸机平台,也能无缝兼容 RT-Thread 系统。一起来看下它的特色。
介绍
FAL (Flash Abstraction Layer) Flash 抽象层是对 Flash 及基于 Flash 的分区进行管理、操作的抽象层,对上层统一了 Flash 及 分区操作的 API ,并具有以下特性:
- 支持静态可配置的分区表,并可关联多个 Flash 设备;
- 分区表支持 自动装载 。避免在多固件项目,分区表被多次定义的问题;
- 代码精简,对操作系统 无依赖 ,可运行于裸机平台,比如对资源有一定要求的 Bootloader;
- 统一的操作接口。保证了文件系统、OTA、NVM(例如:EasyFlash) 等对 Flash 有一定依赖的组件,底层 Flash 驱动的可重用性;
- 自带基于 Finsh/MSH 的测试命令,可以通过 Shell 按字节寻址的方式操作(读写擦) Flash 或分区,方便开发者进行调试、测试;
使用 fal
使用 fal 前需要对项目的 Flash 进行移植工作,移植的文档位于: /samples/porting/README.md 。移植完成后,调用 fal_init() 初始化该库。
常见应用
- 基于 FAL 分区的 fatfs 文件系统例程
- 基于 FAL 分区的 littlefs 文件系统应用笔记
- 基于 FAL 分区的 EasyFlash 移植说明
Finsh/MSH 测试命令
fal 提供了丰富的测试命令,项目只要在 RT-Thread 上开启 Finsh/MSH 功能即可。在做一些基于 Flash 的应用开发、调试时,这些命令会非常实用。它可以准确的写入或者读取指定位置的原始 Flash 数据,快速的验证 Flash 驱动的完整性,甚至可以对 Flash 进行性能测试。
具体功能如下:输入 fal 可以看到完整的命令列表
- msh />fal
- Usage:
- fal probe [dev_name|part_name] - probe flash device or partition by given name
- fal read addr size - read 'size' bytes starting at 'addr'
- fal write addr data1 ... dataN - write some bytes 'data' starting at 'addr'
- fal erase addr size - erase 'size' bytes starting at 'addr'
- fal bench <blk_size> - benchmark test with per block size
- msh />
指定待操作的 Flash 设备或 Flash 分区
当第一次使用 fal 命令时,直接输入 fal probe 将会显示分区表信息。可以指定待操作的对象为分区表里的某个分区,或者某个 Flash 设备。
分区或者 Flash 被成功选中后,还将会显示它的一些属性情况。大致效果如下:
- msh />fal probe
- No flash device or partition was probed.
- Usage: fal probe [dev_name|part_name] - probe flash device or partition by given name.
- [I/FAL] ==================== FAL partition table ====================
- [I/FAL] | name | flash_dev | offset | length |
- [I/FAL] -------------------------------------------------------------
- [I/FAL] | bl | stm32_onchip | 0x00000000 | 0x00010000 |
- [I/FAL] | app | stm32_onchip | 0x00010000 | 0x000b0000 |
- [I/FAL] | ef | norflash0 | 0x00000000 | 0x00100000 |
- [I/FAL] | download | norflash0 | 0x00100000 | 0x00100000 |
- [I/FAL] =============================================================
- msh />
- msh />fal probe download
- Probed a flash partition | download | flash_dev: norflash0 | offset: 1048576 | len: 1048576 |.
- msh />
擦除数据
先输入 fal erase ,后面跟着待擦除数据的起始地址以及长度。以下命令为:从 0 地址(相对 Flash 或分区)开始擦除 4096 字节数据
注意:根据 Flash 特性,擦除动作将按扇区对齐进行处理。所以,如果擦除操作地址或长度未按照 Flash 的扇区对齐,将会擦除掉与其关联的整个扇区数据。
- msh />fal erase 0 4096
- Erase data success. Start from 0x00000000, size is 4096.
- msh />
写入数据
先输入 fal write ,后面跟着 N 个待写入的数据,并以空格隔开。以下命令为:从地址 8 的位置依次开始写入 1、2、3、4 、 5 这 5 个字节数据
- msh />fal erase 0 4096
- Erase data success. Start from 0x00000000, size is 4096.
- msh />
读取数据
先输入 fal read ,后面跟着待读取数据的起始地址以及长度。以下命令为:从 0 地址开始读取 64 字节数据
- msh />fal read 0 64
- Read data success. Start from 0x00000000, size is 64. The data is:
- Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
- [00000000] FF FF FF FF FF FF FF FF 01 02 03 04 05 FF FF FF
- [00000010] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
- [00000020] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
- [00000030] FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
- msh />
性能测试
性能测试将会测试 Flash 的擦除、写入及读取速度,同时将会测试写入及读取数据的准确性,保证整个 Flash 或整个分区的 写入与读取 数据的一致性。
先输入 fal bench ,后面跟着待测试 Flash 的扇区大小(请查看对应的 Flash 手册,SPI Nor Flash 一般为 4096)。由于性能测试将会让整个 Flash 或者整个分区的数据丢失,所以命令最后必须跟 yes 。
- msh />fal bench 4096 yes
- Erasing 1048576 bytes data, waiting...
- Erase benchmark success, total time: 2.674S.
- Writing 1048576 bytes data, waiting...
- Write benchmark success, total time: 7.107S.
- Reading 1048576 bytes data, waiting...
- Read benchmark success, total time: 2.716S.
- msh />
更多 API 及最新代码详见 GitHub:https://github.com/RT-Thread-packages/fal
本坛下载: