IAP升级

IAP代码升级

目录

IAP代码升级

回顾

IAP(代码升级)

tip:三种boot启动模式

[STM32 正常的程序运行流程(程序是存在flash中的)](#STM32 正常的程序运行流程(程序是存在flash中的))

代码升级

实例:代码小于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,然后按下复位键,这样才能从系统存储器启动BootLoader

2、最后在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升级类似,可以尝试一下,主要就是代码是怎么获取的。

相关推荐
7yewh2 小时前
嵌入式硬件杂谈(四)-高速板PCB设计 高速信号全面讲解 蛇形线 等长线 差分对 阻抗对
驱动开发·嵌入式硬件·mcu·物联网·硬件工程·pcb工艺·精益工程
linux_carlos15 小时前
#lwIP 的 Raw API 使用指南
stm32·单片机·mcu·物联网·rtdbs
liu_endong19 小时前
杰发科技AC7840——EEP中RAM的配置
mcu·杰发科技·autochips·车规芯片
King~30+19 小时前
STM32--中断使用(超详细!)
stm32·单片机·嵌入式硬件·mcu
网易独家音乐人Mike Zhou20 小时前
【Linux驱动开发】irq中断配置API及中断应用 阻塞休眠和非阻塞的驱动操作
linux·c语言·驱动开发·stm32·单片机·mcu·iot
7yewh1 天前
嵌入式硬件电子电路设计(七)稳压二极管-齐纳二极管-齐纳击穿全面详解
stm32·嵌入式硬件·mcu·物联网·硬件架构·硬件工程·pcb工艺
7yewh2 天前
嵌入式硬件实战基础篇(二)-稳定输出3.3V的太阳能电池-无限充放电
stm32·嵌入式硬件·mcu·物联网·硬件架构·硬件工程·pcb工艺
7yewh2 天前
嵌入式硬件杂谈(三)-高速PCB入门,什么是阻抗匹配?
嵌入式硬件·mcu·物联网·硬件架构·硬件工程·pcb工艺·精益工程
7yewh3 天前
LeetCode 力扣 热题 100道(五)最长回文子串(C++)
c语言·开发语言·c++·mcu·算法·leetcode
ShiinaKaze4 天前
【STM32】USB 简要驱动软件架构图
stm32·单片机·mcu·usb