IAP代码升级
目录
[STM32 正常的程序运行流程(程序是存在flash中的)](#STM32 正常的程序运行流程(程序是存在flash中的))
回顾
-- lvgl字库操作:
-
会出现程序死和不显示的问题
-
不显示的问题出现的原因:字库没有写进去,标签的字体没有修改
-
程序死的问题:flash初始化一定要在lvgl之前.
任务间通信有没有创建
--
IAP(代码升级)
- 在线升级:OTA升级
- 离线升级: IAP升级(串口)
-- 为什么会有代码升级?
- 产品一旦生产出来,有些产品是没有留下载接口。如果程序更新了,如何将升级后的代码,下载进产品中。
-- 代码升级分为两种,
一种是IAP(本地升级):如USART,RS485,USB(这里的usb指的是通信方式)等等 都可以作为升级接口
OTA(在线升级):一般用到云服务器
- 他们的区别在于:获取代码的方式不一样。
-- 代码编译之后,会生成一个bin文件,这个bin文件,就是我们要升级的代码。
- 那么如果是OTA升级,我们只需要将bin文件放到云服务器上。(我们使用的阿里云服务器上就有一个OTA升级)
- 如果是IAP升级,我们只需要将bin文件放到串口设备上,然后通过串口,将bin文件下载到产品中。
-- 那么如何去实现这个升级呢?
-- 首先我们要先了解单片机的运行流程
-- 单片机到底是怎么启动的
- 单片机程序的启动是从哪开始启动的(看数据手册中的)是从0x00000000开始启动的
-- 我们的程序是保存在flash(512kb)中的,那我们如何从0x0000 0000跳到flash中呢?
- 根据boot的值选择启动区域,是根据BOOT0和BOOT1控制跳转到哪里
-- 串口下载工具就有让我们选择
tip:三种boot启动模式
- 一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
- 1、第一种方式(boot0 = 0):Flash memory启动方式
启动地址:0x08000000 是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。基本上都是采用这种模式。
-- 已知我们单片机的原理图,boot0接地,恒定为0
- 2、第二种方式(boot0 = 1;boot1 = 0):System memory启动方式
启动地址:0x1FFF0000从系统存储器启动,这种模式启动的程序功能是由厂家设置的。一般来说,这种启动方式用的比较少。系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader, 也就是我们常说的ISP程序, 这是一块ROM,出厂后无法修改。一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader 中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。但是这个下载方式需要以下步骤:
1、将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader2、最后在BootLoader的帮助下,通过串口下载程序到Flash中
3、程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动可以看到, 利用串口下载程序还是比较的麻烦,需要跳帽跳来跳去的,非常的不注重用户体验。
- 3、第三种方式(boot0 = 1;boot1 = 1):SRAM启动方式。 启动地址:0x20000000 内置SRAM,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的 地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。
STM32 正常的程序运行流程(程序是存在flash中的)
-- 首先是从栈顶位置,然后是中断向量表,之后是中断的入口函数,之后是main函数
-- 中断向量表是什么?
-- 后面还是主函数的入口程序和中断的入口函数
-- 当中断发生的时候,先去中断向量表起始点, 找到底是哪个中断发生的,然后去中断服务函数中执行响应的操作
-- 这就是为什么说有过两个中断优先级相同,那么先执行哪个中断?谁在前面谁先执行。为什么?
- 因为他是在中断向量表一个一个向下遍历的,排在前面的就先执行
-- 如果没有写中断服务函数
-- 后面还有设置堆区栈区的大小
代码升级
-- 那么如何进行代码升级?
我们要进行代码升级是不是还要获取更新过后的代码。所以我们要想怎么获取.
-- 首先了解如果将程序不下载到起始位置怎么做。(默认是下载到起始地址(0x8000000))
-- 所以我们可以改起始地址之后试一下
-- 之后要擦除FLASH
-- 打开软件之后点击连接,当前芯片flash的内部数据,然后选择橡皮擦擦除,擦除完之后都变成FFFF。
-- 注意:擦除完之后要断开连接,断开连接的标识就在连接的旁边,然后再去烧程序,如果程序设定的大小不够,可以加一点(可以加到0x60000),然后重新烧录。
-- 烧录之后重新连接,可以看到前面的地址都没有数据,并且可以发现程序运行不了,因为程序没有下载到起始地址。
-- 那么是不是可以再写一段程序,将程序下载到起始地址呢?
-- 程序的内容就判断有没有更新,如果没有更新,就跳转到正常运行的程序去,如果有更新,就要把当前的程序擦除掉,擦掉之后将w25q64存的代码放进来,移植完之后就变成更新过后的程序了。
更新过后的程序存在w25q64中,所以我们要先去获取w25q64中的数据,然后下载到flash中。因为存在w25q64中的程序是不能跑的。那么怎么将w25q64上的程序下载进内部flash中,首先我们要想下载进flash,肯定要先擦除flash。
-- 总共有两个工程,一个工程是判断程序有没有更新,另一个工程是主工程,主工程的功能就是接收新代码,然后保存到w25q64中,并将flash的其中一个区域赋一个特定的值,起标识位的作用,工程1可以通过检测这个区域是不是这个值来判断程序有没有更新。
-- 两个工程(代码的大小大于falsh一半的情况)
-
工程1:引导工程:检测代码是否存在更新;
如果有更新,需要擦除原代码空间,然后将新代码放入
如果没有更新,不做操作,直接执行工程2
-
工程2:主工程:空气质量检测仪的功能,接收新代码,保存到w25q64里面
-- 如果代码的大小小于flash一半
-
工程1:引导工程:检测代码是否存在更新;
如果有更新,需要擦除原代码空间,然后将新代码放入
如果没有更新,不做操作,直接执行工程2
-
工程2:主工程:空气质量检测仪的功能,接收新代码,保存到flash里面
实例:代码小于flash的一半时
-- 找一个官方代码当作例子:资料里的代码是小于flash的一半
- 该工程是将flash分成了三块区域:分别是boot区域,app1,app2.
-- 这个boot区域就是上面所说的工程1,app1区域就是工程2,app2区域是用于把偶才能新工程(升级过后的代码)的地方
-- 那么具体是怎么实现的?
- 首先打开一个boot工程(注意一定不要选择全面擦除,选块擦除)
-- 注意:程序的跳转代码是固定写法
-- 然后再看app1工程,注意要先下载boot程序,再下载app程序。
-- 如果APP的代码使用下载器下载,那么我们就需要修改下载的属性,如下图所示:
-- 那么如何测试代码升级呢?
- 需要更改app中的代码,然后获取更新过后的bin文件,那么这个更新文件如何获取?需要修改配置属性,工程中有一个bin文件生成器。
-- 需要将地址改为自己工程bin文件生成器所在的路劲:D:\Keil_v5\Arm\ARMCC\bin\fromelf.exe --bin -o .\Objects\weather.bin .\Objects\weather.axf
其中:D:\Keil_v5\Arm\ARMCC\bin\fromelf.exe 是一个keil自带的生成bin文件的工具绝对路径。
通过这一步设置,我们就可以在 MDK 编译成功之后,调用 fromelf.exe(注意,我的 MDK 是安装在 D盘文件夹下,如果你是安装在其他目录,请根据你自己的目录修改fromelf.exe 的路径),根据当前工程的 weather.axf(如果是其他的名字,请记住修改,这个文件存放在 Objects 目录下面,格式为 xxx.axf),生成一个 RTC.bin 的文件。并存放在 axf 文件相同的目录下,即工程的 Objects 文件夹里面。在得到.bin 文件之后,我们只需要将这个 bin 文件传送给单片机,即可执行 IAP 升级。(我们也可以将bin文件无线发送,存放在SD卡内,存放在外部FLASH内等等方式进行代码升级,其中无线发送的形式叫OTA)。
我们把APP2生成的bin文件,通过串口,发送到APP1的运行设备上,就会自动的保存APP2的代码数据到对应的Flash地址下,那么按下复位按键后(也可以软件复位),再次运行bootloader代码,就会加载APP2的数据到APP1的地址下,并运行新的程序。
-- 编译之后就会生成一个bin文件,将这个文件放在桌面上
-- 程序在运行的时候点击发送bin文件
如果想清楚的看到程序运行的结果,可以实现程序接收到bin文件后就立马复位,所以要在程序更新的后面写一个软件复位的代码。
NVIC_SystemReset();//软件复位
-- OTA升级与IAP升级类似,可以尝试一下,主要就是代码是怎么获取的。