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

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

[复制链接]
yumeii 发布时间:2020-1-8 17:04
对于STM32用户,经常会涉及到通过用户启动程序实现对用户应用程序的更新升级。一般来讲,用户启动程序主要用来跟外界通信,获取新的用户程序代码并实现对用户代码区的应用程序升级。
, F3 E6 q! Q$ l1 {8 {4 B
) o0 ^7 u! _, Q  k
用户应用程序是指实现各种用户功能的代码。在这个过程中,往往需要做从用户引导程序区到用户应用程序区的跳转,有时可能还需实现从用户应用程序区跳回到用户启动程序区,或者不同用户程序区的互相跳转等操作。在这些跳转过程中,往往有人在此遇到阻碍,破费周折,尤其是在使用基于cortex M0内核的STM32F0做IAP应用时,这个过程跟其它基于CORTEX M3/M4/M7内核的STM32系列相比,操作上不太一样,实现起来稍微复杂些。
5 Q; `) e: B  E: s, g3 e; u, g% F  Y
这里就STM32F0芯片内不同程序区的跳转问题做些交流与介绍,限于篇幅,仅直接介绍具体操作和注意事项,不做过多拓展。相关知识点可阅读STM32芯片参考手册、STM32相关ARM内核编程手册。
0 P( S+ T" M  `+ A8 r* ~  \6 }! G4 L5 ^* ^% M) i5 u$ }& U
下面介绍中提及的集成编译环境是指ARM MDK,硬件基于STM32F072RB Nucleo开发板。后面我将逐一介绍从BOOT区【用户启动程序区】跳转到APP区【用户应用程序区】,从APP区跳转到另外新APP区以及从APP区跳回BOOT区的基本流程及注意事项。( n: d0 w; }& l( s1 N8 h+ V

, P5 N0 [2 {( {1 J# V& O* v1 C( L& ~一般来讲,不同区段的执行代码我们通过建立不同的工程项目来实现,最终将不同区段执行代码写入芯片。这里假定用户BOOT区对应的内部FLASH地址段为0x8000000—0x8004000, 用户APP1区对应的内部FLASH地址段为0x8004000—0x8008000, APP2区对应的内部FLASH地址段为0x8008000—0x800C000.
* w8 N! H6 P) d0 V* _$ Q5 s; A6 z" ]0 O# |/ O" {
; d% P* ?/ c# X# {6 |& x) @% @2 O
1.png
) C- M! n$ V2 c0 b6 e
. p; l* a7 N# O1 N& k

: h# _0 x  t( T7 d) j1 _" N% `) T: T一、从用户启动程序区【BOOT区】到用户应用程序区【APP区】的跳转
; f7 s; D6 f! ^3 v; l( I' g! n* c! T" s% m$ H
  |6 B# k( S. D+ x2 \4 ^
先说从BOOT区跳转到APP区。跳转代码比较简洁、简单,注意跳转前要关闭刚才程序区开启过的所有中断使能,保证所有中断请求位都被清除,不要只是简单的关闭总中断,否则往往隐患多多。BOOT区相关跳转代码如下:) R' |0 v3 _/ A  `! r) g) Z

! M; ~; ~7 y% ]5 O4 y  Q. O: J
" Q/ R/ d2 z% @' }0 p/ ^
2.png
1 S+ y5 a( |# T( v" R. a# V1 F
) O0 z7 n# X, s
) k# y% \# _6 n! V  Z
这个从BOOT区到APP区的跳转最终能否成功,关键取决于APP区代码相关配置及准备工作。假设这里的APP区是上面提到的APP1区,内部FLASH地址段为0x8004000—0x8008000,那么在MDK的option项里的memory配置板块要做正确配置,即flash空间与ram空间的配置,如下图所示:
' D. j' {: D+ E0 k! P3 c  M  u7 ]2 W' I
% W/ L5 I4 ^! m* [2 Q
3.png
5 b) D1 y. A2 O' a: M" S& O. }3 u' T; q% Y8 n0 e$ H# X& w  |- r
) Z) b- ~8 Z; a  \$ {
IROM1的配置就是APP1代码摆放的起始空间地址及长度。IRAM的配置要注意先保留48个字的空间用来存放中断矢量表的内容。因为stm32F0芯片的中断矢量表的大小就是48个字【即0xc0字节】。至于剩下的内部RAM空间大小由芯片本身的RAM容量决定。【这里是基于STM32F072RB芯片,其内部RAM总容量为0x4000】。
/ x% }2 E. u  @7 e2 v- Z* m6 s
2 A9 L; R3 O( L5 j另外一件很重要的事情就是做中断矢量表的拷贝。在APP1区的main()程序开头部分,将放在flash程序空间起始部分的连续48个中断矢量地址表拷贝到内部RAM的起始地址段。即将矢量表从0x8004000地址开始拷到0x20000000开始的连续48个字空间。+ ^& G7 P  s# Q6 h: H$ Z$ u

6 x3 ?2 D$ g( Y" A; N/ s% Y
. {  |: u1 `2 o/ W* R, V
基于MDK环境的相关参考代码如下:        
2 i) |4 a4 C, y" U
- N  ?2 e- @* V+ y/ H
: A( M% [8 s  t( E& i+ ?
4.png : P  c- u+ ^) E8 T
1 b8 w3 i5 w7 @
) R, X' D' `4 [. e8 T; o
上面代码中绿色语句就是实现中断矢量表从内部flash到内部RAM的拷贝,而红色语句则是为了实现程序0地址执行域的重映射,即将程序运行的0地址从内部flash的0x8000000通过重映射机制切换到0x20000000,为的是在APP1区发生中断时CPU能从正确的地方准确获取相应中断矢量地址去执行中断服务程序。
3 e1 e; t" @$ c2 H$ r8 d' ^8 S
6 w& Z  T5 H( U3 z* F. j/ F8 k, B到此,从BOOT区到APP1区的跳转就算完成了。
4 L% z. e0 P8 i# Y4 k
0 N3 {- p- P$ c二、从一用户应用程序区【APP区】到另一用户应用程序区【APP区】的跳转
( n- @% D. ?$ j6 B3 b) }% ^+ x5 x3 K' y. ~6 c
. l6 l6 H( A/ l0 h( I
那么,如果想从APP1区跳转到另外APP2代码区呢?这个跟从BOOT区跳转到APP1区类似。在APP1区的跳转代码这里就不说了,地址给对、代码写对就好。APP2区的代码也同样必须做中断矢量表的拷贝和0地址域的重映射。这里因为在APP1代码里已经做过了0地址的重映射,所以就不必重复做重映射了,只需做拷贝操作,即将从0x8008000开始的48个字拷贝进0x20000000开始的RAM空间。
& X' Z+ Y. N) R+ s+ h9 I; O5 d; [0 f; T* `. P) N3 ~) U: o

! O3 M% y% J- N" j. _假定APP2代码区的内部flash空间安排在为0x8008000—0x800C000。MDK环境里memory布局配置如下:
, n. R* O& p3 w( p+ ^$ W% K: S' o% r, ~" n/ V2 p7 ~" M- Q1 U/ u

; Z2 x5 |' w- w" ^( I 5.png ) M. D9 e( W: `) |1 p$ U- P
- q( D0 m* E- T1 j
' Q: W. t3 t" r$ H" x; L
三、从用户应用程序区【APP区】到用户启动程序区【BOOT区】的跳转, X! f! V2 n8 E, \6 s
6 m8 Z' ?0 m& z6 }. Q8 Z1 H
有时我们还希望或需要程序能从APP区跳回用户BOOT区,那如何操作呢?对于STM32F0芯片而言,程序执行区从APP区跳回BOOT区跟从BOOT区跳到APP区还不太一样,经常有人在这个跳转过程中卡壳。
2 y6 l: v/ U9 M$ b* w; e) f3 K" W+ f) z2 o' _
假设从APP2区跳回BOOT区,在APP2区做跳转准备时除了给定正确的跳转地址外,另一个要做的就是再次通过重映射操作将0地址映射空间从内部SRAM切换回内部flash区。实际应用中,往往因为忽视了这点,跳回去后一碰到中断就问题来了。另外,从APP区跳回BOOT区无须矢量表的拷贝操作。所以在APP2区执行跳转前只需将0地址重映射回内部flash空间,通过运行如下库代码完成:__HAL_SYSCFG_REMAPMEMORY_FLASH();
& E6 p  c; v7 N: X, V+ l7 v8 W) Z8 b
/ ?; x0 s# Y2 m+ |$ t: b小结:" `- X- g' M  w$ S% B0 d
7 u" ]- Z: a8 l) ~$ ]8 y( Y  m

) k. B/ F: ^! d7 d0 Z7 t$ F0 y1、从BOOT区跳转到APP区,在APP区要做中断矢量表的拷贝和将0地址映射空间从内部flash切换到内部SRAM起始地址。
: l5 C+ b9 j/ ~9 q7 M- g
$ _2 g3 e7 v# A/ p1 E9 b
5 f8 k% e, e7 W8 m
2、从APP区跳转到其它新的APP区,需在新的APP区的代码里再做中断矢量表的拷贝,并保证相关存储配置的正确。
; q$ c& I5 x3 G9 u( U
5 U+ y& c3 N! t0 ]5 ~
! H' f' o* A+ }( W. f
3、从APP区跳回BOOT区,该过程无矢量表的拷贝,只需将0地址映射空间重新映射回内部flash区。+ z5 \6 l4 C. L" d- I

, [- o4 ^0 t8 w- t

/ Q" y2 `  ?& E8 s$ Y6 m4、不论从什么区跳往什么区,跳转前禁用当前用户打开过的所有中断使能、并确保无未处理的中断请求存在。
8 r# J8 m2 E1 t8 Q  Y
# h# e0 B) S& b& P, y+ C
8 o8 |$ J3 s( h$ m: x; j& B
5、以上操作流程主要针对基于ARM Cortex M0内核的STM32F0系列芯片。
  k6 J( p" L  P5 n  l! z# q* J9 c# n  t5 T

3 o4 e$ [0 q; c! y" b
收藏 2 评论0 发布时间:2020-1-8 17:04

举报

0个回答

所属标签

相似分享

官网相关资源

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