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

关于STM32F0 IAP应用中不同代码区的跳转

[复制链接]
yumeii 发布时间:2020-1-8 17:04
对于STM32用户,经常会涉及到通过用户启动程序实现对用户应用程序的更新升级。一般来讲,用户启动程序主要用来跟外界通信,获取新的用户程序代码并实现对用户代码区的应用程序升级。
0 ?) U+ [' [& L% D2 e" p* N# }) @
6 a. C; M. t+ S7 b" T1 i
用户应用程序是指实现各种用户功能的代码。在这个过程中,往往需要做从用户引导程序区到用户应用程序区的跳转,有时可能还需实现从用户应用程序区跳回到用户启动程序区,或者不同用户程序区的互相跳转等操作。在这些跳转过程中,往往有人在此遇到阻碍,破费周折,尤其是在使用基于cortex M0内核的STM32F0做IAP应用时,这个过程跟其它基于CORTEX M3/M4/M7内核的STM32系列相比,操作上不太一样,实现起来稍微复杂些。
! W+ X4 h1 o. M/ q: Q; ^
" d4 b1 W/ x- n  K这里就STM32F0芯片内不同程序区的跳转问题做些交流与介绍,限于篇幅,仅直接介绍具体操作和注意事项,不做过多拓展。相关知识点可阅读STM32芯片参考手册、STM32相关ARM内核编程手册。
- H1 H. K, p: m' ~' a$ ~8 `- z4 E- p' N& c, a* i2 n
下面介绍中提及的集成编译环境是指ARM MDK,硬件基于STM32F072RB Nucleo开发板。后面我将逐一介绍从BOOT区【用户启动程序区】跳转到APP区【用户应用程序区】,从APP区跳转到另外新APP区以及从APP区跳回BOOT区的基本流程及注意事项。& ^, f6 K  W2 l

; _  I5 ^+ A: m) Y& O, t一般来讲,不同区段的执行代码我们通过建立不同的工程项目来实现,最终将不同区段执行代码写入芯片。这里假定用户BOOT区对应的内部FLASH地址段为0x8000000—0x8004000, 用户APP1区对应的内部FLASH地址段为0x8004000—0x8008000, APP2区对应的内部FLASH地址段为0x8008000—0x800C000.; e# x% M& c4 L1 ~+ C
3 ]1 ^) ?. L3 D8 [

$ v% U8 S. m' Y$ C' U. m# l! z 1.png
# C9 U+ h, {2 ]9 x$ W) X" Y! ?* q$ N$ U* T; k0 O8 q
1 \, t% x. q6 j. A4 D  C% m
一、从用户启动程序区【BOOT区】到用户应用程序区【APP区】的跳转) k2 Z/ A. s% B+ R: r

0 j3 G& L5 d  K; @

; o; ?( L5 W4 q0 y' z: _先说从BOOT区跳转到APP区。跳转代码比较简洁、简单,注意跳转前要关闭刚才程序区开启过的所有中断使能,保证所有中断请求位都被清除,不要只是简单的关闭总中断,否则往往隐患多多。BOOT区相关跳转代码如下:" r2 Y( t( U$ E: s! t: m. h3 Y, x
0 {" f) C, ?& c, Z" O* R

# W3 U+ w  z3 r3 B. D0 b4 J 2.png , H0 j- Y9 q, o6 K
/ r& `" b6 H* N
5 Z+ x2 F7 C9 N. _$ }$ N$ p( K( y& m
这个从BOOT区到APP区的跳转最终能否成功,关键取决于APP区代码相关配置及准备工作。假设这里的APP区是上面提到的APP1区,内部FLASH地址段为0x8004000—0x8008000,那么在MDK的option项里的memory配置板块要做正确配置,即flash空间与ram空间的配置,如下图所示:) N8 a  z9 h' h& _, I* r8 R. _% C
" z$ ^4 T- s( \+ i

' `. D7 m: u4 k' Z- i. \ 3.png
6 E: c  |$ F7 A) E: \! a( f/ ?+ z4 o7 z  N" }/ h& n+ t
" }/ f1 }5 a+ `" {$ w4 p
IROM1的配置就是APP1代码摆放的起始空间地址及长度。IRAM的配置要注意先保留48个字的空间用来存放中断矢量表的内容。因为stm32F0芯片的中断矢量表的大小就是48个字【即0xc0字节】。至于剩下的内部RAM空间大小由芯片本身的RAM容量决定。【这里是基于STM32F072RB芯片,其内部RAM总容量为0x4000】。
; k3 X( S; t0 B# K3 @, P$ R& ]+ x# [1 P) T- p( V
另外一件很重要的事情就是做中断矢量表的拷贝。在APP1区的main()程序开头部分,将放在flash程序空间起始部分的连续48个中断矢量地址表拷贝到内部RAM的起始地址段。即将矢量表从0x8004000地址开始拷到0x20000000开始的连续48个字空间。
2 ?+ R3 k4 r7 S# e3 M6 [/ I, H  T$ ^# a
5 R( _% G# s$ q, B* F) @
0 T9 q, g8 l, ^2 l( i
基于MDK环境的相关参考代码如下:        6 j: T* ?$ E7 d9 U- K3 j

  J# L6 z2 c8 ~/ U) D% p  v/ P
/ r+ e8 p3 ]. F2 H4 C
4.png
$ i& U4 z% \0 j' g0 \8 _* j* a7 {( w* w: i7 s* I3 t0 k6 \# f5 u' I4 t3 u

( ?. t2 Q* R0 X; b; ?! }上面代码中绿色语句就是实现中断矢量表从内部flash到内部RAM的拷贝,而红色语句则是为了实现程序0地址执行域的重映射,即将程序运行的0地址从内部flash的0x8000000通过重映射机制切换到0x20000000,为的是在APP1区发生中断时CPU能从正确的地方准确获取相应中断矢量地址去执行中断服务程序。
. d% h5 M, }1 t  Z5 n! X! r
% i2 W( Z" P/ t' A到此,从BOOT区到APP1区的跳转就算完成了。5 y8 c6 s8 V+ w) O

" W$ ]8 U* e2 `' C' Q' n二、从一用户应用程序区【APP区】到另一用户应用程序区【APP区】的跳转9 [" H# j4 i: {5 S
1 C9 x# V1 Z7 f* q1 v8 s
1 z9 ^( }, u. o) i3 m. _
那么,如果想从APP1区跳转到另外APP2代码区呢?这个跟从BOOT区跳转到APP1区类似。在APP1区的跳转代码这里就不说了,地址给对、代码写对就好。APP2区的代码也同样必须做中断矢量表的拷贝和0地址域的重映射。这里因为在APP1代码里已经做过了0地址的重映射,所以就不必重复做重映射了,只需做拷贝操作,即将从0x8008000开始的48个字拷贝进0x20000000开始的RAM空间。8 p7 F0 d6 ?* n- N% k. R4 x- [8 ~6 r7 O

8 J3 ?' w5 ^* I
0 o8 s- Q  \  r( B  Z3 r
假定APP2代码区的内部flash空间安排在为0x8008000—0x800C000。MDK环境里memory布局配置如下:8 V' n, B2 V7 |. s* n# P; H
$ n+ D, H. Z% _3 a
: u9 S5 B3 c9 `: G1 [  z
5.png ! Z: ?& A7 @4 u! a; o1 n
% F3 g# l2 v& ]" A
3 I' L4 t4 H2 L6 B0 K. C
三、从用户应用程序区【APP区】到用户启动程序区【BOOT区】的跳转5 ]0 i$ A. K+ ~! P2 V3 _$ N
" a3 V- i( H  d7 W6 E; y6 E
有时我们还希望或需要程序能从APP区跳回用户BOOT区,那如何操作呢?对于STM32F0芯片而言,程序执行区从APP区跳回BOOT区跟从BOOT区跳到APP区还不太一样,经常有人在这个跳转过程中卡壳。+ B& e, G% T* |7 A+ F  z
" W. j) B+ a$ D
假设从APP2区跳回BOOT区,在APP2区做跳转准备时除了给定正确的跳转地址外,另一个要做的就是再次通过重映射操作将0地址映射空间从内部SRAM切换回内部flash区。实际应用中,往往因为忽视了这点,跳回去后一碰到中断就问题来了。另外,从APP区跳回BOOT区无须矢量表的拷贝操作。所以在APP2区执行跳转前只需将0地址重映射回内部flash空间,通过运行如下库代码完成:__HAL_SYSCFG_REMAPMEMORY_FLASH();' [7 W8 N. }+ _# x% _
8 {, i  l. m% }4 C1 Z
小结:: Z9 R6 M: \% R1 v( H; C

2 Y+ X, X. Q; P8 B4 Q* R
8 H, G+ a, }  c% K1 q1 X3 U1 o
1、从BOOT区跳转到APP区,在APP区要做中断矢量表的拷贝和将0地址映射空间从内部flash切换到内部SRAM起始地址。& }% [2 q# s& i$ B
$ v, ]) E5 J; m8 \7 k; M( [& ]
* t# U3 [( ^7 R9 E" t
2、从APP区跳转到其它新的APP区,需在新的APP区的代码里再做中断矢量表的拷贝,并保证相关存储配置的正确。
0 `4 p) v- @6 ]8 v1 i' Z+ t( P7 a! _% y
5 s- R4 ?' \8 B/ b! V# j7 W; g* o; ^
3、从APP区跳回BOOT区,该过程无矢量表的拷贝,只需将0地址映射空间重新映射回内部flash区。) |* ?1 E7 s5 o3 M. r0 E
! o& k, z6 F( T

, E' u$ j1 E: e4、不论从什么区跳往什么区,跳转前禁用当前用户打开过的所有中断使能、并确保无未处理的中断请求存在。8 p5 e. V' I# T6 Y2 u. E" A9 H
7 v$ }; e  ]7 N9 Y$ T6 i1 b

+ \# I3 X/ ^! m. |( ~5、以上操作流程主要针对基于ARM Cortex M0内核的STM32F0系列芯片。
; x: W9 ?/ ]) M" i$ }( i
, G- D. B: m. i+ g: |1 b3 b" X
+ g5 T; n5 C9 \: e
赞 收藏 2 评论0 发布时间:2020-1-8 17:04

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版