Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
ART-Pi
elm_fatfs_FAT文件系统
外部flash
ART-Pi 外部 SPI Flash 使用 elmfatfs 文件系统
发布于 2023-06-16 16:34:23 浏览:727
订阅该版
[tocm] # 有关技术背景 ## SPI 介绍 https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi SPI 原理: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/f8d48bfced9496743dc027bc46c8cb27.png) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/4f7d71282b9aa37ce845d29c56212723.png) ## FAL (Flash Abstraction Layer) Flash 抽象层 https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/fal/fal?id=fal-%e7%bb%84%e4%bb%b6 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/067a5aaa36753aac1194b1e64d704aa2.png.webp) ## DFS (Device File System) 设备虚拟文件系统 https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/filesystem/filesystem?id=dfs-%e7%ae%80%e4%bb%8b DFS 的层次架构图: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/882501c07eb0f86089e2df931a8112e5.png.webp) ## ROMFS https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/qemu-network/filesystems/filesystems?id=%e4%bd%bf%e7%94%a8-romfs ## ARTPI 外部 SPI Flash ARTPI 有一个外部 SPI Flash,空间为 16-Mbytes,使用的是 ARTPI 的 SPI1 接口。 查阅 Flash 的数据手册可知,扇区大小为 4KB,也就是 4096B: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/52f35f6f1e9466cbc055baa212551385.png.webp) # 整体思路 在 meunconfig 中开启 DFS,本教程使用 elmfatfs 文件系统,需要将 elmfatfs 挂载到 RT-Thread 的 DFS 上,所以 elmfatfs 也要开启: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/85071d2be15e53b57000313babd1f12c.png.webp) 注意要把扇区大小改成上面查阅的 4096: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/5fee2679852b86c016ce2aca063688af.png) 当然,不要忘记在 meunconfig 中开启 SPI Flash filesystem: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/f11c4e87a2d2e18dca867aa83703ca47.png) 此时 `scons --target=mdk5` 然后编译下载,运行结果会是这样: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/5dcf67f3f03398ccc76cda107acfc6d8.png) 显示两个报错: 一是 Flash 上面的 filesystem 分区(在上方输出的 FAL 分区表种可以找到,对应的定义在 `fal_cfg.h` 文件中)挂载到 /flash 上失败了;二是 lfs 文件系统没有找到 我们在 `filesystem.c` 中找到了报错对应的代码: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/ac8a5638619c62929b541fbca2b20812.png.webp) 可以看出来这部分代码是挂载 lfs 文件系统,于是上面报错的原因找到了:我们使用的是 elm-FATFS 系统,需要手动修改一下挂载代码。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/14fa845146c857cb3efe8a7cc3913b25.png.webp) 我们创建设备的时候是 BLK 设备,要用 `fal_blk_device_create` 这个函数。 代码修改之后是这样: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/860bd0319ec20e81f8357b44e8a0a254.png.webp) 照葫芦画瓢写个 elm 系统的挂载,主要的区别有: 1.注册设备用的 `fal_blk_device_create` 而非 `fal_mtd_nor_device_create` 2.挂载到 / 而非 /flash 3.文件系统使用 elm 而非 rom 修改完之后重新编译下载,发现依旧报错,运行 ls 查看一下情况,发现是这样: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/f8c43c5dc817395e949a63b5a21d86d6.png) 再次返回查看代码,原来是这里导致的: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/0b6f893829af36afedaa130eac91a74b.png) 使用了 romfs,然后开启了 flash 和 sdcard 两块区域。这里我们需要默认不使用 ROMFS,改成这样: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/f761bffb7f10c595912b606534967691.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/6bb98307c1079179ee90ff058315134c.png) 另外在 menuconfig 中查看,发现这个宏是默认开启的,找到是在 `boards/Kconfig` 中默认选择了,需要注释掉: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/28c844e1c4981d14ff72c7d54e4c5333.png) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/f2ee8773c3a4cc3a7d84d5795d2160f1.png) 到对应的选项取消掉这个宏: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/598f779d2e8ce7aae85d7497dd7c634e.png.webp) 最终,filesystem.c 的代码完整版如下: ``` /* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-12-13 balanceTWK add sdcard port file * 2019-06-11 WillianChan Add SD card hot plug detection */ #include
#ifdef BSP_USING_FS #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 #include
#ifdef BSP_USING_SDCARD_FS #include
#include "drv_sdio.h" #endif #ifdef BSP_USING_SPI_FLASH_FS #include "fal.h" #endif #define DBG_TAG "app.filesystem" #define DBG_LVL DBG_INFO #include
#ifdef RT_USING_DFS_ROMFS /* 默认不使用 ROMFS */ #include "dfs_romfs.h" static const struct romfs_dirent _romfs_root[] = { {ROMFS_DIRENT_DIR, "flash", RT_NULL, 0}, {ROMFS_DIRENT_DIR, "sdcard", RT_NULL, 0} }; const struct romfs_dirent romfs_root = { ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_romfs_root, sizeof(_romfs_root) / sizeof(_romfs_root[0]) }; #endif #ifdef BSP_USING_SDCARD_FS /* SD Card hot plug detection pin */ #define SD_CHECK_PIN GET_PIN(D, 5) static void _sdcard_mount(void) { rt_device_t device; device = rt_device_find("sd0"); if (device == NULL) { mmcsd_wait_cd_changed(0); sdcard_change(); mmcsd_wait_cd_changed(RT_WAITING_FOREVER); device = rt_device_find("sd0"); } if (device != RT_NULL) { if (dfs_mount("sd0", "/sdcard", "elm", 0, 0) == RT_EOK) { LOG_I("sd card mount to '/sdcard'"); } else { LOG_W("sd card mount to '/sdcard' failed!"); } } } static void _sdcard_unmount(void) { rt_thread_mdelay(200); dfs_unmount("/sdcard"); LOG_I("Unmount \"/sdcard\""); mmcsd_wait_cd_changed(0); sdcard_change(); mmcsd_wait_cd_changed(RT_WAITING_FOREVER); } static void sd_mount(void *parameter) { rt_uint8_t re_sd_check_pin = 1; rt_thread_mdelay(200); if (rt_pin_read(SD_CHECK_PIN)) { _sdcard_mount(); } while (1) { rt_thread_mdelay(200); if (!re_sd_check_pin && (re_sd_check_pin = rt_pin_read(SD_CHECK_PIN)) != 0) { _sdcard_mount(); } if (re_sd_check_pin && (re_sd_check_pin = rt_pin_read(SD_CHECK_PIN)) == 0) { _sdcard_unmount(); } } } #endif /* BSP_USING_SDCARD_FS */ int mnt_spi_flash_init(void) { struct rt_device *flash_dev = RT_NULL; #ifndef RT_USING_WIFI fal_init(); #endif flash_dev = fal_blk_device_create("filesystem"); if (flash_dev) { //mount filesystem if (dfs_mount(flash_dev->parent.name, "/", "elm", 0, 0) != 0) { LOG_W("mount to '/' failed! try to mkfs %s", flash_dev->parent.name); dfs_mkfs("elm", flash_dev->parent.name); if (dfs_mount(flash_dev->parent.name, "/", "elm", 0, 0) == 0) { LOG_I("mount to '/' success!"); } } else { LOG_I("mount to '/' success!"); } } else { LOG_E("Can't create block device filesystem or bt_image partition."); } } int mount_init(void) { #ifdef RT_USING_DFS_ROMFS /* 默认不使用ROMFS */ if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) != 0) { LOG_E("rom mount to '/' failed!"); } #endif #ifdef BSP_USING_SPI_FLASH_FS mnt_spi_flash_init(); #if 0 struct rt_device *flash_dev = RT_NULL; #ifndef RT_USING_WIFI fal_init(); #endif flash_dev = fal_mtd_nor_device_create("filesystem"); if (flash_dev) { //mount filesystem if (dfs_mount(flash_dev->parent.name, "/flash", "lfs", 0, 0) != 0) { LOG_W("mount to '/flash' failed! try to mkfs %s", flash_dev->parent.name); dfs_mkfs("lfs", flash_dev->parent.name); if (dfs_mount(flash_dev->parent.name, "/flash", "lfs", 0, 0) == 0) { LOG_I("mount to '/flash' success!"); } } else { LOG_I("mount to '/flash' success!"); } } else { LOG_E("Can't create block device filesystem or bt_image partition."); } #endif #endif #ifdef BSP_USING_SDCARD_FS rt_thread_t tid; rt_pin_mode(SD_CHECK_PIN, PIN_MODE_INPUT_PULLUP); tid = rt_thread_create("sd_mount", sd_mount, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 2, 20); if (tid != RT_NULL) { rt_thread_startup(tid); } else { LOG_E("create sd_mount thread err!"); } #endif return RT_EOK; } INIT_APP_EXPORT(mount_init); #endif /* BSP_USING_FS */ ``` 重新生成、编译、下载,运行结果如下: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20230616/6bf020f9c97c3f278ab7112fff3c0e01.png) 大功告成!
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
IcyFeather
这家伙很懒,什么也没写!
文章
10
回答
7
被采纳
1
关注TA
发私信
相关文章
1
程序分散加载到外部QSPI FLASH 启动问题
2
stm32f429如何下载程序到外部flash
3
安卓手机不能识别挂载w25q flash
4
rtthread stlink加载外部算法问题
5
flashdb kv value的最大字节
6
关于F1使用通用BOOT+片外FLASH升级SFUD初始化失败的问题
7
文件系统挂载到指定内存区域
8
ART-Pi的APP运行在外部Flash,那还能对内部flash进行读写操作吗?
9
外部flash是nm25q128挂载不上有大神指点嘛
10
挂载外部flash出现这个问题有大神解决吗
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部