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

STM32+IAP方案 实现网络升级应用固件

[复制链接]
STMCU-管管 发布时间:2020-9-24 13:52
概况:
  • 什么是IAP,为什么要IAP
  • 可实现的原理
  • 实现过程
  • 细节及实现4 T! O! Q; W( F- M& B5 V# z
    以上基本都可以从【IAR环境下STM32+IAP方案的实现】中找到答案。这里只是贴图,醒目:

    ! \, J' y8 b$ E; h

    ! w* s. b4 s) b) V  ?2 Q

# A' a2 R, t" X' I. ~: u6 E6 y; F0 E. g
IAP框架布局:
( k8 [- D4 B2 k5 O5 O: H  v/ f" J
' ~/ j3 O+ u, o, O, J. u
! W3 `. J- _) Z
/ k' o* `4 _. E8 Y3 g5 |
STM32F103ZET6的启动方式有三种:内置FLASH启动、内置SRAM启动、系统存储器ROM启动,通过BOOT0和BOOT1引脚的设置可以选择从哪中方式启动,这里选择内置的FLASH启动。其FLASH的地址为0x08000000—0x0807ffff,共512KB,这些都能从芯片数据手册中直接得到。而这里首要的一个问题是中断的问题。正常情况下发生中断的过程为:发生中断(中断请求),到中断向量表查找中断函数入口地址,跳转到中断函数,执行中断函数,中断返回。也就是说在STM32的内置的Flash中有一个中断向量表来存放各个中断服务函数的入口地址,内置Flash的分配情况大致如下图2-1。
" w* `# F7 D1 b  n; J: R! H0 R( ~
8 B8 r2 J2 l* Y1 C; i8 f1 W. Q

; w# X  \+ c$ V/ H" F+ E5 w. W  w1 N, W" f, D) M4 _& p

8 a0 j6 K5 e4 |/ w% h

# L; P' o8 r) r
& P. ?' w. @1 `. D& p" K# H& F. x5 x/ p+ s1 ~6 W9 ~

4 T8 `( ]* {$ d4 S  k! g4 i9 E, t% x# v* v4 W4 m% T. `
5 O1 B+ K0 `3 X- Y/ a

! A9 K: |3 l* J! O在内置的Flash里面添加一个BootLoader程序,BootLoader程序和user application各有一个中断向量表,假设BootLoader程序占用的空间为N+M字节,则程序的走向应该如图2-2所示(借用网友的原图并做改动,其中虚线部分为原图步骤④⑤的走向,本人改为指向灰色部分)。

3 c$ M) f8 Y: _# Y! U/ @! n
/ c! s1 `" M( n7 T3 C2 V  Z% S/ m5 {
# k4 l0 {* h& w0 E: X% p

* v! w6 B7 C5 j4 T上电初始程序依然从0x08000004处取出复位中断向量地址,执行复位中断函数后跳转到IAP的main(标号①所示),在IAP的main函数执行完成后强制跳转到0x08000004+N+M处(标号②所示),最后跳转到新的main函数中来(标号③所示),当发生中断请求后,程序跳转到新的中断向量表中取出新的中断函数入口地址,再跳转到新的中断服务函数中执行(标号④⑤所示),执行完中断函数后再返回到main函数中来(标号⑥所示)。
- X7 v5 j2 d9 w0 D, T# ~

1 a: u% ^) N* `5 {
对于步骤④⑤,网友认为是:“在main执行的过程中,如果CPU得到一个
中断请求,PC指针仍强制跳转到地址0x08000004中断向量表处,而不是新的中断向量表,如图标号④所示,程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中,如图标号⑤所示”。我对此的理解是:“当发生中断后,程序从0x08000004(旧)处的中断向量表中得到相应的中断服务函数入口地址,继而跳转到相应的中断服务程序”。但是旧的中断向量列表里边存放的是IAP程序中断函数的入口地址,它是如何得到user程序中断函数的入口地址呢?所以我觉得此种说法是错误的。“当发生中断时PC指针强制会跳转到0x08000004处”这种说法并没有错,只是忽略了后续的一些知识要点而导致这个说法出现矛盾。
8 X* Y) T) y; c& O) o. S, T& t  E5 B* P7 |5 x7 x5 L' _1 x

3 i) D9 ~+ \) u5 k* F  I对于步骤④⑤我认为的是,在main函数的执行过程中,如果CPU得到一个中断请求,PC指针本来应该跳转到0x08000004处的中断向量表,由于我们设置了中断向量表偏移量为N+M,因此PC指针被强制跳转到0x08000004+N+M处的中断向量表中得到相应的中断函数地址(待求证),再跳转到相应新的中断服务函数,执行结束后返回到main函数中来。* Z5 ^/ j6 k6 ^* K& }4 w1 j

* p( K2 E7 D. g1 z2 I* P

IAP流程描述:1、IAP的bootloader引导程序

IAP在应用中编程,可以拓展成远程网络更新应用固件。
! B. h4 l: Z/ c片内的flash,至少划分成2个分区,对应至少两个完整的程序;; d0 L3 O3 y$ c3 `: V" @
低地址分区端推荐放入IAP程序==bootloader引导程序(这里边的手段可以是串口、网络等不同的方式),高地址分区端推荐烧写app固件。1 ]% ^+ c3 M% h
关键点提及:. H5 m8 H; i: O! P# e$ F
IAP程序中,当满足跳转条件(被触发)时,执行跳转代码到app应用固件程序,跳转代码流程:
/ `2 `. o# q: t5 b; o至少需要设定跳转目的地的app应用固件 栈顶指针,:

