
使用stm32f105rct6的can通信做IAP,实现固件的远程更新功能。IAP的实现包括两个程序:BootLoader和应用程序。启动过程先启动BootLoader,等待1s,若接收到烧写指令则开始更新程序,若无指令则启动应用程序。应用程序接收到更新指令后,切换到BootLoader。 远程程序更新需要防止更新失败后,程序卡死,只能通过人工现场更新的情况。可以使用看门狗实现重启返回BootLoader,给重新烧写留出时间。 实现IAP流程,需要的工作包括:$ e: }5 J3 R! S/ B 1、规划单片机存储区,设置中断向量位置,生成应用程序bin文件$ Y* V* I( [' y# h 2、编写BootLoader,实现应用程序切换4 k8 s) b! i. x 3、编写远程更新上位机,实现通信协议 4、插入看门狗程序,实现烧写失败后重启& R, R% X" {4 W; C9 l7 i 1、规划单片机存储区,设置中断向量位置,生成应用程序bin文件 stm32f105rct6的flash共256KB,规划flash空间: & W7 t' w2 Q+ P3 ` 0x08000000~0x08004000 共16KB空间,给BootLoader 0x08004000~0x08010000 共48KB空间,给应用程序' y% I. |, { p8 `$ d% R+ h 0x08010000~0x08014000 共16KB空间,保留 0x08014000~0x08018000 共16KB空间,给配置 单片机应用程序在起始地址中的结构,首先是中断向量,然后是代码。) s2 Z6 |1 a: m ? 中断向量的结构:开头4字节堆栈指针,接下来是4字节reset函数地址,之后是其他中断函数的地址。 单片机开机后,从0x08000000处取得SP,然后从0x08000004处取得reset地址作为PC,在reset函数中调用main函数,进入C语言控制的程序中。* ~ U5 p" S. J9 Z 1 q! b) Y4 x; J 在keil中的options -> target -> IROM 填写应用程序的起始和长度,并在linker -> use memory layout from target dialog中打钩: v' l) t+ G) }9 U( A2 D 在应用程序中,调用NVIC函数,设置中断向量位置为0x08004000 生成应用程序的bin文件: keil中,在options -> user -> after build -> run 中输入指令 fromelf.exe --bin -o ..\w01sim\bin\mcubin\canext.bin .\obj\test.axf r3 Y; U9 @4 ?! m2 ` i 2、编写BootLoader,实现应用程序切换- h. i1 C- ?+ R8 }" T7 t* X 建立一个普通的stm32工程,实现can通信和数据协议、flash烧写等功能,当超时无指令,或烧写成功后,需要进行程序切换。 程序切换时,首先应关闭设备时钟、关闭中断,避免应用程序中未对设备进行初始化,导致boot方式启动与冷启动有功能差别。( T8 ^/ T4 p$ A r+ z 切换原理:模拟单片机上电过程,人工设置堆栈指针,调用应用程序入口函数。+ D/ T+ s6 X# P0 m 切换代码如下:8 X' f+ d2 h7 |7 x6 S
其中MSR_MSP函数如下:
3、编写远程更新上位机,实现通信协议9 ~' K' q- G7 l2 V 上位机实现通信协议:5 U3 M9 G6 V! ]/ Z+ t+ R- b9 ^0 b 每个程序具有自己的version,16bit,高1字节为程序代号,低1字节为程序发布版本 通信的过程: . T5 J a t+ U3 l, Q1 G, f 1. 控制方发送查询指令,应用程序或BootLoader收到后发送自身version 4 z9 }9 j2 K" |. ? g 2. 控制方发送起始指令,指令中带有长度和crc,应用程序收到后,若不准许,则发不准更新包,若准许,则不响应,直接切入BootLoader 3. 控制方持续发送起始指令,BootLoader收到后,回复相同canid的包,准许更新 4. 控制方得到准许后,发送id递增的can包,将bin文件下载到MCU 5. 发送完成后,控制方额外发送一个can id低16bit为0xffff的包,内容任意,表示结束。BootLoader收到后开始计算crc,若失败,则发失败包。若成功,则开始烧写flash,若烧写失败,发送烧写失败包。 6. 烧写成功,BootLoader切换到应用程序,此时控制方一直发查询指令,直到应用程序回复版本号正确。 4、插入看门狗程序,实现烧写失败后重启, G6 g- [+ z7 ~+ Q3 G& q; H3 {9 { 在BootLoader中开看门狗,切换到应用程序后喂狗。若程序烧写失败,则切换到应用程序后程序卡死,导致MCU重启,又进入BootLoader,停留1s,等待下次烧写。 Q; B) y' }9 O. Y1 ]6 |) s) W . F7 n* p1 h( [3 W( ` . s1 z- o2 z7 @- R/ e% \1 ^! i |