一、IAP是什么?
IAP(In Application Programming,在应用编程)是一种技术,它允许在设备运行过程中通过软件对固件进行更新。这种更新方式不需要使用特殊的硬件编程器或者移除芯片,因此也被称为在线编程或空中下载技术(OTA, Over-The-Air)。IAP升级对于物联网设备、嵌入式系统等非常重要,因为它允许在产品部署后进行功能更新或修复错误。
二、为什么使用IAP?
如果芯片内没有程序的话,无法直接进行烧录。因此,在使用J-Link或其他编程器进行烧录代码时,通常情况下芯片中至少有一部分程序作为引导加载程序(Bootloader)。不过,需要注意的是,不是所有的芯片出厂时都带有内置的Bootloader。对于某些芯片,如STM32系列,它们可能包含了一个简单的Bootloader,但更多的是需要用户自己编写一个Bootloader来实现特定的固件升级功能。
当我们购置一块STM32芯片时,它可能不自带Bootloader。在实际的工业生产中,为了实现远程固件升级,我们需要自行编写一个Bootloader来升级应用程序代码(App Code)。Bootloader的主要任务是接收和验证固件更新数据,并将其写入到闪存中适当的位置。
Bootloader是一个小型程序,负责管理固件的更新过程。它通常包括检测更新、接收更新数据、验证数据完整性以及将新固件写入闪存等任务。App Code (User Application)是设备的主要功能实现部分,即用户编写的用于实现特定功能的代码。
在闪存flash的分区上,一般建议将闪存的前64KB用来存放Bootloader程序,这部分空间不会被应用程序覆盖,以确保Bootloader始终可用。剩余的空间则用于存放应用程序代码(App Code)和其他数据。
如下面的flashboot.jlink文件设置:
USB
si SWD
speed 4000
device R7FA6M4AD
r
erase 0x00 0xffff # 0xffff = 65535
loadfile Boot_V1.bin 0x0
r
go
quit
在实际应用中,Bootloader可能需要实现以下功能:
- 通过某种通信接口(如串口、USB、网络等)接收固件更新数据。
- 验证接收到的数据(如使用CRC校验、数字签名等)。
- 将验证过的固件数据写入到闪存的适当位置。
- 更新完成后,重启系统并跳转到新的应用程序代码开始执行。
三、怎么使用IAP升级
3.1 固件分区
一般情况下我们要先将内存划分为几个区域:Bootloader区、应用程序区、备份区、其他区。
- Bootloader区:存放Bootloader程序,负责启动过程和固件更新。
- 应用程序区:存放用户应用程序,即实际的功能代码。
- 备份区:可选,用于保存旧版本的应用程序或作为失败更新的回退选项。
- 其他分区:如配置数据区、安全区等,用于存储配置信息或安全相关数据。
在IAP升级的过程中,新的固件被下载到备用的应用程序区,然后进行算校验和或使用数字签名验证新固件的完整性和真实性。如果一切正常,引导加载程序会将控制权交给新的固件版本,使其成为下一个启动周期的主固件区。如果升级失败,设备可以回退到旧的固件版本,以保证基本功能不受影响。这样的分区设计有助于提高系统的稳定性和可靠性,同时简化了固件升级的过程。
3.2 Bootloader开发
首先要清楚Bootloader的主要职责包括:
- 启动流程:在系统复位或加电后,Bootloader应能正确地定位并加载应用程序。
- 自我更新:Bootloader能够更新自身以修复可能存在的bug或添加新功能。
- 应用程序更新:这是IAP升级的核心功能,Bootloader需要能够接收新版本的应用程序并将其写入闪存。
- 错误处理:在更新过程中出现任何错误时,Bootloader应能妥善处理,比如回退到旧版本。
接下来我们开始编写Bootloader。首先要对硬件进行初始化,Bootloader启动后,需要初始化必要的硬件资源,如时钟、GPIO等。再根据固件的布局调整中断向量表的位置。最后根据预先定义的分区信息,从闪存中加载应用程序并跳转到应用程序的入口点。
Bootloader需要支持某种通信协议(如UART、SPI、USB等),以便接收新版本的固件数据。在写入闪存前,还需要验证接收到的数据的完整性和合法性,再将验证过的固件数据写入备用的应用程序分区。成功更新后,Bootloader需要能够在下次启动时加载新版本的应用程序。
如果有备份分区,Bootloader需要能够在更新失败时切换到备份分区。并记录更新过程中的任何错误信息,以便调试。
以下是一个简化的Bootloader代码结构示例:
// 初始化硬件
void initHardware(void);
// 加载应用程序
void loadApplication(void);
// 更新应用程序
void updateApplication(const uint8_t* newApp, size_t size);
// Bootloader主函数
int main(void)
{
// 初始化硬件
initHardware();
// 检查是否有更新请求
if (updateRequested())
{
// 尝试更新应用程序
if (updateApplication(receivedAppData, receivedAppSize))
{
// 更新成功
// 重启设备
NVIC_SystemReset();
}
else
{
// 更新失败
// 可以选择回退到备份分区
loadBackupPartition();
}
}
else
{
// 没有更新请求,直接加载应用程序
loadApplication();
}
return 0;
}
3.3 通信接口配置
在IAP (In-Application Programming) 升级程序中,通信接口是用于数据传输的关键部分,它负责将新固件从主机(通常是PC或服务器)传输到目标设备。根据应用场景和目标平台选择最合适的通信接口。常见的通信接口包括:
- 串口 (UART):适合近距离、低速通信。
- USB:提供高速数据传输,兼容性强,广泛应用于各种设备。
- 以太网 (Ethernet):适用于需要高带宽和远程连接的应用场景。
- Wi-Fi:无线连接,适用于需要无线更新的应用场景。
- 蓝牙 (Bluetooth):适用于短距离无线通信,尤其是移动设备。
3.1.1 串口 (UART)
- 波特率:设置适当的波特率以匹配两端的通信速度。
- 数据位:通常为8位。
- 停止位:通常为1位。
- 奇偶校验:可选,取决于通信要求。
- 流控:可选,如果需要避免数据溢出。
3.1.2 USB
- 端点配置:定义数据传输的端点。
- 最大包大小:根据USB设备的能力设定。
- 设备类:选择适当的USB设备类(如CDC、HID等)。
3.1.3 以太网 (Ethernet)
- IP地址:为设备分配固定的IP地址。
- 子网掩码:设置子网掩码以确定网络范围。
- 网关:指定默认网关。
- DNS服务器:可选,用于解析域名。
3.1.4 Wi-Fi
- SSID:选择Wi-Fi网络的名称。
- 密码:输入Wi-Fi网络的密码。
- 加密类型:如WPA2等。
- IP配置:静态或动态IP地址。
3.1.5 蓝牙 (Bluetooth)
- 服务UUID:定义蓝牙服务的唯一标识符。
- 特征UUID:定义用于数据传输的特征。
- 连接配置:设置连接参数,如最大MTU等。
在实现通信协议上,需要定义协议的格式,其中包括起始标志、数据长度、数据包内容、校验和或CRC等,还需要定义错误码和重试机制来进行错误处理。
以下是一个简化的示例,展示如何在主应用程序中配置串口通信接口:
#include <stdio.h>
#include "uart.h" // 假设这是一个用于串口通信的库
// 初始化串口
void initSerial() {
// 设置波特率为115200
uart_init(UART_PORT, 115200);
// 设置数据位为8位
uart_set_databits(UART_PORT, UART_DATA_8_BITS);
// 设置停止位为1位
uart_set_stopbits(UART_PORT, UART_STOP_1_BIT);
// 禁用奇偶校验
uart_set_parity(UART_PORT, UART_PARITY_DISABLE);
// 禁用流控
uart_set_flowcontrol(UART_PORT, UART_FLOWCONTROL_DISABLE);
}
// 发送数据
void sendData(const char *data) {
uart_write(UART_PORT, data, strlen(data));
}
// 接收数据
void receiveData(char *buffer, size_t length) {
uart_read(UART_PORT, buffer, length);
}
int main() {
initSerial(); // 初始化串口
// 发送测试数据
sendData("Hello, UART!");
// 接收测试数据
char receivedData[100];
receiveData(receivedData, sizeof(receivedData));
printf("Received: %s\n", receivedData);
return 0;
}
标签:UART,应用程序,升级,更新,原理,固件,Bootloader,IAP
From: https://blog.csdn.net/m0_52980547/article/details/140919330