1.
FAL组件
1.1
什么是FAL
FAL (Flash Abstraction Layer) Flash 抽象层,是对 Flash 及基于 Flash 的分区进行管理、操作的抽象层,对上层统一了 Flash 及 分区操作的 API (框架图如下所示),并具有以下特性:
支持静态可配置的分区表,并可关联多个 Flash 设备;
分区表支持 自动装载 。避免在多固件项目,分区表被多次定义的问题;
代码精简,对操作系统 无依赖 ,可运行于裸机平台,比如对资源有一定要求的 Bootloader;
统一的操作接口。保证了文件系统、OTA、NVM(例如:EasyFlash https://github.com/armink-rtt-pkgs/EasyFlash) 等对 Flash 有一定依赖的组件,底层 Flash 驱动的可重用性;
自带基于 Finsh/MSH 的测试命令,可以通过 Shell 按字节寻址的方式操作(读写擦) Flash 或分区,方便开发者进行调试、测试;

通过上图我们也可以清晰明了了,看到,FAL抽象层向下可以通过Flash硬件进行统一管理,当然也可以使用SFUD框架(串行Flash通用驱动库,这部分RT-Thread已完成官方框架的移植同时提供多个应用历程),而对上也可以使用如DFS、NVM提供的Flash硬件统一访问接口,方便用户更加直接方便对底层Flash硬件的访问操作。
注:非易失性存储器 (NVM):在芯片电源关闭期间保存存储在其中的数据。因此,它被用于没有磁盘的便携式设备中的内存,以及用于可移动存储卡等用途。主要类型有:非易失性半导体存储器 (Non-volatile semiconductor memory, NVSM) 将数据存储在浮栅存储单元中,每个单元都由一个浮栅(floating-gate) MOSFET 组成。
关于存储,可以用一张图来解释:

来源:ROM、RAM、FLASH、NVM......一文搞定(https://blog.youkuaiyun.com/lianyunyouyou/article/details/118277207)
1.2
使用ENV配置FAL
在RT-Thread v4.1.0之前,FAL是作为软件包形式对用户开放使用的,而v4.1.0之后,FAL被RT-Thread官方重新定义为RTT组件的一部分,这样也能更加方便用户的开发。
我们下面正式讲解FAL组件的使用:
首先打开ENV工具,根据以下路径打开FAL使能 RT-Thread Components->[*]FAL: flash abstraction layer,由于我们后面会用到SFUD,所以这里把 FAL uses SFUD drivers 一并使能,并修改FAL设备名称为 W25Q128.

完成上述操作后保存退出,并使用 scons --target=mdk5 重新生成MDK5文件并打开
1.3
FAL SFUD 移植
为了提供示例,我们选用 W25Q128 spi flash 作为测试模块,并且使用SFUD框架对spi flash设备进行管理和驱动。
由于目前RT-Thread的SFUD已经对 W25Q128 完成支持,根据官方的使用手册,我们仅需编写 fal_cfg.h 文件完成对 FAL_FLASH_DEV_TABLE 及 FAL_PART_TABLE 的定义即可。文件存放路径:.\rt-thread\bsp\lpc55sxx\lpc55s69_nxp_evk\board\ports\fal_cfg.h
// fal.cfg.h
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-04-21 Wangyuqiang the first version
*/
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtthread.h>
#include <board.h>
#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define NOR_FLASH_DEV_NAME "norflash0"
#else
#define NOR_FLASH_DEV_NAME FAL_USING_NOR_FLASH_DEV_NAME
#endif
/* Flash device Configuration */
extern struct fal_flash_dev nor_flash0;
/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&nor_flash0, \
}
/* Partition Configuration */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WROD, "easyflash", NOR_FLASH_DEV_NAME, 0, 512 * 1024, 0}, \
{FAL_PART_MAGIC_WROD, "download", NOR_FLASH_DEV_NAME, 512 * 1024, 1024 * 1024, 0}, \
{FAL_PART_MAGIC_WROD, "wifi_image", NOR_FLASH_DEV_NAME, (512 + 1024) * 1024, 512 * 1024, 0}, \
{FAL_PART_MAGIC_WROD, "font", NOR_FLASH_DEV_NAME, (512 + 1024 + 512) * 1024, 7 * 1024 * 1024, 0}, \
{FAL_PART_MAGIC_WROD, "filesystem", NOR_FLASH_DEV_NAME, (512 + 1024 + 512 + 7 * 1024) * 1024, 7 * 1024 * 1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
此时编译的话是找不到该头文件的,需要我们在Keil中设置:

在RTT FAL组件中的SFUD提供的 fal_flash_dev 对象默认的nor_flash0参数中,flash大小默认为8M,而 W25Q128 最大最16M,我们可以选择在 .\rt-thread\components\fal\samples\porting\fal_flash_sfud_port.c文件中对struct fal_flash_dev nor_flash0 进行修改:
struct fal_flash_dev nor_flash0 =
{
.name = FAL_USING_NOR_FLASH_DEV_NAME,
.addr = 0,
.len = 16 * 1024 * 1024,
.blk_size = 4096,
.ops = {init, read, write, erase},
.write_gran = 1
};
当然也可以选择不进行修改,根据大佬的原话就是因为在调用初始化接口函数init后,会从flash设备读取正确的参数更新到nor_flash0表项中,我们在使用FAL组件前都需要调用FAL初始化函数fal_init,其内调用flash设备初始化函数fal_flash_init,最后会调用注册到fal_flash_dev设备表项中的初始化函数device_table[i]->ops.init,所以nor_flash0表项参数会在FAL初始化时被更新。
同时我们需要开启SFUD框架支持,打开ENV工具,由于SFUD的使用需要指定一个spi设备,这里我选择使用最近移植好的软件spi,路径 Hardware Drivers Config->On-chip Peripheral Drivers->[*] Enable soft SPI BUS-> [*] Enable soft SPI1 BUS (software simulation) ,这里我的测试开发板是恩智浦的LPC55S69-EVK,并且这款bsp的软件模拟spi由我本人对接,关于这部分的软件spi引脚定义可以选用默认即可,当然也可以使用自定义引脚,记住不要与其他引脚产生冲突。

此时我们回到ENV主界面,进入 RT-Thread Components->Device Drivers->Using Serial Flash Universal Driver ,此时我们才可以看到SFUD选项出现(如果没有使能spi是没法看到的),使能后保持默认即可

到这里,ENV的配置暂时告一段落!
1.4
FAL SFUD 测试用例
为了验证 W25Q128 及软件模拟spi在SFUD框架上是否能够成功运行,我们在 .\rt-thread\bsp\lpc55sxx\lpc55s69_nxp_evk\board\ports\&nbs
RT-Thread中FAL、DFS与EasyFlash组件应用

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



