01 什么是IAP升级?
IAP 升级是In - Application Programming升级的简称,指的是在嵌入式系统或设备的应用程序运行过程中,通过特定方式对设备的软件系统进行更新的一种方式。简单来说,就是设备在正常工作状态下,无需借助外部编程工具或拆除硬件,直接通过自身的软件程序完成系统升级。
02 单片机的启动流程
在学习IAP之前要先了解单片机的启动流程。
以下以STM32为例简单说明:
启动的硬件流程
电源上电与复位
当 STM32 单片机上电(或复位)时,硬件会执行以下操作:
初始化内部时钟源(通常先使用内部 RC 振荡器)。
从特定地址读取栈顶指针(SP)的初始值。
从紧接其后的地址读取程序计数器(PC)的初始值,即复位向量(Reset Handler)的地址。
启动的软件流程
1. 复位向量表
STM32 的 Flash 或其他存储器的起始地址存放着中断向量表,其中前两个条目固定为:
地址 0x00000000:栈顶指针(MSP - Main Stack Pointer)的初始值。
地址 0x00000004:复位向量(Reset Handler)的入口地址。
向量表的其他条目包含各种中断服务函数(ISR)的地址,如定时器中断、外部中断等。
2. 复位处理函数
复位向量指向的 Reset Handler 是启动过程的核心代码,通常包含以下步骤:
初始化栈指针:设置主栈(MSP)的初始值。
配置系统时钟:切换到外部晶振(HSE)或 PLL,提高系统时钟频率。
初始化数据段(.data):从 Flash 复制初始化变量到 RAM。
清零 BSS 段(.bss):将未初始化的全局变量清零。
调用用户代码入口(main ()):跳转到 C 代码的 main 函数。
3. 系统初始化
在进入 main () 之前,通常会调用SystemInit()
函数,该函数主要完成:
配置系统时钟(如设置 PLL 分频系数)。
启用外设时钟(如 GPIO、USART 等)。
配置 Flash 访问参数(如等待周期)。
03 启动流程与 IAP 的关系
理解 STM32 的启动流程是实现 IAP(在应用编程)的基础:
1.Bootloader 设计:需要自定义 Bootloader 程序,放置在 Flash 的起始区域,负责判断是否需要升级以及加载应用程序。
2.向量表重定位:当应用程序不位于 Flash 起始地址时,需要重定位向量表,确保中断正常工作。
3.跳转条件判断:Bootloader 需要检测升级标志(如特定文件或通信指令),决定是启动应用程序还是进入升级流程。
大体分为两部分设计,bootloader、APP的代码设计:
Bootloader:用于检查APP区代码是否需要更新,以及跳转到APP区执行APP程序;
APP:执行业务代码,实时接收并判断升级指令;
05 Flash分区
以STM32F103VET6为例
boot区:0x0800 0000 到 0x0800 2FFF 地址的flash块划分给bootloader,用于升级固件,大小是12kb(大小可以根据项目情况自己定义);
用户参数区:0x0800 3000 到 0x0800 37FF 的flash块划分为用户参数区,用于存储用户的一些参数,大小是2Kb(可以保存在APP升级标志位,大小可以根据项目情况自己定义);
APP_1区:0x0800 3800 到 0x0803 F7FF 的flash块划分为APP区 ,用于存放用户功能应用代码,大小是240Kb(大小可以根据项目情况自己定义);
APP_2区:0x0803F800 到 0x0807 B7FF 的flash块划分为APP缓存区 (update region),用于暂存下发的固件,大小跟应用程序区一样 240kb(大小可以根据项目情况自己定义);
未定义: 0x0807 B800 到 0x0807 FFFF 的flash块划分未定义区,可以根据具体用途定义,大小是18Kb(剩余未用);
1、内部flash读写
2、升级数据的接收(一般用串口接收或者CAN);
bootloader代码设计步骤:
扇区擦除,用于写入前擦除相应扇区;
升级标志获取与擦除;
获取升级标志如果业务正在执行的是APP_1区,就写入APP_2区;
获取升级标志如果业务正在执行的是APP_2区,就写入APP_1区;
(这样做的话即使升级失败,会去执行旧业务代码);
写入完成跳转到对应设置的APP程序的运行地址升级完成;
APP代码设计
APP代码是用户功能代码,实现业务逻辑,在APP代码中接收到升级命令,会自动重启到Bootloader,在Bootloader中更新APP区代码;
这里只需要在接收升级指令后运行跳转代码和配置中断向量表的地址即可;