首页 > 编程语言 >IAP 程序升级原理

IAP 程序升级原理

时间:2024-08-06 11:56:18浏览次数:11  
标签:UART 应用程序 升级 更新 原理 固件 Bootloader IAP

参考见:IAP升级 资料收集-CSDN博客

一、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

相关文章

  • STM32启动文件,在启动文件中理解IAP
    ;********************(C)COPYRIGHT2017STMicroelectronics********************;*FileName:startup_stm32f103xe.s;*Author:MCDApplicationTeam;*Description:STM32F103xEDevicesvectortableforMDK-ARMtoolchain.;*......
  • 监控系统原理揭秘-数据运算篇
    一、监控系统概览监控系统在现代技术环境中扮演着至关重要的角色。运营同学每天检查自己的活动数据,研发人员每天检查系统各项指标是否正常,这些工作都少不了监控系统的身影。通常来讲,监控系统包括数据采集、数据计算、数据存储、数据可视化及监控预警等功能。本文主要介绍数据计算......
  • 深入探讨控制反转(IOC)与依赖注入(DI)模式原理与应用实践
    本文由ChatMoney团队出品在软件开发中,控制反转(InversionofControl,简称IOC)和依赖注入(DependencyInjection,简称DI)是两种常用的设计模式,它们旨在降低组件间的耦合度,提高代码的可维护性和灵活性。一、控制反转(IOC)模式控制反转是将组件间的依赖关系从程序内部提到外部来管理。......
  • 高速图像采集卡设计原理图: 613-基于6UVPX C6678+XCVU9P的信号处理板卡
    基于6UVPXC6678+XCVU9P的信号处理板卡一、板卡概述      板卡基于6U VPX标准结构,包含一个C6678 DSP芯片,一个XCVU9P 高性能FPGA,双路HPC FMC。  二、处理板技术指标•  DSP处理器采用TI 8核处理器TMS320C6678;•  DSP 外挂一组64bit DDR3......
  • 多态的机制原理
    多态通常有两种实现方法:子类继承父类(extends)类实现接口(implements)多态的实现机制:重载(overload)和重写(override)如果一个子类继承了一个父类,子类中拥有和父类相同方法名称,返回值,参数类型的话,就是重写,会执行子类中的方法。如果一个类中定义了多个同名方法,他们有不同的......
  • 京准电子:NTP网络时间服务器技术设计原理架构
    京准电子:NTP网络时间服务器技术设计原理架构京准电子:NTP网络时间服务器技术设计原理架构京准电子科技官微——ahjzszNTP网络时间服务器为防火墙内的网络设备、终端、服务器提供准确、可靠和安全的高精度卫星时间参考,可为它支持数万台支持标准的网络时间协议(NTP,含V1/2/3/4)和......
  • C++(虚函数实现多态基本原理)
    目录1.概念2.示例3.总结在C++中,加上virtual关键字可以实现多态,这是因为它允许函数在基类和派生类中有不同的实现,并确保在运行时正确调用派生类的方法。具体来说,这种机制称为“动态绑定”或“运行时多态”。1.概念虚函数(VirtualFunction):当你在基类中声明一个函数......
  • UITableView的原理——探究及重新实现代码
    转自简书,原文地址,本文主要探讨一些特殊细节,像视图重用这类最基本的原理可在源码里查看。先前重新实现了一个list容器视图,由于Apple没有开源,在此分享过程中探索到的UITableView一些细节。MPTableView:AlistviewlikeUITableView,morefast,morefeatures.1·捉摸不定的con......
  • 2024河南省大学生电子设计竞赛A题:AC-AC变换电路并联运行(代码工程+原理图+PCB+设计报告
    1.电赛题目2.题目需求分析在题目中需要注意以下几个关键点:1.要求电路的拓扑结构为AC-AC直接变换电路,不得使用AC-DC-AC,-------- 应该是主要针对的背靠背电路。 AC-AC电路拓扑较少见,详细可以参照《AC-AC变换技术》-----陈道练。2.系统的供电也从AC36V输入获取......
  • selenium复习之---原理+基础用法
    简介1.是什么selenium是用来进行页面元素定位的第三方库,用来进行web自动化测试的工具,可以直接运行在浏览器中。2.原理:selenium在工作过程中有三个角色,selenium客户端、webdriver和浏览器selenium客户端是开发者与selenium的交互接口,它会发送指令给webdriver浏览器则接收来自......