项目上需要做设备的远程升级更新程序,从而避免每次更新程序时都需要去现场烧录的麻烦。从而学习探索了RT提供的OTA功能。
RT-Thread 开发团队提供了通用的 Bootloader。开发者通过该 Bootloader 即可直接使用 RT-Thread OTA 功能,轻松实现对设备端固件的管理、升级与维护。" 引用于官方资料文档。
主要参考资料:
1.官方文档资料 https://www.rt-thread.org/document/site/application-note/system/rtboot/an0028-rtboot/
2.论坛网友制作中遇到的问题以及解决办法 https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=12241&highlight=boot
移植使用平台和工具:
STM32F103ZET6 512K FLASH 64K RAM (建议在FLASH小于256K 不外置SPI FLASH的情况下就别使用OTA了)
J-Flash V4.90 用于生成的烧录OTA固件
J-Link STM32 Unlock 有时自己误操作可能会导致芯片锁死,用于解锁芯片
Xshell 配置为串口,便于查看输出情况。其他的串口调试助手也可以,但是推荐Xshell, 因为RT的ulog输出支持各种格式,Xshell 显示更加直观。
获取Bootloader
这一点的描述在官方文档的描述已经非常详细,具体请认真阅读参看官网文档。只是需要注意自己在配置参数的部分,根据自己所需要进行配置相关参数。
以下是我keil5工程编译出来的一些情况:
Program Size: Code=105170 RO-data=13866 RW-data=1324 ZI-data=6316
由此可知 下载到FLASH中的大小 = Code + RO Data + RW Data = 117 K 。以下是我配置图。
我并没有使用外部FLASH,全部使用芯片内部的FLASH。也没有配置相依的固件恢复分区。而是只配置了app分区和download分区。其中app分区的偏移地址为0x10000,Bootloader实际是从0x8000000开始存储的,设置0x10000偏移地址实际是给Bootloader的固件预留了64K的空间(实际32K足以),所以app分区是从0x8010000起始,往后占用192K大小。同理download分区也一样,由于前面已经占用了256K空间(预留bootloader 64k + 192k app分区),所以偏移地址设置为0x40000。特别注意分区的设置合理性,很多bootloader不能使用大部分都是分区的原因。
关于官网上关于分区的设置,我开始疑惑了好久。最后我才发现自己被自己惯性思维误导了。
一直以为最开始设置的app就是第一个分区,其实不是关键还是看偏移地址。实际上,上面图片的第一个分区是download分区。
这部分剩下的跟着官网资料操作应该没什么问题了。
烧录 Bootloader
我使用的是J-FLASH,官网上还有使用 ST-LINK Utility 工具烧录的方法。由于官网上使用的J-FLASH版本有点高,自己是4.9版本的。所以小部分操作也不同,所以还是记录一下。就怕万一哪天我也忘了,直接上图。参考着官网资料上看吧。
这个时候 需要按快捷键F3 先进行对擦除芯片。再进行F5烧录程序即可。
如果中途报错或者失败。使用J-Link STM32 Unlock进行解锁后再进行重复操作。
烧录成功后连接上串口1 (PA9),使用xshell进行查看。如下就是成功烧录了bootloader。
按官网资料的操作,在ENV工具中开启相应的选项。
接下来是 配置 FAL 分区(这是重点),我之前在这里卡了挺久的。
这部分 和官网资料有些少部分操作不同,因为官网上是F4的芯片,和F1在FLASH 地址上有点点区别,F4芯片也是从0x8000000地址开始,但是前128K为保留。前128K不能用于分区配置,那我们只有用来装bootloader了。
这是时候的工程编译会报错,缺少相应的fal_cfg.h文件,这个文件需要自己手动添加进去。在自己的BSP目录下\packages\fal-latest\samples\porting中找到fal_cfg.h文件。我是按以下方法进行添加的。
在board文件夹中新建了一个ports文件,将\packages\fal-latest\samples\porting下面的全部拷贝过来。然后再添加路劲到SConscript脚本文件中去。添加内容如下:
再次编译依然会报错,这个时候我们需要修改fal_cfg.h的内容。
具体修改为如下:
第2项代表了程序启动运行地址,根据前面的设置 app 地址为0x08010000 (重点)
第4项中是我们在第一节网页上设置的分区表,按照对应的设置即可。
"bl" 为保留分区 从地址大小0开始(实际为0x8000000),保留分区大小为64K,用于存放bootloader。
"app" 分区 和 "download"分区依次论推。
修改 app 固件配置
由于 app 分区的起始地址为 0x08010000,app 固件如果想运行在该地址,就需要修改链接脚本和中断向量的跳转地址。
1.修改链接脚本地址
2.修改中断向量的跳转地址
这部分和官网资料一致,借鉴下官网图片。修改中断向量表的跳转基地址为 0x8010000。
首先在 main.c 文件中添加如下代码,这段代码的功能是重新设定中断向量跳转地址为 app 分区的地址。
/**
* Function ota_app_vtor_reconfig
* Description Set Vector Table base location to the start addr of app(RT_APP_PART_ADDR).
*/
static int ota_app_vtor_reconfig(void)
{
#define NVIC_VTOR_MASK 0x3FFFFF80
/* Set the Vector Table base location by user application firmware definition */
SCB->VTOR = RT_APP_PART_ADDR & NVIC_VTOR_MASK;
return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);
然后在 main 函数中添加版本信息打印,如下图所示:
之前忘记了添加 fal的初始化,如上添加进去。我自己的配置如下
接下来编译下载程序。
固件就会被烧录到 app 分区。Bootloader 启动后将跳转到 app 分区运行,如下图所示:看到了打印的版本号是1.0.0
剩下的部分采用xshell进行发送固件升级,就不在累述了,跟着官网文档操作一步一步来就可以成功。实现界面如下,看到已经成功升级为AIS 2.0.0版本了。另外官网还提供了中HTTP/HTTPS的升级方法,我也准备使用这种,还在探索中。。。不过原理和上述的方法大致相同。
不过,bootloader RT并没有开源。只能用,看不到源码。
但是,好消息是 有网友大神Spunky 制作了个,还弄成了软件包,留下个论坛链接地址。此等大佬,只有膜拜。。。
https://www.rt-thread.org/qa/thread-422812-1-1.html
2020.2.22 附加
采用HTTP的形式+Air720H 4G模块 进行远程升级的方法可以参考这篇博文。https://blog.csdn.net/ylzmm/article/details/104315914