在Nordic52832芯片的Flash上,使用的是RT-Thread系统,采用DFS+littlefs 的方式创建文件系
统。本文会描述在创建的过程中踩过的一些坑,希望可以帮助到大家。
先来看一下DFS的架构,最底部就是Flash硬件,我们会使用FAL组件来创建块设备也就是倒数第二层,虚拟文件系统层使用littlefs文件系统类型,最后在POSIX层可以调用open()、close()、read()、write()等接口操作文件。
打开Device virtual file system,按照自己的需求进行设置。如果使用的不是littlefs文件系统类型,而是FatFS ,可以在这里将Enable elm-chan fatfs打开。
打开on-chip FLASH,可以设置芯片的FLASH信息,我使用的52832芯片,有512k的flash,从地址0x00000000开始,有64k的RAM,从地址0x20000000开始。
勾选FAL组件包,版本选择的是v0.5.0,可以按自己的需求选择,这个SFUD是用于片外Flash的,这里不需要勾选。
通过上面的操作后,我们更新软件包重新生成工程,打开工程可以看到有一些新增的文件。
编译工程会发现,报错了,显示在drv_flash.c文件中使用了未定义的mcu_onchip_flash。
可以在drv_flash.c文件,找到fal.h文件打开
打开fal.h后再打开fal_cfg.h文件。
可以看到有一个extern struct fal_flash_dev nor_flash0;声明。
会发现这个结构体类型和drv_flash.c文件中的mcu_onchip_flash类型是一样的,我们只要把nor_flash0改成mcu_onchip_flash,把const删除,结构体中的name改成NOR_FLASH_DEV_NAME就可以了。
再次编译,没有报错了。
调用fal_init()函数,可以看到log中打印出了flash的设置。绿色表格是fal的分区,目前还没有进行设置。
接下来编写代码,创建块设备,我们创建的是littlefs文件类型的块设备,所以还需要引入littlefs相关的内容。
使用默认设置,可以按自己需求更改。
这里的version不要使用v2.5.0版本,会出现以下错误,打开软件包发现里面只有yml文件。
安装软件包,重新生成工程。
更改fal_cfg.h中FAL_PART_TABLE中的内容,第一个值是固定值不更改。第二个是分区的名称可以自己定义但不能重复。第三个是flash设备名称可以自定义但不能重复。第四个是分区开始地址,是在flash中的地址。第五个是分区大小。
我这里从flash偏移量444*1024开始,开辟32k的空间,这里开辟的空间一定是要没有使用的空间。
可以根据自己的flash使用进行推算,本人的flash使用是协议栈+app+bootloader,开辟的空间因该位于app中没有使用的位置,所以开始地址可以从bootloader的开始地址往前32k。
调用fal_mtd_nor_device_create(FATFS_FLASH_NAME)函数,进行块设备的创建并注册。
编译后可能会出现如下报错,可以在文件最顶部加上#include <nrfx.h>引入这个头文件。
运行后可以看到我们的块设备w25q-ef已经创建好了。
然后就可以进行块设备的格式化和挂载了。
块设备的格式化:
dfs_mkfs("lfs", FATFS_FLASH_NAME);
挂载:
dfs_mount(FATFS_FLASH_NAME, "/", "lfs", 0, 0);
参考代码:
#include <nrfx.h>
#include <ulog.h>
#include "dfs_fs.h"
#include <fal.h>
#define FATFS_FLASH_NAME "w25q-ef"
void littlefs_init(uint8_t mode)
{
rt_bool_t b_init = RT_FALSE;
if (mode == 1)
{
int32_t res;
res = dfs_mkfs("lfs", FATFS_FLASH_NAME);
LOG_D("dfs %d",res);
return;
}
if (b_init==RT_TRUE)
{
return;
}
b_init = RT_TRUE;
fal_init();
fal_mtd_nor_device_create(FATFS_FLASH_NAME);
if (dfs_mount(FATFS_FLASH_NAME, "/", "lfs", 0, 0) == 0)
{
rt_kprintf("File Syetem Initialized\r\n");
}
else
{
rt_kprintf("File Syetem Fail\r\n");
if (dfs_mkfs("lfs", FATFS_FLASH_NAME) == 0)
{
rt_kprintf("dfs_mkfs sucess\r\n");
if (dfs_mount(FATFS_FLASH_NAME, "/", "lfs", 0, 0) == 0)
{
rt_kprintf("File Syetem Initialized\r\n");
}
}
}
}
输入ls命令,可以看到块设备挂载到了根目录/下。