赞
踩
作者:KK
上期回顾:(点此连接跳转),上期介绍了如何利用RT-Thread系统同步网络时间和天气预报到UI上,本期将介绍一下如何通过SD卡和ymodem串口升级固件。
1.固件升级演示:
固件升级在第三个界面,已经提前把待升级的固件和图片bin文件放在了SD卡里,升级前软件版本为V1,升级后软件版本为V2,并且更改了表盘,升级完成后,会记录升级的时间,详细请看视频演示:
2.命令行演示:
命令行添加了更多功能,不仅可以通过命令行升级固件,还可以把sd卡中的图片文件复制到spi flash中,命令行的更多功能,欢迎下载源代码体验。
DFS( Device File System)是一种抽象的文件机制,RT-Thread中对文件系统的相关操作实际上都是通过操作DFS实现,也就是说DFS是对各种文件系统的抽象。DFS使的其他部分无须关心不同文件系统之间的差异,使得RT-Thread可以支持多种类型的文件系统。
RT-Thread DFS 组件的主要功能特点有:
为应用程序提供统一的 POSIX 文件和目录操作接口:read、write、poll/select 等。
支持多种类型的文件系统,如 FatFS、RomFS、DevFS 等,并提供普通文件、设备文件、网络文件描述符的管理。
支持多种类型的存储设备,如 SD Card、SPI Flash、Nand Flash 等。
DFS 的层次架构如下图所示,主要分为 POSIX 接口层、虚拟文件系统层和设备抽象层。
FatFs 是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。
初始化 DFS 组件。
初始化具体类型的文件系统。
在存储器上创建块设备。
格式化块设备。
挂载块设备到 DFS 目录中。
当文件系统不再使用,可以将它卸载
elm-FAT文件系统注册过程如下图所示:
- 1void sd_mount(void *parameter)
- 2{
- 3 while (1)
- 4 {
- 5 rt_thread_mdelay(500);
- 6 if(rt_device_find("sd0") != RT_NULL)
- 7 {
- 8 if (dfs_mount("sd0", "/fatfs", "elm", 0, 0) == RT_EOK)
- 9 {
- 10 LOG_I("sd card mount to '/fatfs'");
- 11 break;
- 12 }
- 13 else
- 14 {
- 15 LOG_W("sd card mount to '/fatfs' failed!");
- 16 }
- 17 }
- 18 }
- 19}
- 20
- 21int stm32_sdcard_mount(void)
- 22{
- 23 rt_thread_t tid;
- 24
- 25 tid = rt_thread_create("sd_mount", sd_mount, RT_NULL,
- 26 1024, RT_THREAD_PRIORITY_MAX - 2, 20);
- 27 if (tid != RT_NULL)
- 28 {
- 29 rt_thread_startup(tid);
- 30 }
- 31 else
- 32 {
- 33 LOG_E("create sd_mount thread err!");
- 34 }
- 35 return RT_EOK;
- 36}
- 37INIT_APP_EXPORT(stm32_sdcard_mount);

