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

【经验分享】串口进行STM32F0的IAP移植手记(包括RAM&ROM地址设置)

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序* {) [  @. ]1 e3 H) y, n0 \2 Z
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。
/ j& \" |; V/ w) r1 [: g! K& |) q) l. @8 {) d; {9 n
. K1 N; N. w3 ?/ n* E* e: J
2 KEIL下移植8 w: j+ N4 B) y3 a+ x
IAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。
* K, l! D* e& D" Q$ J" [# R: y, P3 h  o2 R) E7 \: \3 D+ P  E* M
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,
& U' ?6 ~  f6 M

9 l1 A5 _. @$ E  d3 {2 W

, G' L/ e5 n) n7 _! X
20160728204029911.png
  m; V2 P9 Z# e* [

0 n; Z/ c* ^* R# r
. }" E& q( K2 V- R8 M8 `# `
并编译,结果发现原始的公式是编译不过的,如下错误信息:

( A% F8 D2 j6 a  w" O7 ~: F& I$ C8 T( ~. u1 w, t5 S" q: m2 p

7 r9 u2 s, G1 e4 X6 P: v
F6`I@6LD$B)$NXX9ZL7YH.png

+ D0 K. ~% C$ a) ?- j) ^$ ^" d& _5 ^6 {% c
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。
# B; b, E- D3 w仔细查看代码,发现main函数之前这么一段:

7 _; u7 H2 ]5 a8 A! m$ U
0 Y2 K5 J" p5 ]! T5 d1 v0 N
' d* |+ X- o2 z8 G
%OUHQSFZW]KE6YY14U8V{YX.png
# \1 z  o7 `1 S6 _" n/ }0 f
9 ]$ k/ j& A3 M  {+ L
可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

5 m; D9 T0 w. H9 o% g$ z: o7 y5 E+ c* j& {4 @' \& x/ E2 `% B
- U" E6 N+ J9 w* I* n, k3 l, u! t
20160728203625097.png
/ D5 k6 A- P0 _2 f
1 I8 |; u6 h$ e7 K* Y

( _6 s$ F0 e- q) K: [再次编译,错误就会消失了。
0 m; U8 ~3 L, s6 T, o1 \% A# q8 L6 U/ f. O% k* t3 B
另外需要将main函数内前面几行代码做些修改:

2 g) r, N. @0 J, r; X# ^4 m
  1. int main(void)  - ~+ f; V6 ]4 Q  Y/ W
  2. {  & j9 \: G" w! D4 K6 A0 D
  3.   uint32_t i = 0;  9 {& {; R+ y8 h6 }" s
  4.   - Q! ]9 w! o. n" R0 N$ ?
  5.   /*!< At this stage the microcontroller clock setting is already configured,  
    1 O& x% w$ a/ r
  6.        this is done through SystemInit() function which is called from startup
    2 c% p  w' I- s! y4 ]+ z8 w
  7.        file (startup_stm32f0xx.s) before to branch to application main.
    8 N" [. w: q* j; t; a2 I
  8.        To reconfigure the default setting of SystemInit() function, refer to
    + w! N/ g% N& t; t6 k5 _& Q& c
  9.        system_stm32f0xx.c file 9 p7 N% G. ~5 [
  10.      */   
    7 U8 R* L) D7 d, y" t) H. {% |: E
  11.   . y3 I: `0 [+ Z4 e% i1 G
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/   
    ; Q( e' C; O% W/ Y+ u# N' r
  13.   2 ~: e6 b* ?$ t& X% ~, l9 [
  14.   /* Copy the vector table from the Flash (mapped at the base of the application
    * N9 C7 x, G5 a% H2 h
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  . ^# ?4 L+ T: {" {; V# m" V* h
  16.   for(i = 0; i < 48; i++)  
    2 y) W3 S8 z1 t" e
  17.   {  - H6 {+ _0 K! @5 p" L' ]
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  
    $ d8 r% s8 _7 v0 N. d; w& S
  19.   }  8 |2 T8 Z: C( |$ V7 O5 @' _
  20.   1 ^0 ^8 v; e  M) A2 _, D  d' N
  21.   /* Enable the SYSCFG peripheral clock*/  , l  d& |: \* t1 }5 x# u3 w
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   7 g+ M$ b9 C3 F5 }. a8 j
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  / p( \' R1 c- |$ ~+ H: e( r
  24.   /* Remap SRAM at 0x00000000 */  9 B' F% j* S. Y. R8 h
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
    7 Q1 `$ ^5 r9 G2 U
  26.   * Y+ S0 {$ Z" G  D
  27. /...  . b& [3 f3 E* S/ ]  v
  28. }  
复制代码

% B3 Z5 Y) v0 W: h
8 h$ O+ g& F& v打开对应的map文件,有如下内容:

5 v& E6 N5 L3 K) u$ o
  1. [plain]  view plain  copy+ y" v4 D% S* S+ J) S5 k, v
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  / j' \# n4 g: Y4 \) x* W
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  8 o  @0 e5 x+ G. `5 c- z9 v% ~# \
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  
    % I1 k- Z0 A3 C# c
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  " K+ ~3 j  N( X# r6 f2 M
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    4 ^# s5 |% M& R" g3 J
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)    F4 l  x% C3 S' i0 ^' X
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  4 r! {2 P! t8 _/ _- I
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  7 B9 h* K$ T- Y7 Y% u5 m. u
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  
    * K, A, ~" B- ]3 O% U  e+ B% r
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
    - [* L6 D9 C7 ~* x/ C+ r7 D
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  ! r5 E' ]9 d2 Y3 q/ f
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  " S, t5 Q" Q$ O1 H# ~- y
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  
    3 ^9 E- C4 c, C9 G
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  , G$ z( i- l. l9 ~2 ~) `/ Q
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  + n4 k0 o/ F/ Y! F& s# n2 i8 [7 v
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  ' V4 X: a( T: s/ ^6 y" L
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  2 u7 e: w  t1 X5 l. N4 y4 |
  19.    Region
    + ~* W; W. m( @# E  f
  20. Base                      0x08003504   Number         0  anon: \- o8 a& v- |* |* R
  21. Table)  
    4 I9 V# d. T' F# p6 S- a0 z
  22.    Region$ C) S# q3 {# q. p* z
  23. Limit                     0x08003524   Number         0  anon( R/ z; M% ^( C( c9 d9 `
  24. Table)  + V5 j  X! V4 F  g# f' r* U$ T
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  2 I/ [3 b8 O5 B/ f
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  
    5 k: g. b, j1 G* @
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  0 ]+ [2 `0 _* a6 M
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
    ( s4 o2 n( W5 h* G- V6 N
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  
    * \  g2 _# D, \) ^. V3 J
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  
    ( L! \+ S: H1 a- g: u. S
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  
    ' b5 j( Z/ u$ {: k
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  
    ' S/ j1 V: v! `& c5 v# r, T$ j
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码

( m" T3 K' u8 D$ L3 s如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

0 p; R/ h4 u+ \6 C" P9 U" N
* R/ @9 n# r4 r注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。' I% `6 R9 J- z* A; f% F

4 [8 ]8 v5 [9 r2 o' w- g; j$ m" \5 j4 R% f1 F8 m. i8 v1 L+ L
3 IAR下移植
  B+ E. A* Y( v$ S" Q  s- r" W3 \

在IAR下的IAP没有什么特殊的,主要还是看APP的配置。

使用IAR打开APP工程,修改device为STM32F070:

' i8 |3 u4 F- }. t$ @$ Z. M2 ^" g2 h/ W

20160728213900343.png


! {2 N2 k  d5 O5 b, V2 }


1 W; y& H4 v) v' L6 f; K- Q

链接配置:

中断向量表:

/ t8 W+ z* Q1 T" e+ P- y

20160728213954703.png

7 Z* E. A3 b" n) z


- g% J# W7 N5 O3 N3 I1 b5 e& s6 S- h

内存映射:

" @  _' X$ J) J! A/ l

20160728214047079.png

1 c+ t( z3 u7 n9 n; {


) O: b2 D" L6 X2 R1 f

如上,APP存放在FLASH的位置0x8003000,内存还是设置为:0x20000000.

编译后,打开对应的map文件如下所示:

  1. Entry                      Address  Size  Type      Object  
    5 M; o! T. s" i# z
  2. -----                      -------  ----  ----      ------  
    ) w' ~  V- b; g* S+ h
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  + u& u! p3 b& Q6 b
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  
    ! I. h/ Y+ z/ P" D8 g4 ^
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  & }# X/ o3 g1 y
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  3 R/ C+ @; I; ^9 l
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  
    ) T, c% N3 X. t( N  P$ g5 V" q
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  2 `5 I# W- h$ y
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  
    % [: V" N; Q- ?9 p
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  
    3 Q7 K2 T2 m8 I/ ~- Y1 U  ]
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  
    5 g, i2 ~+ P* b! p* W
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  5 W: W1 K& h; E
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  : r: ?( I& }( E+ \
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  ( j+ _* q7 u- W1 y
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  ( r1 i1 V8 o. S7 {' J
  16. Region
    7 k+ w4 x. J& `  J2 A5 ^4 `
  17. Base     0x080034fc         --   Gb  - Linker created -  " A8 p* h6 d' O, p5 Y" X
  18. Region
    ) @- g' G! R, {' `" y) m
  19. Limit    0x08003510         --   Gb  - Linker created -  5 \$ s4 H: i1 {4 O) z+ G( X
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  
    0 P. A' Q; ~9 G9 u8 w  G# S7 B
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  9 O9 N6 _/ X  n. Y7 v5 \) _
  22. SYSCFG_MemoryRemapConfig  $ ]* ?  M  b$ |3 C$ x
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  9 A$ R5 o: z. I' k# w
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  
    1 p5 A' ?* O7 e: b6 `1 f: J' M
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  
    1 e- D. l2 K7 _5 f: O- {
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  8 z% `: H; ]  p$ f) A
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  9 _4 V, s9 D5 ?& c9 v
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  
    ! D' D* {7 c8 x$ R
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  
    7 r5 H1 `# Y) r
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
    - H  e, K  Z( H% K' Z
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  5 s' n6 ]# k8 ^; j( y' S
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  
    : K4 m- u, w9 H
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  1 d% D$ _. q, k  n/ C
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  8 r! Y" a  S) _! a" {' }$ ?" n' |
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  
    " A4 f, O0 F' F9 k
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  + C" ]! y8 }# x
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]    w% X& F* S$ W( ]1 Z4 z
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  
    ' c* B- d" e( n% k+ R! k  |
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  9 \6 w) L" R- b! a
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  3 j0 q% b& K- m* P4 k' k# R/ ^
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  
    - c$ E% c4 Y6 @! O
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  
    4 T; H" j* C/ h( z" r  X0 Y3 K. ?
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  
    * [0 b( ^. Y8 r- ?' S' r
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  
    - D: C) m+ s- |  s
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  * x6 p; A3 G+ w7 X9 h0 ]
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  ) ~3 ~7 G) o: I7 m" ]" `9 @5 u+ q9 [
复制代码
% C5 I- K! T, r8 B. M: ?2 z3 Y
如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。1 R7 L. N# j: _' v# [0 i" X  F
3 T; n# a$ |7 h, J

注:从IAR工程的链接配置来看,并没有像KEIL那样配置RAM位置为:0x2000000,编译后的结果向量表也不会与其他全局变量相冲突,可见IAR编译器已经自动计算并避免这种冲突,不像KEIL那样会出现链接错误,以此来提示用户。


( E4 k1 o. Y8 n" r

另外:在IAR下,在不存在IAP的情况下也是可以调试APP的,这点是KEIL所不具备的功能,看样子,IAR在细节的处理上比KEIL要好。


, B( m$ c& j, S- P/ G3 G6 T0 y, D3 D  [8 ?6 {: ]: f1 H$ Z. t" y
_HVKG9_``N2XH@$PGJH2}C4.png
JWW28BWYG`WTNXJ1YX2]391.png
C06]7O30B9NH`XRI6UW`QRI.png
F6`I@6LD$$0B)$NXX9ZL7YH.png
20160728204029911.png
收藏 评论0 发布时间:2021-11-22 22:03

举报

0个回答

所属标签

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