赞
踩
OTA(Over-The-Air)是一种通过无线通信方式,为设备分发新软件、配置甚至更新加密密钥的技术。它允许中心位置向所有用户发送更新,确保每个接收者都无法拒绝、破坏或改变这些更新,并且能够即时将更新应用到所有设备上。OTA升级适用于通过网络或蓝牙等无线通信方式进行,使得设备管理更加便捷和灵活,同时提升了系统的安全性和可维护性
在OTA固件升级中,单区模式和双区模式是两种常见的策略,各自有着特定的优缺点。
单区模式,整个升级过程仅使用一个存储区(通常是Bank0)。升级流程包括先擦除当前运行的老固件,然后直接将新固件下载到同一存储区,并对其进行有效性校验。这种模式优点在于节省Flash空间,实现简单直接,适用于资源有限的设备。然而,其缺点是风险较高,一旦升级失败或新固件不可用,设备可能会无法正常运行,需要外部干预才能恢复。
双区模式,老固件和新固件分别存储在不同的存储区(通常是Bank0和Bank1)。升级过程先将新固件下载到预留的下载区(Bank1),然后进行校验。校验通过后,系统进入Bootloader模式,将新固件从下载区复制到主运行区(Bank0),替换老固件。这种模式的优势在于安全可靠,即使升级失败,系统仍能回滚到之前的稳定版本,避免系统故障。它也提供了更高的灵活性,允许设备在升级过程中同时运行两个固件版本,确保平稳过渡。不过,双区模式需要额外的Flash空间来支持两个固件版本的存储,因此对资源的需求较高。
IAP(In Application Programming,即在应用中编程),旨在实现用户应用程序的动态更新,而无需使用专门的编程工具或硬件。一般情况下,STM32芯片的代码区域只存放一个用户程序。通过使用IAP方案,可以将代码区域划分为两部分:一个是固定的引导加载程序(bootloader),另一个是用户应用程序(user application)。如图所示
在单片机上电时,系统首先进入引导加载程序(bootloader)。引导加载程序会检测预设的条件,例如检测按键是否按下、是否接收到特定的串口数据、或者U盘是否插入等。如果条件未被触发,引导加载程序将直接跳转到用户应用程序(user application)执行用户的应用逻辑。如果条件被触发,引导加载程序将执行以下步骤:
擦除用户应用程序:引导加载程序会擦除当前存储的用户应用程序代码区域,确保该区域是空的,以便接受新的用户代码。
重新写入用户代码:引导加载程序从外部源(如串口通信、USB设备等)接收新的用户应用程序数据,并将其写入到之前擦除的用户代码区域中。
此时普通的应用程序占据内部Flash的大部分空间,包括主要的应用逻辑和功能代码。整个应用程序共享一个中断向量表,用于存储每个中断的入口地址,供所有的中断服务例程使用。
IAP方案在内置Flash的特定地址范围内增加了一个Bootloader程序。Bootloader的主要功能是通过串口或其他通信接口来更新或烧录用户应用程序。Bootloader程序有自己独立的中断向量表,专门处理引导过程中的中断和异常情况。用户应用程序仍然占据内部Flash的一部分空间,但更新和烧录可以通过Bootloader完成,而非传统的编程器。用户应用程序也有自己的中断向量表,确保在运行时正确处理中断事件。
设置两个工程:Bootloader程序、UserApplication程序。以下是详细的设置说明:
Bootloader程序被安排在内部FLASH的第一页,起始地址为 0x0800 0000,占用20KB空间,地址范围从0x0800 0000到0x0800 4C00(页号0至19)。在执行跳转到UserApplication之前,需确保Bootloader关闭所有打开的中断或外设,以避免影响UserApplication的运行。
UserApplication程序从内部FLASH的第二页开始,起始地址为0x0800 5000,占用43KB空间,地址范围从0x0800 5000到0x0800 F800(页号20至62)。
内部FLASH的最后一页被保留用于UserData,占用1KB空间,起始地址为0x0800 FC00,页号为63。
如图所示:
第一页 | 最后一页 | ||||
分区 | 容量 | 地址 | 页号 | 地址 | 页号 |
BootLoader | 20KB | 0800 0000 | 0 | 0800 4C00 | 19 |
UserApplication | 43KB | 0800 5000 | 20 | 0800 F800 | 62 |
UserData | 1KB | 0800 FC00 | 63 |
D:\Keill_v5\ARM\ARMCLANG\bin\fromelf.exe --bin Objects\Project.axf -o Project.bin
1. 内核初始化
1)内核复位和NVIC寄存器部分清零
- 在复位时,内核和NVIC相关寄存器被清零,确保系统处于可控状态。
2)设置堆栈
- 内核从向量表的起始地址读取堆栈指针(SP_main),设置主堆栈指针(SP)。
3)设置PC和LR寄存器
- PC寄存器被设置为复位中断向量的地址,LR寄存器通常设置为0xFFFFFFFF(复位值)。
2. 执行复位中断处理函数(Reset_Handler)
1)强制PC指针指向中断向量表的复位中断向量
- 单片机的硬件会将PC指针自动定位到复位中断向量表的复位中断向量处,开始执行Reset_Handler函数。
2)Reset_Handler中的初始化步骤
- 在Reset_Handler函数中,会调用SystemInit函数进行系统的初始化,包括时钟设置和中断向量表配置等。
3. 初始化全局/静态变量和重定位
1)调用 __main 函数
- __main 函数由编译器生成,负责初始化全局/静态变量、执行重定位工作,并最终跳转到用户定义的main函数。
4. 跳转到main函数执行用户代码
- 在所有初始化工作完成后,控制权被传递给用户编写的main函数,开始执行用户程序的主体逻辑。
1)内核初始化
- 复位时,内核和NVIC寄存器被清零。
- 设置堆栈和初始化PC、LR寄存器。
2)执行引导加载程序的复位中断处理函数(Bootloader Reset_Handler)
- 硬件将PC指针定位到引导加载程序的复位中断向量处,开始执行引导加载程序的Reset_Handler函数。
- 引导加载程序的初始化步骤,可能包括初始化引导加载程序自身的硬件资源和配置。
3)初始化全局/静态变量和重定位
- 引导加载程序调用
__main
函数进行全局变量的初始化和重定位工作。4)等待指令或判断是否需要进行IAP
- 引导加载程序可能等待外部触发条件,如特定按键组合、串口指令等,来决定是否启动IAP流程。
5)启动固件更新(IAP过程)
- 如果需要进行固件更新,引导加载程序会初始化相关硬件接口(如串口、USB等)以及存储器(如Flash)接口。
- 下载新固件数据,对数据进行校验(CRC校验等)确保完整性。
6)擦除原有固件区域
- 引导加载程序可能需要先擦除原有固件存储区域,以便存储新的固件数据。
7)写入新固件
- 将通过IAP方式下载的新固件数据写入到目标Flash存储器中的指定位置。
8)校验和完成
- 写入完成后,引导加载程序进行最终的校验,确保固件写入的正确性和完整性。
9)系统重启
- 如果固件更新成功,引导加载程序可能会进行系统的最后配置和清理工作。
- 然后重启系统,跳转到新固件的起始地址执行。
10)跳转到新固件执行
- 控制权转移给新固件的Reset_Handler函数,开始执行新固件的初始化和主逻辑。
在下载bin文件的过程中,确保数据帧的完整性至关重要。一般情况下,串口使用空闲中断来判断数据帧是否传输结束。但在大量数据传输时,可能会出现空闲中断误判的情况。为了解决这个问题,可以考虑使用类似RS485通信的方式,通过定时器定时触发来确定数据传输的结束标志,例如设定一个100ms的空闲周期作为传输结束的标志。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。