在文件系统操作表中找出elm文件系统
检查"/fatfs"路径是否存在
检查elm文件系统是否已经挂载在文件系统表中
检查文件系统表是否有空余,如果有,把空余地址指向elm文件系统
注册文件系统
调用elm文件系统的挂载接口
在根目录下使用ls命令,可以查看目录:
使用TouchGFX 4.14.0 Designer添加设置界面。增加进度条,和两个按钮,以及固件版本和更新时间的记录(记录环境变量使用的是easyflash软件包)。我这个界面设计的比较简陋,重在实现功能,审美好的人,欢迎重新设计这个界面。
- 1bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)
- 2{
- 3 uint32_t dataOffset = (uint32_t)src;
- 4 if (dataOffset >= 0x90000000 && dataOffset < 0x92000000)
- 5 {
- 6 char *updata_pciture;
- 7
- 8 /* get the updata pciture location from Env */
- 9 updata_pciture = ef_get_env("updata_pciture");
- 10
- 11 if(0 == strcmp(updata_pciture, "spi_flash"))
- 12 {
- 13 const struct fal_partition *part;
- 14 part = fal_partition_find("tgfx");
- 15
- 16 dataOffset = dataOffset - 0x90000000;
- 17 // for copying data from there.
- 18 if (part != RT_NULL)
- 19 {
- 20 fal_partition_read(part, dataOffset, (uint8_t *)dest, numBytes);
- 21 }
- 22 return true;
- 23 }
- 24 else
- 25 {
- 26 int fd;
- 27 struct statfs buffer;
- 28 if(rt_device_find("sd0") != RT_NULL)
- 29 {
- 30 if ((dfs_statfs("/",&buffer) == RT_EOK)|(dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK))
- 31 {
- 32 fd = open("/ER_EROM1", O_RDONLY, 0);
- 33 if (fd < 0)
- 34 {
- 35 rt_kprintf("open file for read failed\n");
- 36 return false;
- 37 }
- 38 dataOffset = dataOffset - 0x90000000;
- 39 lseek(fd, dataOffset, SEEK_SET);
- 40 // for copying data from there.
- 41 read(fd, (uint8_t *)dest, numBytes);
- 42 close(fd);
- 43 }
- 44 return true;
- 45 }
- 46 else
- 47 {
- 48 return false;
- 49 }
- 50 }
- 51 }
- 52 else
- 53 {
- 54 // For all other addresses, just use the default implementation.
- 55 // This is important, as blockCopy is also used for other things in the core framework.
- 56 return HAL::blockCopy(dest, src, numBytes);
- 57 }
- 58}

此代码用来根据设置的环境变量选择从sd卡还是spi flash拷贝图片。
- 1#ifdef RT_USING_FINSH
- 2#include <finsh.h>
- 3/* export to finsh */
- 4FINSH_FUNCTION_EXPORT(ReadUpdataToSpiflash, Read data To Spiflash test);
- 5
- 6#ifdef FINSH_USING_MSH
- 7static void cmd_updata(int argc, char *argv[])
- 8{
- 9 char* filename;
- 10
- 11 if(argc == 2)
- 12 {
- 13 filename = argv[1];
- 14 }
- 15 else
- 16 {
- 17 filename = DEFAULT_FILENAME;
- 18 recv_partition = DEFAULT_DOWNLOAD_PART;
- 19 LOG_I("Default save firmware on download partition.\n");
- 20 }
- 21 ReadUpdataToSpiflash(filename);
- 22}
- 23FINSH_FUNCTION_EXPORT_ALIAS(cmd_updata, __cmd_updata, Read data To Spiflash test);
- 24#endif /* FINSH_USING_MSH */
- 25#endif /* RT_USING_FINSH */

添加msh命令,使通过msh命令也能升级固件,将SD的图片资源拷贝到spi flash的功能
在keil中添加以下命令,然后便会在binary目录下,生成外部flash和内部flash的bin文件:
参考以下文章:STM32通用Bootloader——FOTA
rt_fota集成了ymodem的协议,在没有app的情况下,也可以通过rt_fota的ymodem命令给固件和图片资源升级。
ymodem_ota命令,默认将固件下载到download分区:
代码开源地址:https://gitee.com/Aladdin-Wang/hellotouchGFX
<插播一句:9月1日RT-Thread将在北京举行发布会发布RT-Thread Smart混合微内核操作系统,欢迎报名来现场交流了解更多信息,观看微内核应用Demo>>
你可以添加微信17775982065为好友,注明:公司+姓名,拉进 RT-Thread 官方微信交流群!
RT-Thread
让物联网终端的开发变得简单、快速,芯片的价值得到最大化发挥。Apache2.0协议,可免费在商业产品中使用,不需要公布源码,无潜在商业风险。
长按二维码,关注我们
转一转
赞一赞
看一看
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。