OTA升级
转载自https://blog.csdn.net/weixin_43866583/article/details/127706079?spm=1001.2014.3001.5502
OTA 在线升级
OTA:Over-the-Air Technology,字面意思理解为:空中下载技术。
OTA 在线升级:通过OTA的方式实现产品软件更新的一种方式。
所以,简单而言,通过外部的方式(有线 / 无线)对产品进行更新,而不是用传统的编程器刷入固件的方式就可以称之为 OTA 在线升级。
严格意义上来讲,OTA 指的是空中下载,即只有通过无线的方式进行更新的才称之为 OTA 升级;而那种通过外部的接口接线来实现的更新,应该称之为本地升级。这两者还是有点区别的,只是一般我们都没有那么严格去区分罢了!
实现方式
1)接收新的升级固件并完成新旧固件的替换,这部分代码为 BootLoader;
2)产品功能的正常程序,用于执行各种应用功能,这部分程序称为 App。
那就是说,要实现在线升级,就需要准备两份程序,一份是BootLoader ,另一份是App。其中 bootloader 用于将外部传入的新固件(应用程序App)接收到内部并存储,接收完成以后,由 bootloader 用新接收到的固件去替换旧的固件,替换完成之后跳转到新的应用程序中进行执行。这样就完成了产品的固件更新。
后台式升级
后台式升级的意思是:在进行升级的时候,接收新固件包的方式是在后台进行的,不会影响功能的正常执行。等到固件更新完成之后,再跳转到Bootloader中去用新的固件替换旧的固件,替换完成之后呢再跳转到App去执行。
比如,现在的智能手机的在线更新就是后台式升级的方式。在你升级系统的时候,接收升级包的过程中,你还是可以正常使用的手机的,打电话、看视频、玩游戏等都不耽误,直到下载完成,你点击了开始更新之后,手机才进入更新状态,不让你操作,等更新完毕之后重启就又可以继续操作了。
非后台式式更新
非后台式升级的意思是:在进行升级的时候,接收固件时需要跳转到Bootloader,这个时候你不能在使用这个产品的任何功能,只能一直等着它接收并完成更新,完成之后你才能继续操作其他的功能。
STM32 的在线升级
划分 Flash 区域
要准备两份代码的,一份是BootLoader,另外一份是App。由于这两份代码在STM32中都是要存放在Flash中的,而且它们的空间还不能重叠,要独立区分开
(1)用于存放Bootloader程序;
(2)用于存放应用程序;
(3)用于存放接收到的新固件。(注:这部分可要可不要,根据你的设计选择)
注意:上图中(3)这个Flash区域是考虑用于保存在线升级的固件的,作为备份固件。方便用于以后系统出现异常时,可以从这个备份固件中重新加载到App中,防止固件丢失!
1 - Flash空间地址的划分
首先,我们要知道,在stm32中,flash的地址空间是从0x08000000开始的,在keil中也是默认的从这个位置开始的。
一般而言,Bootloader 是在上电时默认开始执行,因此将Bootloader程序可以存放到STM32默认执行的位置(keil编译器默认从0x08000000地址开始存放)。
应用程序从 Bootloader 后开始存放即可,只要不和BootLoader发生冲突即可。
假设 Bootloader 的大小为10k,即0x2800字节,那么可以选取 0x08000000 ~ 0x08002800 地址范围作为BootLoader的存放区域。
应用程序从0x08005000开始存放
2 - 设置工程
设置起始地址和大小
准备两个工程,一个是bootloader的程序,另外一个是应用程序的工程,并对工程进行设置。bootloader选择默认执行的位置,应用程序根据实际需要设置开始存放到flash指定的位置。
比如:App的起始地址设为0x08005000,大小设为0x1B000(RAM总大小0x20000-0x5000)
BootLoader 也是一样的设置方式,只是地址不同而已。
生成 bin 文件
应用程序需要转换为bin文件才可以写入Flash中,能发送到产品中的固件也是要先转为bin格式的文件的
编译器可以选择生成hex文件,再把hex文件转换为bin文件
还可以使用简单方法,编译后直接执行fromelf.exe命令将.axf文件转换为.bin文件。生成的bin文件在工程目录下的out文件夹下
3 - 接收固件更新包
接收固件更新包的话,就要根据你的实际产品进行选择了。
首先,如果你是后台式更新的话,那接收固件更新包的功能就要在App中实现;如果你是非后台式更新的话,那接收固件更新包的功能就要在BootLoader中实现。
其次,要考虑接收固件更新包的方式。无线的话用的是wifi、蓝牙、4/5G网络还是啥的;有线的话用的是串口UART、Spi、IIC、CAN、以太网还是啥的。
最后,最好的方式是能够对接收到的固件更新包做一个校验,防止数据接收过程中出现错误,导致升级后出现严重问题。
注意:BootLoader 需要提前刷入,不然无法完成在线升级!
4 - 拷贝程序至Flash
接收成功固件包之后,需要将数据写入到 Flash 的指定位置(比如 0x08005000)完成固件的更新程序写入。
STM32对Flash的操作过程如下:
1 |
|
5 - 跳转至 App 应用程序
将接收到应用程序全部正确写入Flash的App指定位置后,Bootloader 需要完成跳转到应用程序App的开始位置的操作。
1 |
|
特别注意 - 设置向量中断表偏移
这个跳转到用程序之后,有一个非常重要的事情要注意,就是要重新设置App的中断向量表,否则不能正常运行的。
STM32的内部闪存(FLASH)的地址默认是从0x8000000开始的,默认也是从这个位置开始执行程序的。并且在STM32的内部有一张 “中断向量表” 用于响应中断,程序在启动以后首先会从中断向量表取出复位中断程序,执行完复位中断程序以后才会跳转到main( )函数开始执行。
中断向量表的位置从0x8000004开始,如果采用的是bootloader和应用程序的方式的话,bootloader一般放在默认开始的位置,所以它的中断向量表还是正确的。
而APP应用程序是放置在其他的位置,那么APP应用程序部分的中断向量表就要发生偏移,才能为应用程序找到并响应中断。
在应用程序中,与程序跳转需要注意的是,单片机从Bootloader程序跳转至应用程序的复位向量处开始执行,单片机在执行main函数之前会执行一些系统初始化程序