1. IAP升级实战:从理论到硬件的全面解析
我一直觉得IAP升级是嵌入式开发中最实用的功能之一。想象一下,你的设备已经部署在现场,突然发现有个bug需要修复,或者要增加新功能。如果每次都要跑过去拆机用下载器烧录,那简直是噩梦。IAP就是在程序运行中通过通信方式实现软件更新,完全摆脱了对物理下载器的依赖。
我最近在一个STM32F103C8T6项目上实现了完整的IAP方案,使用W25Q64作为外部存储来暂存升级固件。这个方案最大的优势是安全可靠——即使升级过程中断电,也不会让设备变砖,因为原系统还在Flash中正常运行,只是升级失败了而已。
在实际操作中,我建议把升级逻辑放在Bootloader中。虽然原始文章提到是在APP中接收升级数据,但这样确实风险较大。我在早期项目中也试过这种方式,一旦升级失败就容易导致系统跑飞。后来改为在Boot程序中处理升级,稳定性大大提升,而且还为后续实现双APP备份打下了基础。
2. 硬件选型与资源规划
2.1 核心控制器选择
STM32F103C8T6是我最常用的型号,性价比极高。它拥有64KB Flash和20KB RAM,对于大多数应用场景都足够。最重要的是,它的内存映射设计非常清晰,便于实现IAP功能。Flash起始地址为0x08000000,我们可以将其划分为Bootloader区和APP区。
我通常给Bootloader分配8KB空间(0x08000000-0x08001FFF),剩下的56KB留给APP程序。这个分配不是固定的,你可以根据实际需求调整。如果Bootloader功能复杂,可能需要更多空间;如果APP程序很大,也可以适当压缩Bootloader空间。
2.2 外部存储的重要性
W25Q64是一片8MB的SPI Flash,用来存储升级固件再合适不过。为什么需要外部存储?因为STM32的内部Flash在擦写时会导致程序暂停执行。如果我们直接在内部Flash中边接收边烧写,一旦数据量大或者通信中断,整个系统就会出问题。
使用W25Q64作为缓冲,我们可以先完整接收升级包并校验,确认无误后再一次性写入内部Flash。这样即使升级过程中出现问题,原系统仍然完好无损。我选择W25Q64还因为它的SPI接口简单稳定,驱动程序成熟可靠。
3. Bootloader设计与实现细节
3.1 启动流程与跳转机制
Bootloader的核心职责是决定启动哪个程序。上电后首先运行Bootloader,它需要检查是否有新的升级文件等待烧写。如果有,就执行升级流程;如果没有,就跳转到APP程序。
跳转函数是关键中的关键,我优化后的版本是这样的:
void JumpToApp(uint32_t appAddress)
{
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
__di


638

被折叠的 条评论
为什么被折叠?



