你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】can总线实现stm32的IAP

[复制链接]
STMCU小助手 发布时间:2022-2-5 00:00
使用stm32f105rct6的can通信做IAP,实现固件的远程更新功能。IAP的实现包括两个程序:BootLoader和应用程序。启动过程先启动BootLoader,等待1s,若接收到烧写指令则开始更新程序,若无指令则启动应用程序。应用程序接收到更新指令后,切换到BootLoader。
+ P6 O" T, Y) T) I远程程序更新需要防止更新失败后,程序卡死,只能通过人工现场更新的情况。可以使用看门狗实现重启返回BootLoader,给重新烧写留出时间。
& U. t1 R) ?2 v1 m' Y+ M/ J实现IAP流程,需要的工作包括:$ e: }5 J3 R! S/ B
1、规划单片机存储区,设置中断向量位置,生成应用程序bin文件$ Y* V* I( [' y# h
2、编写BootLoader,实现应用程序切换4 k8 s) b! i. x
3、编写远程更新上位机,实现通信协议
, Q0 o( u3 p& n! e- E8 [4 h4、插入看门狗程序,实现烧写失败后重启& R, R% X" {4 W; C9 l7 i
1、规划单片机存储区,设置中断向量位置,生成应用程序bin文件
" I( P& o: f3 j  h& Ystm32f105rct6的flash共256KB,规划flash空间:  & W7 t' w2 Q+ P3 `
0x08000000~0x08004000 共16KB空间,给BootLoader  
% i' @8 \! o6 X) ~8 N0x08004000~0x08010000 共48KB空间,给应用程序' y% I. |, {  p8 `$ d% R+ h
0x08010000~0x08014000 共16KB空间,保留
) P  {. L* Z  X: F0x08014000~0x08018000 共16KB空间,给配置
1 `& |# Q5 E, I, S8 X+ L  {6 X" Z单片机应用程序在起始地址中的结构,首先是中断向量,然后是代码。) s2 Z6 |1 a: m  ?
中断向量的结构:开头4字节堆栈指针,接下来是4字节reset函数地址,之后是其他中断函数的地址。
) a0 a  ]5 K9 g1 ?单片机开机后,从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
7 ?, w, e, `8 d1 p5 _生成应用程序的bin文件:
/ X9 N! k% B3 g# i, @1 f$ {keil中,在options -> user -> after build -> run   中输入指令
  x  ]) y! m( _  w: I    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烧写等功能,当超时无指令,或烧写成功后,需要进行程序切换。
& D. g4 c& C' {; X/ }% \程序切换时,首先应关闭设备时钟、关闭中断,避免应用程序中未对设备进行初始化,导致boot方式启动与冷启动有功能差别。( T8 ^/ T4 p$ A  r+ z
切换原理:模拟单片机上电过程,人工设置堆栈指针,调用应用程序入口函数。+ D/ T+ s6 X# P0 m
切换代码如下:8 X' f+ d2 h7 |7 x6 S
  1. void switch_2_addr(u32 *pc) //切换到指定的程序指针
    9 l$ P9 X0 D' ^6 _9 H. x( K  U; a
  2. {6 [0 h1 p" b5 j& b! {! c2 F+ ?
  3.     u32 i = 0;, ~% ~2 {$ O$ |$ P' L4 G( v
  4.     RCC->APB1RSTR = 0x00000000;//复位结束
    7 P* o* l% h& W1 A
  5.     RCC->APB2RSTR = 0x00000000;
    " [' I8 C+ N+ @! f! T9 U
  6. . t- i1 P0 A: c: X  a
  7.     RCC->AHBENR = 0x00000014;  //睡眠模式闪存和SRAM时钟使能.其他关闭.; x' T; N: u9 q. G" A
  8.     RCC->APB2ENR = 0x00000000; //外设时钟关闭.% A, @* Q! N& M
  9.     RCC->APB1ENR = 0x00000000;, }: f4 Q6 y+ }7 ~6 K/ A
  10.     RCC->CR |= 0x00000001;     //使能内部高速时钟HSION
      R: e% T' n' S" e7 t
  11.     RCC->CFGR &= 0xF8FF0000;   //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]' p' o. C! l$ P) G0 y
  12.     RCC->CR &= 0xFEF6FFFF;     //复位HSEON,CSSON,PLLON8 i* O; A+ l/ c! C8 ?
  13.     RCC->CR &= 0xFFFBFFFF;     //复位HSEBYP
    5 x( F6 f  O/ w7 W
  14.     RCC->CFGR &= 0xFF80FFFF;   //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
    / ~" V; X  {' l' }$ I
  15.     RCC->CIR = 0x00000000;     //关闭所有中断
    - H. z" b" B0 N; n

  16. ; o9 k* [# A" B4 v. ^
  17.     NVIC->ICER[0] = 0xFFFFFFFF;! A; h, C; z% M
  18.     NVIC->ICER[1] = 0x000007FF;9 X% N) Q# |. k' L; ?  T$ T3 i' d
  19.     NVIC->ICPR[0] = 0xFFFFFFFF;% l2 ]0 w7 ], x, V' k
  20.     NVIC->ICPR[1] = 0x000007FF;" I/ L1 a8 y7 Z2 \1 j0 r
  21.     for(i = 0; i < 0x0B; i++)
    ' j; q5 {2 [  e1 R, a4 \7 _
  22.     {
    8 P* I: ]$ W3 _! U
  23.         NVIC->IP[i] = 0x00000000;
    / [2 q+ N' U- r* s$ l" |
  24.     }0 U% s! k" T" m# l
  25.    __ASM volatile("cpsid i"); //关闭所有中断5 d5 v7 s/ J* ~% D2 x# f
  26. % w$ i8 m8 m& v' l! K# v3 A
  27.     MSR_MSP(*pc); //堆栈指针是应用程序起始的第一个u32
    : F  \0 S/ v/ t
  28.     ((void (*)(void))*(pc+1))();//入口函数是应用程序起始的第二个u32
    7 [0 k! O1 i3 r( p; U- ?+ O
  29. }
复制代码

5 ^8 Z) {+ \; e
其中MSR_MSP函数如下:
  1. 1 __asm void MSR_MSP(u32 addr)
    - ^$ w( i5 l3 y
  2. 2 {
    ; p$ j8 U! u8 S* e; Z3 i3 W. q& r
  3. 3     MSR MSP, r0             //set Main Stack value
    9 E, u9 F) I& |. y: k
  4. 4     BX r14+ I- H, D$ A* L8 t
  5. 5 }
复制代码
, J# C. Z1 H; e! C$ X
3、编写远程更新上位机,实现通信协议9 ~' K' q- G7 l2 V
上位机实现通信协议:5 U3 M9 G6 V! ]/ Z+ t+ R- b9 ^0 b
每个程序具有自己的version,16bit,高1字节为程序代号,低1字节为程序发布版本  
$ V% j( ?" t; s4 y; r, P通信的过程:  . T5 J  a  t+ U3 l, Q1 G, f
1. 控制方发送查询指令,应用程序或BootLoader收到后发送自身version  4 z9 }9 j2 K" |. ?  g
2. 控制方发送起始指令,指令中带有长度和crc,应用程序收到后,若不准许,则发不准更新包,若准许,则不响应,直接切入BootLoader  
! B4 f! K) w& [8 x) V; b3. 控制方持续发送起始指令,BootLoader收到后,回复相同canid的包,准许更新  
5 e1 C: f" K1 R9 [! u8 J/ S4. 控制方得到准许后,发送id递增的can包,将bin文件下载到MCU  
( k2 t2 [2 m" S, ]% H5. 发送完成后,控制方额外发送一个can id低16bit为0xffff的包,内容任意,表示结束。BootLoader收到后开始计算crc,若失败,则发失败包。若成功,则开始烧写flash,若烧写失败,发送烧写失败包。  
7 G3 T( ~: R+ [- O9 h) Q) L6. 烧写成功,BootLoader切换到应用程序,此时控制方一直发查询指令,直到应用程序回复版本号正确。  
1 X4 L! N* f7 A2 S& N 4、插入看门狗程序,实现烧写失败后重启, G6 g- [+ z7 ~+ Q3 G& q; H3 {9 {
在BootLoader中开看门狗,切换到应用程序后喂狗。若程序烧写失败,则切换到应用程序后程序卡死,导致MCU重启,又进入BootLoader,停留1s,等待下次烧写。  Q; B) y' }9 O. Y1 ]6 |) s) W

9 o/ z; j$ F- R0 X$ }3 q. F7 n* p1 h( [3 W( `

+ z3 q+ w6 R4 ?9 t% r0 }. s1 z- o2 z7 @- R/ e% \1 ^! i
收藏 1 评论0 发布时间:2022-2-5 00:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版