本demo演示了在嵌入式环境中对TF卡(SD卡)的完整操作流程,覆盖了从文件系统挂载到高级文件操作的完整功能链。项目分为两个核心模块:
1、main.lua:主程序入口
2、tfcard_app.lua:TF卡基础应用模块,实现文件系统管理、文件操作和目录管理功能。
3、http_download_file.lua:HTTP下载模块,实现网络检测与文件下载到TF卡的功能
在Air780EHM/EHV/EGH开发板上,spi0上同时外挂了tf卡和ch390h以太网芯片两种spi从设备,这两种外设通过不同的cs引脚区分; 测试tf功能前,需要将ch390h的cs引脚拉高,这样可以保证ch390h不会干扰到tf功能;
/sd路径空间信息获取:
输出详细存储信息(总空间/剩余空间)
创建目录:io.mkdir("/sd/io_test")
创建/写入文件: io.open("/sd/io_test/boottime", "wb")
检查文件存在: io.exists(file_path)
获取文件大小:io.fileSize(file_path)
读取文件内容: io.open(file_path, "rb"):read("*a")
启动计数文件: 记录设备启动次数
文件追加: io.open(append_file, "a+")
按行读取: file:read("*l")
文件关闭: file:close()
文件重命名: os.rename(old_path, new_path)
列举目录: io.lsdir(dir_path)
删除文件: os.remove(file_path)
删除目录: io.rmdir(dir_path)
1、Air780EHM核心板一块(Air780EHM/780EGH/780EHV三种模块的核心板接线方式相同,这里以Air780EHM为例)
2、TYPE-C USB数据线一根
3、AirMICROSD_1010模块一个和SD卡一张
4、Air780EHM/780EGH/780EHV核心板和数据线的硬件接线方式为
Air780EHM核心板通过TYPE-C USB口供电;(核心板USB旁边的开关拨到on一端)
TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
5、Air780EHM核心板和AirMICROSD_1010模块接线方式
| Air780EHM | AirMICROSD_1010 |
|---|---|
| GND(任意) | GND |
| VDD_EXT | 3V3 |
| GPIO8/SPI0_CS | spi_cs |
| SPI0_SLK | spi_clk,时钟 |
| SPI0_MOSI | spi_mosi,主机输出,从机输入 |
| SPI0_MISO | spi_miso,主机输入,从机输出 |
1、Air780EHM开发板一块(Air780EHM/780EGH/780EHV三种模块的开发板接线方式相同,这里以Air780EHM为例)
2、TYPE-C USB数据线一根
3、AirMICROSD_1010模块一个和SD卡一张
4、Air780EHM/780EGH/780EHV开发板和数据线的硬件接线方式为
Air780EHM开发板通过TYPE-C USB口供电;(开发板USB旁边的开关拨到USB供电一端)
TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
5、Air780EHM开发板和AirMICROSD_1010模块接线方式 | Air780EHM | AirMICROSD_1010 | | --------------- | --------------------- | | GND(任意) | GND | | VDD_EXT | 3V3 | | GPIO16/SPI0_CS | spi_cs | | SPI0_SLK | spi_clk,时钟 | | SPI0_MOSI | spi_mosi,主机输出,从机输入| | SPI0_MISO | spi_miso,主机输入,从机输出|
1、Luatools下载调试工具: https://docs.openluat.com/air780epm/common/Luatools/
2、内核固件版本: Air780EHM:https://docs.openluat.com/air780epm/luatos/firmware/version/ Air780EGH:https://docs.openluat.com/air780egh/luatos/firmware/version/ Air780EHV:https://docs.openluat.com/air780ehv/luatos/firmware/version/
1、搭建好硬件环境
2、通过Luatools将demo与固件烧录到核心板或开发板中
3、烧录好后,板子开机将会在Luatools上看到如下打印:
(1)TF卡初始化与挂载
[2025-08-24 19:51:24.152][000000001.389] SPI_HWInit 552:spi1 speed 2000000,1994805,154
[2025-08-24 19:51:24.213][000000002.390] D/fatfs init sdcard at spi=1 cs=20
[2025-08-24 19:51:24.286][000000002.390] SPI_SetNewConfig 996:spi1 speed 400000,400000
[2025-08-24 19:51:24.329][000000002.408] SPI_SetNewConfig 996:spi1 speed 24000000,25600000
[2025-08-24 19:51:24.383][000000002.408] D/SPI_TF 卡容量 122138624KB
[2025-08-24 19:51:24.430][000000002.408] D/SPI_TF sdcard init OK OCR:0xc0ff8000!
[2025-08-24 19:51:24.477][000000002.412] I/user.fatfs.mount 挂载成功 0
[2025-08-24 19:51:24.535][000000002.617] I/user.fatfs getfree {"free_sectors":244262144,"total_kb":122132480,"free_kb":122131072,"total_sectors":244264960}
[2025-08-24 19:51:24.583][000000002.618] I/user.fs lsmount [{"fs":"ec7xx","path":""},{"fs":"inline","path":"\/lua\/"},{"fs":"ram","path":"\/ram\/"},{"fs":"luadb","path":"\/luadb\/"},{"fs":"fatfs","path":"\/sd"}]
(2)文件操作演示
[2025-08-24 19:51:24.685][000000002.619] I/user.文件操作 ===== 开始文件操作 =====
[2025-08-24 19:51:25.145][000000003.032] I/user.io.mkdir 目录创建成功 路径:/sd/io_test
[2025-08-24 19:51:25.231][000000003.043] I/user.文件创建 文件写入成功 路径:/sd/io_test/boottime
[2025-08-24 19:51:25.297][000000003.046] I/user.io.exists 文件存在 路径:/sd/io_test/boottime
[2025-08-24 19:51:25.376][000000003.049] I/user.io.fileSize 文件大小:41字节 路径:/sd/io_test/boottime
[2025-08-24 19:51:25.467][000000003.052] I/user.文件读取 路径:/sd/io_test/boottime 内容:这是io库API文档示例的测试内容
[2025-08-24 19:51:25.547][000000003.056] I/user.启动计数 文件内容: 这是io库API文档示例的测试内容 十六进制: E8BF99E698AF696FE5BA93415049E69687E6A1A3E7A4BAE4BE8BE79A84E6B58BE8AF95E58685E5AEB9 82
[2025-08-24 19:51:25.616][000000003.056] I/user.启动计数 当前值: 0
[2025-08-24 19:51:25.693][000000003.057] I/user.启动计数 更新值: 1
[2025-08-24 19:51:25.736][000000003.068] I/user.文件写入 路径:/sd/io_test/boottime 内容: 1
[2025-08-24 19:51:25.795][000000003.081] I/user.文件创建 路径:/sd/io_test/test_a 初始内容:ABC
[2025-08-24 19:51:25.852][000000003.088] I/user.文件追加 路径:/sd/io_test/test_a 追加内容:def
[2025-08-24 19:51:25.909][000000003.091] I/user.文件验证 路径:/sd/io_test/test_a 内容:ABCdef 结果: 成功
[2025-08-24 19:51:25.954][000000003.102] I/user.文件创建 路径:/sd/io_test/testline 写入3行文本
[2025-08-24 19:51:26.001][000000003.106] I/user.按行读取 路径:/sd/io_test/testline 第1行: abc
[2025-08-24 19:51:26.048][000000003.106] I/user.按行读取 路径:/sd/io_test/testline 第2行: 123
[2025-08-24 19:51:26.093][000000003.107] I/user.按行读取 路径:/sd/io_test/testline 第3行: wendal
[2025-08-24 19:51:26.140][000000003.112] I/user.os.rename 文件重命名成功 原路径:/sd/io_test/test_a 新路径:/sd/io_test/renamed_file.txt
[2025-08-24 19:51:26.188][000000003.116] D/fatfs f_open /io_test/test_a 4
[2025-08-24 19:51:26.238][000000003.116] D/vfs fopen /sd/io_test/test_a r not found
[2025-08-24 19:51:26.312][000000003.117] I/user.验证结果 重命名验证成功 新文件存在 原文件不存在
[2025-08-24 19:51:26.367][000000003.117] I/user.目录操作 ===== 开始目录列举 =====
[2025-08-24 19:51:26.424][000000003.121] I/user.fs lsdir [{"name":"boottime","size":0,"type":0},{"name":"testline","size":0,"type":0},{"name":"renamed_file.txt","size":0,"type":0}]
[2025-08-24 19:51:26.478][000000003.127] I/user.os.remove 文件删除成功 路径:/sd/io_test/renamed_file.txt
[2025-08-24 19:51:26.539][000000003.129] D/fatfs f_open /io_test/renamed_file.txt 4
[2025-08-24 19:51:26.593][000000003.130] D/vfs fopen /sd/io_test/renamed_file.txt r not found
[2025-08-24 19:51:26.656][000000003.130] I/user.验证结果 renamed_file.txt文件删除验证成功
[2025-08-24 19:51:26.734][000000003.137] I/user.os.remove testline文件删除成功 路径:/sd/io_test/testline
[2025-08-24 19:51:26.856][000000003.139] D/fatfs f_open /io_test/testline 4
[2025-08-24 19:51:26.922][000000003.140] D/vfs fopen /sd/io_test/testline r not found
[2025-08-24 19:51:27.113][000000003.140] I/user.验证结果 testline文件删除验证成功
[2025-08-24 19:51:27.197][000000003.147] I/user.os.remove 文件删除成功 路径:/sd/io_test/boottime
[2025-08-24 19:51:27.251][000000003.149] D/fatfs f_open /io_test/boottime 4
[2025-08-24 19:51:27.302][000000003.150] D/vfs fopen /sd/io_test/boottime r not found
[2025-08-24 19:51:27.365][000000003.150] I/user.验证结果 boottime文件删除验证成功
[2025-08-24 19:51:27.407][000000003.158] I/user.io.rmdir 目录删除成功 路径:/sd/io_test
[2025-08-24 19:51:27.461][000000003.159] D/fatfs f_open /io_test 4
[2025-08-24 19:51:27.536][000000003.159] D/vfs fopen /sd/io_test r not found
[2025-08-24 19:51:27.610][000000003.159] I/user.验证结果 目录删除验证成功
[2025-08-24 19:51:27.668][000000003.160] I/user.文件操作 ===== 文件操作完成 =====
[2025-08-24 19:51:27.712][000000003.160] I/user.系统清理 开始执行关闭操作...
[2025-08-24 19:51:27.772][000000003.160] I/user.文件系统 卸载成功
[2025-08-24 19:51:27.867][000000003.160] I/user.SPI接口 已关闭
(3)网络连接与HTTP下载
[2025-08-24 20:31:49.405][000000006.268] I/user.HTTP下载 开始下载任务
[2025-08-24 20:31:49.438][000000006.275] dns_run 674:gitee.com state 0 id 1 ipv6 0 use dns server2, try 0
[2025-08-24 20:31:49.471][000000006.277] D/mobile TIME_SYNC 0
[2025-08-24 20:31:49.503][000000006.297] dns_run 691:dns all done ,now stop
[2025-08-24 20:31:54.800][000000012.080] I/user.HTTP下载 下载完成 success 200
[2025-08-24 20:31:54.872][000000012.080] {"Age":"0","Cache-Control":"public, max-age=60","Via":"1.1 varnish","Transfer-Encoding":"chunked","Date":"Sun, 24 Aug 2025 12:31:49 GMT","Access-Control-Allow-Credentials":"true","Vary":"Accept-Encoding","X-Served-By":"cache-ffe9","X-Gitee-Server":"http-pilot 1.9.21","Connection":"keep-alive","Server":"ADAS\/1.0.214","Access-Control-Allow-Headers":"Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With,X-CustomHeader,Content-Range,Range,Set-Language","Content-Security-Policy":"default-src 'none'; style-src 'unsafe-inline'; sandbox","X-Request-Id":"1f7e4b55-53c8-440a-9806-8894aa823f50","Accept-Ranges":"bytes","Etag":"W\/\"6ea36a6c51a48eaba0ffbc01d409424e7627bc56\"","Content-Type":"text\/plain; charset=utf-8","Access-Control-Allow-Methods":"GET, POST, PUT, PATCH, DELETE, OPTIONS","X-Frame-Options":"DENY","X-Cache":"MISS","Set-Cookie":"BEC=1f1759df3ccd099821dcf0da6feb0357;Path=\/;Max-Age=126000"}
[2025-08-24 20:31:54.910][000000012.080] 411922
[2025-08-24 20:31:54.936][000000012.082] I/user.HTTP下载 文件大小验证 预期: 411922 实际: 411922
[2025-08-24 20:31:54.979][000000012.083] I/user.HTTP下载 资源清理完成