$ H. `  Y5 ^$ A& x

  1. /* Initialize user application's Stack Pointer */, }1 ~; }) d$ f4 v5 Y
  2. __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
复制代码

8 F- t2 }3 S3 C) i/ \# I( \

其中,app应用固件的分区地址:

  n0 t9 b% V4 ^& U6 K# ~

  1. #define USER_FLASH_FIRST_PAGE_ADDRESS 0x08009000
复制代码

  h# _$ [( E+ n: L9 j5 E% b

! F" K) C, _& [) x1 h2、app应用固件
* ]8 R9 W$ e. q8 o9 Q- K. k

需要两处的更改,不然错误未知& X% v$ y! j! r# I2 l
IROM设置如图:

0 ?% V* P5 D5 p# w9 w: ~: E

4 M& O  @4 `# i
3 ^0 @6 y" R# @8 Z" v. Y* `
中断向量表偏移:


/ y7 f5 [9 {6 s. Y# Z$ A% u$ M

8 o) C7 s( e/ A8 X" k6 A* E

% z& \; {5 D( t  H# G$ {

  1. NVIC_SetVectorTable(NVIC_VectTab_FLASH,VectorTable_Offset);" J. x) [8 m3 d* z& r9 C
复制代码


. }8 g: Q+ b  M' z1 q% m: }# v7 g* W& q3 c; L) E

, ?* s2 j4 ]% D1 [1 L

其中:

/ w4 h- R$ r6 S

  1. #define NVIC_VectTab_FLASH           ((uint32_t)0x08000000)
    5 |$ C! O* }' B8 j
  2. #define VectorTable_Offset  0x9000
复制代码
' Z7 O+ V# f( V/ |4 j

查错:. i" W+ J5 p! D" _8 {

如果做了上边的工作,IAP依然无法顺利执行跳转至app应用程序,可以查看.map和.bin文件,确定是否如实的改变的中断向量表的偏移和栈顶指针,如图:


6 |( W" w& U" k( C! j2 x4 l

6 U% Y0 I. Y5 O

7 z/ p- H, R+ A( |1 {" H
8 q$ h" f6 H& D
# q/ J3 B: T9 U- |  T) {, C* [7 {
.bin文件:

  F4 u- |% W  k. g

7 e7 H* {$ G6 V8 R/ [$ }
2 o' a. T: X) y" G: z( Y9 s) Y* f8 T9 r0 C
可以看到,主栈顶MSP地址=0x2000C8C8、reset_handler地址=0x08009189
; q/ U1 w! B  k0 Q$ U* ^, `如此,才能生效,否则,可能原因:
# ~9 z& u- q% K: T, s7 @修改后的向量表偏移,在之后的程序中,又再次被还原,通过如下的函数:


- ~% q0 c: D" f+ g7 b8 T

  1. void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);- {  D+ B8 u0 ?
  2. void SystemInit (void);- M. V: }" R: A5 Q
  3. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
复制代码

6 E5 y. ?6 S4 ]
附:3 E: ^$ n; h; P( a, Q) T

1、如需要.hex文件转.bin,参见上边的文章" ~4 ]$ q& z4 S7 g) r& j
当然,就算使用.hex文件,同样可以升级,只是需要修改IAP中判定已经升级的文件是否有效,文件条件部分的代码,

% o1 ?) u2 O/ ~& G

  1. if(((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
复制代码
1 n' `* R$ e( `& K6 K- v. _
& z; S. }7 |$ j* E

% E. z0 o* `! N- F

2、地址偏移后的app应用程序,是否能够独立的运行?/ [8 G3 r) \# t# n/ U7 H5 O; G$ M
不能,理由:

: ]- C5 {& ^5 y) O6 ]- F4 d1 A


: p; A" Q/ j5 {' @( i$ Z* f' q: ^+ w* g0 Y9 K
可知,开机上电并不能够找到我们指定的偏移后的向量表。


: j4 X6 ?& p+ d1 t; M

+ R3 a' V0 S: t: D/ H+ r
. k# J! J) I  L' Y
收藏 评论0 发布时间:2020-9-24 13:52

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版