STM32F4 简化版 IAP 完整项目开发日志
链接
- 仓库 https://github.com/z1178902213/IAP_test
详细内容
一、项目硬件与分区
- 主控:STM32F407;外设:ESP8266 WiFi模块、板载以太网。
- Flash划分为3个分区:
0x08000000‑0x0803FFFF:BOOT引导程序0x08040000‑0x080A0000:APP运行区0x080A0000‑0x080FFFFF:APP下载存储区(升级包存放)
二、BOOT引导程序功能
- 上电后等待5秒串口指令:
- 输入
1:进入烧录模式,接收上位机下发BIN固件,写入APP存储区;写入完成校验,拷贝固件到运行区,完成跳转。 - 输入
2:恢复出厂,将存储区固件拷贝至运行区。 - 输入
3或者5秒超时:直接跳转到运行区执行APP程序。
- 输入
- 跳转APP关键点:手动读取APP镜像的栈指针MSP与复位入口,汇编切换MSP,跳转复位函数;跳转前切换HSI时钟、调低Flash等待周期、处理中断向量表,规避HardFault死机。
- 升级流程:上位机发送BIN文件长度→BOOT擦除存储区扇区→接收BIN数据流写入Flash→数据校验→拷贝镜像到运行区→跳转APP。
注:BOOT为简化实现,没有做复杂传输校验协议。
三、APP应用程序(FreeRTOS+LwIP)
APP运行在运行区,基于FreeRTOS操作系统,移植LwIP协议栈实现以太网TCP Server,ESP8266通过串口AT指令控制WiFi:
- 任务划分
- LED闪烁任务:系统存活指示。
- 串口&WiFi处理任务:解析控制台指令,转发AT指令给ESP8266。
- 以太网任务:TCP回显服务器,支持DHCP获取IP。
- 网络能力:ETH以太网、ESP8266 WiFi均可和上位机双向收发数据。
开发踩坑重点
- FreeRTOS移植:必须在
SysTick_Handler调用xPortSysTickHandler,否则任务无法时间片轮转;新版本FreeRTOS配置项、中断函数处理需要修改。 - HAL串口DMA接收:
HAL_UART_Receive_DMA无法识别帧结束,需要使用HAL_UARTEx_ReceiveToIdle_DMA+空闲中断回调获取真实接收长度;串口不会自动补\0,需要手动处理字符串结束符。 - ESP8266模组:必须拉高
WIFI_EN使能引脚、RST复位引脚,模块才能正常启动;AT指令末尾必须带换行。 - LwIP移植:参考野火工程;工具坑:野火v1.0.3网络调试助手存在bug,建议更换调试工具;路由器不一定会显示DHCP设备,以ping通为准。
- APP跳转:跳转前必须处理时钟、Flash latency、中断向量表,否则进入硬件异常;APP工程要修改中断向量表偏移。
- HAL版本坑:高版本HAL提供
HAL_UARTEx_ReceiveToIdle_DMA,降级到旧版本HAL后该API消失,需要自己实现IDLE空闲中断接收。
四、QT上位机软件
使用QT开发,使用QSerialPort做串口通信、QTcpSocket实现TCP网络通信,功能:
- 串口:枚举串口、打开关闭串口、收发数据;读取本地BIN固件文件,按照自定义协议下发BIN给BOOT完成IAP升级。
- 网络:TCP客户端,连接STM32的TCP服务,完成以太网/WiFi的数据收发。
- 已知bug:QT串口库接收部分WiFi模块返回数据存在丢字节问题;中文GBK编码乱码需要手动做编码转换。
五、遇到的典型问题汇总
- MDK:Keil未激活出现代码大小限制;需要勾选
Use MicroLIB,开启Browse Information支持函数跳转;可以修改IROM1地址直接烧录到对应Flash分区调试。 - FreeRTOS:串口任务优先级过低会丢数据;DMA串口输出任务建议阻塞等待DMA完成,避免输出错乱。
- 开发习惯反思:不要盲目使用最新版本HAL、FreeRTOS,初学容易出现版本兼容问题;不要炫技写复杂代码,优先保证功能可用。
六、项目局限
- 简化IAP版本,没有做复杂校验协议,没有MD5校验;
- WiFi任务处理逻辑存在瑕疵,部分边界场景处理不完善;
- QT上位机存在串口接收丢包、编码的遗留bug;
- BOOT没有精准Systick,5秒等待延时精度一般。
完整源码仓库:z1178902213/IAP_test,包含下位机工程与QT上位机完整代码。