参考文章:RT-Thread--片上 flash挂载 littlefs 文件系统
RT-Thread Studio片上Flash 实现Flash抽象层FAL笔记
RT-Thread Studio STM32F249BIT6移植FAL记录
stm32f407使用rt thread 的easy flash 和fal
参考文章是通过脚本配置工具env的menuconfig 进行配置的,在Rt-Thread Studio配置操作还是有点差异。配置操作的前提是SPI Flash硬件基础已经具备。
在Rt-Thread Studio中打开RT-Thread Settings,进入配置界面
1,使能SPI总线和MTD
在搜索栏中搜索SPI,在下拉列表中点取“使用SPI总线/设备驱动程序”,进入到该界面,设置如下:
2,使能虚拟文件系统
文件系统的最大数目和和文件系统类型数目都设置为5,使能只读文件系统。
3,使能 fal 软件包
在搜索栏中搜索fal,在下拉列表中点取“FAL:Flash抽象层实现,管理Flash设备和分区”,进入到该界面,设置如下:
使能调试日志的输出默认的打开的,如果不信看到一大推的信息输出,关掉此选项。Littlefs选项要打开,确保disk block size的大小是4096。
4,配置后保存并编译,发现:
...fal-v1.0.0\inc/fal.h:15:21: fatal error: fal_cfg.h: No such file or directory
双击产生的错误提示,定位到错误处,如下
实际上在错误处按下Ctrl键点击,进入到下图界面
实际该文件是存在的。报错原因是文件所在路径不对,可以两种两种办法处理,方法一是直接复制该文件到和fal.h相同目录下。方法二是,修改其SConscript文件,加入该头文件的搜索路径。我选择方法一,问题解决。
4,接着报错:
...spi/spi_flash.h:28:33: error: field 'mtd_device' has incomplete type
代码修改如下:注意定义指针类型(struct rt_mtd_nor_device *)
#ifdef RT_USING_MTD_NOR
struct spi_flash_mtd
{
struct rt_mtd_nor_device* mtd_device;
struct rt_spi_device * rt_spi_device;
struct rt_mutex lock;
void * user_data;
};
#endif
5,继续编译,出现连接错误:
.../packages/fal-v1.0.0/src/fal_flash.o:(.rodata.device_table+0x0): undefined reference to `stm32f2_onchip_flash'
问题出在这里
找到nor_flash在fal_flash_sfud_port.c的定义是这样的
同样道理,需要加入On Chip flash的定义,但是这部分在RT-Thread Studio中没找到配置选项,只好自己增加,首先在board.h中加入如下定义:
/*-------------------------- ON CHIP CONFIG BEGIN --------------------------*/
/** if you want to use on chip flash you can use the following instructions.
*
* STEP 1, define macro related to the on chip flash
* such as #define BSP_USING_ON_CHIP_FLASH
*
* STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support on chip flash peripherals. define macro related to the peripherals
* such as #define HAL_FLASH_MODULE_ENABLED
*/
#define BSP_USING_ON_CHIP_FLASH
然后打前面复制的inc/fal_cfg.h文件,修改如下:
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtconfig.h>
#include <board.h>
#define NOR_FLASH_DEV_NAME "norflash0"
#define FLASH_SIZE_GRANULARITY_16K (4 * 16 * 1024)
#define FLASH_SIZE_GRANULARITY_64K (1 * 64 * 1024)
#define FLASH_SIZE_GRANULARITY_128K (7 * 128 * 1024)
#define STM32_FLASH_START_ADRESS_16K STM32_FLASH_START_ADRESS
#define STM32_FLASH_START_ADRESS_64K (STM32_FLASH_START_ADRESS_16K + FLASH_SIZE_GRANULARITY_16K)
#define STM32_FLASH_START_ADRESS_128K (STM32_FLASH_START_ADRESS_64K + FLASH_SIZE_GRANULARITY_64K)
/* ===================== Flash device Configuration ========================= */
extern const struct fal_flash_dev stm32_onchip_flash_16k;
extern const struct fal_flash_dev stm32_onchip_flash_64k;
//extern const struct fal_flash_dev stm32_onchip_flash_128k;
extern struct fal_flash_dev nor_flash0;
/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&stm32_onchip_flash_16k, \
&stm32_onchip_flash_64k, \
&nor_flash0, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "bootloader", "stm32_onchip", 0, FLASH_SIZE_GRANULARITY_16K, 0}, \
{FAL_PART_MAGIC_WORD, "app", "stm32_onchip", 0, FLASH_SIZE_GRANULARITY_64K, 0}, \
{FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME, 0, 1024*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", NOR_FLASH_DEV_NAME, 1024*1024, 1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
注意stm32_onchip_flash_16k和stm32_onchip_flash_64k的定义在drv_flash_f4.c文件中。
编译通过。下载运行,出现
以下几个地方的代码需要一致才不报错:
(1)SPI Flash 设备名用的是 norflash0,如下图
当然生成的代码请参照上面inc/fal_cfg.h文件。
(2)SPI Flash初始化代码,注意画红线部分
(3)文件系统挂载:
#ifdef RT_USING_DFS
#include <dfs_romfs.h>
#include <dfs_fs.h>
#include <dfs_posix.h>
#if DFS_FILESYSTEMS_MAX < 4
#error "Please define DFS_FILESYSTEMS_MAX more than 4"
#endif
#if DFS_FILESYSTEM_TYPES_MAX < 4
#error "Please define DFS_FILESYSTEM_TYPES_MAX more than 4"
#endif
#ifdef BSP_USING_SDCARD_FATFS
static int onboard_sdcard_mount(void)
{
if (dfs_mount("sd0", "/sdcard", "elm", 0, 0) == RT_EOK)
{
LOG_I("SD card mount to '/sdcard'");
}
else
{
LOG_E("SD card mount to '/sdcard' failed!");
}
return RT_EOK;
}
#endif
#ifdef BSP_USING_SPI_FLASH_LITTLEFS
//#include <fal.h>
#define FS_PARTITION_NAME "filesystem"
static int onboard_spiflash_mount(void)
{
struct rt_device *mtd_dev = RT_NULL;
fal_init();
mtd_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);
if (!mtd_dev)
{
LOG_E("Can't create a mtd device on '%s' partition.", FS_PARTITION_NAME);
}
if (dfs_mount(FS_PARTITION_NAME, "/spiflash", "lfs", 0, 0) == RT_EOK)
{
LOG_I("spi flash mount to '/spiflash'");
}
else
{
dfs_mkfs("lfs", FS_PARTITION_NAME);
if (dfs_mount(FS_PARTITION_NAME, "/spiflash", "lfs", 0, 0) == RT_EOK)
{
LOG_I("spi flash mount to '/spiflash'");
}
else
{
LOG_E("spi flash failed to mount to '/spiflash'");
}
}
return RT_EOK;
}
#endif
static const struct romfs_dirent _romfs_root[] =
{
#ifdef BSP_USING_SDCARD_FATFS
{ROMFS_DIRENT_DIR, "sdcard", RT_NULL, 0},
#endif
#ifdef BSP_USING_SPI_FLASH_LITTLEFS
{ROMFS_DIRENT_DIR, "spiflash", RT_NULL, 0},
#endif
};
const struct romfs_dirent romfs_root =
{
ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_romfs_root, sizeof(_romfs_root) / sizeof(_romfs_root[0])
};
static int filesystem_mount(void)
{
if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) != 0)
{
LOG_E("rom mount to '/' failed!");
}
#ifdef BSP_USING_SDCARD_FATFS
onboard_sdcard_mount();
#endif
#ifdef BSP_USING_SPI_FLASH_LITTLEFS
onboard_spiflash_mount();
#endif
return RT_EOK;
}
INIT_APP_EXPORT(filesystem_mount);
#endif /* BSP_USING_FS */
然后重新编译下载
可以看到,SPI flash 初始化并成功挂载。
输入fal probe arg测试下