• 欢迎大家分享资料!前往留言板评论即可!

Luat读写SD卡/TF卡,通过fatfs模块

合宙 模组资料网 2年前 (2021-05-15) 353次浏览 0个评论 扫描二维码
文章目录[隐藏]

高能预警

当前版本 v0034 还没有内置fatfs的, 这里用的是自定义lod文件

update: 2019-06-18 更新到0034底层,并提供编译好的lod

代码预览

pmd.ldoset(6,pmd.LDO_VMMC) -- 必须打开供电
--fatfs.debug() -- 调试模式,会打印很多日志,帮助排错
fatfs.init() -- 初始化, 默认连接SPI_1, 片选是GPIO3
local fsm, err = fatfs.getfree() -- 获取磁盘信息
if fsm ~= nil then
    log.info("FatFS","Total", tostring(fsm.total_kb) .. "kb", tostring(fsm.total_kb/1024) .. "mb")
    log.info("FatFS","Free", tostring(fsm.free_kb) .. "kb", tostring(fsm.free_kb/1024) .. "mb")
end
-- 读取文件
local re, cnt, msg = fatfs.readfile("lua.txt")
if cnt ~= nil then
    log.info("FatFS", "lua.txt", "content ---> ", cnt);
end
-- 播放mp3目录下的sms.mp3文件
--fatfs.playmp3("/mp3/sms.mp3")

如何做到的?

先列一下前提和已知条件:

  1. SD卡(或者常用的小卡, TF卡),是支持SPI方式进行访问的,但比SDIO模式慢
  2. Air202/Air268/Air168/Air800均提供了SPI功能,而且性能还不错
  3. FAT16/FAT32可以通过fatfs进行访问,对接底层需要实现几个基础方法

把关键点逐个击破

  • 第一步, 知晓SD的SPI协议, 通过直接调用luat的spi, 完成卡的初始化,容量读取,读取数据块,跑通基本逻辑,验证可能性
  • 第二步, 下载luat的lod源码(一说csdk), 编译出原始lod, 并验证c模块的加载
  • 第三步, 把fatfs源码集成进lod源码, 并实现几个核心api, 完成对sd的读写

使用的硬件

  • Air202 S5/Air800 M4 开发板
  • TF卡/SD卡一张, 确保只有一个分区, 并格式化为FAT32, 根目录放几个文件,英文命名
  • TF卡读写模块

接线:

Air800 M4 TF模块 说明
5V VCC 供电
GND GND
SPI1_SCL/GPIO_8 SCL 时钟
SPI1_MISO/GPIO_12 SDI 数据输入
SPI1_MOSI/GPIO_11 SDO 数据输出
GPIO_3 CS 片选,不要错(可配置)

如何使用

  • 首先, 需要访问 https://gitee.com/wendal/Luat_Lod_Source , 如果您有码云账号, 麻烦点个star
  • 然后, 访问附件, 下载 Luat_V0032_8955.lod 或者 Luat_V0034_8955_fatfs.lod
  • 再接着, 把lod和 main.lua 下载到 你的开发板
  • 开机,看日志

已经支持的API

方法名 用途
mount 初始化,必须调用一次且仅一次
getfree 获取空间信息,在mount之后调用
unmount 取消挂载,通常不需要调用
mkfs 格式化SD/TF卡
debug 调试模式,如果发现bug,请开启之,不需要传参数
lsdir 列出目录下的文件
mkdir 创建目录
stat 获取文件/文件夹信息
open 打开文件,返回举报
read 使用句柄读取文件数据
write 使用句柄写入文件数据
seek 移动句柄指针
close 关闭文件句柄
unlink 删除文件/文件夹
rename 文件改名
readfile 直接读取文件内容,简易方法
playmp3 播放sd卡上的mp3文件

固件里面到底改了什么?

如果你看到这里,应该是的确有心用SD卡了,那么我需要澄清几个问题:
1. 并不变砖, 虽然我刷挂了一块板子, 原因是选错了lod, 而不是因为fatfs. 编译目录里面有2个lod文件, 一大一小, 刷小的会挂(这点比较坑).
2. fatfs对源码的修改并不大, 只是添加一个库,并引用它 源码级别的引用 , 并没有去修改其他模块的代码, 也不会影响其他模块的功能
3. 同样的修改可以应用到老的lod源码, 独立性很强的

修改的内容(注意文件编码,都是GB2312):

  1. 添加 cust_src/elua/lib/fatfs 目录, 所有实现代码都在这里
  2. 修改 cust_src/cust_module_list.mk 添加对fatfs目录编译引用
// 在末尾添加
LOCAL_MODULE_DEPENDS  += cust_src/elua/lib/fatfs
  1. 修改 cust_src/elua/modules/include/auxmods.h
// 在125行附近添加, 是新建2行, 前后都要加空行
#define AUXLIB_FATFS     "fatfs"
LUALIB_API int ( luaopen_fatfs )( lua_State *L );
  1. 修改 cust_src/elua/platform/coolsand/include/platform_conf.h
// 在141行加入,前后不要加空行!!! 注意末尾的斜杠!!
_ROM( AUXLIB_FATFS, luaopen_fatfs, fatfs_map ) \

是的,就修改这4个地方, 没有对其他模块进行修改的.

fatfs库的源码是怎么实现的

  • 首先,它是最新的FatFs R0.13c
  • 然后,主要代码来源于ffsample里面的generic, 这是一个非常完善的demo, 经过我多天的摸索, 发现替换掉里面的几个底层方法,就可以很好地适配Air系列的SPI, 分别是 dly_us(延时函数) xmit_mmc(发送函数) rcvr_mmc(接收函数), 这里代码都在diskio.c文件里面
  • 最后,就是fatfs的lua绑定了, 这部分只能从0开始写了

还有什么不足

  • 还不能与FLOAT固件兼容,应该是固件空间的设置问题,还没搞懂
  • 还需要支持模拟SPI的方式
  • 需要提高读写速度,当前速度还是有点慢, 部分原因是SPI的速率还没找到最合适的
  • 延时函数只能到毫秒级, 如果实现us级别,读写速度更快
  • 还不知道get_fattime,导致当前创建的文件,时间是固定的

嗯,大概就是这样,希望大家喜欢这个fatfs模块


转载请注明原文链接:Luat读写SD卡/TF卡,通过fatfs模块
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址