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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序+ f6 @. O! `" X: m6 W3 \5 x
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。7 v2 x9 y- V' ?' Q  n9 f

4 y5 ~1 V/ Y6 Q6 s9 n3 |4 B8 Y) j
  R. R$ _8 o6 W8 |- z
2 KEIL下移植
7 K' d; g9 k1 W$ ]% Y7 EIAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。! n& {* H0 c) _$ V( {; l# N: c
  z  p; ?% [/ e% x
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,
7 N; i% G  A0 ]0 |4 ?8 K

2 [; J, H2 i: h  X
- R. H" h# \% u
20160728204029911.png
: v" c% C5 c% o/ w
5 d2 |( ~9 k7 I" y6 R( A1 _
7 |3 o! g3 B* {/ I" _
并编译,结果发现原始的公式是编译不过的,如下错误信息:
2 @. I! t1 q0 [" i9 \
/ O( m% G6 `: ]/ b* \

# S- [( J$ g/ k/ z/ T' Q
F6`I@6LD$B)$NXX9ZL7YH.png

7 A( {* i6 l: i. d. D* }/ M; K
1 D: I" U, t4 K$ G. C8 r; U/ N+ P
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。
7 C$ l! ~, H  v! n! g仔细查看代码,发现main函数之前这么一段:

; o+ m2 t/ P, c* L+ z; `9 v& s% f) ^. R

: e5 G0 z. J7 E  s  P" L! q) K
%OUHQSFZW]KE6YY14U8V{YX.png

. ^( L4 I6 V6 G* I  l* F# {4 \7 P0 N) K
可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

5 i: T  }3 J; C" b, M! D( f) z; {0 J" V2 J
5 H5 B2 u/ ~2 e7 `5 G5 @
20160728203625097.png

( m! C* L0 f% p8 Q) _1 K
4 t) t$ g3 _( d$ L& u, h4 n: D" M8 U3 f+ n# P0 d6 k& Q
再次编译,错误就会消失了。
: C( J+ O0 Y$ r5 ]/ h  j# S
; C4 B% F& X+ X- t6 u8 {7 Q另外需要将main函数内前面几行代码做些修改:

( ?8 y- z2 t" n9 L; Z
  1. int main(void)  
    * n$ E/ g5 G6 H! Z: W5 [; J1 r; [
  2. {  0 \( }4 L% F  b
  3.   uint32_t i = 0;  3 A& M6 i# y2 |- s  l0 X
  4.   
    1 P# I5 o: d: k$ S
  5.   /*!< At this stage the microcontroller clock setting is already configured,  5 u- R4 U9 x' ]/ N
  6.        this is done through SystemInit() function which is called from startup ; ]3 K; O& `+ [6 e* U' c( y
  7.        file (startup_stm32f0xx.s) before to branch to application main.
    . c' d  W) t3 F. N- O/ r
  8.        To reconfigure the default setting of SystemInit() function, refer to
    3 w1 j$ S  Z& @1 |( B% n; ^
  9.        system_stm32f0xx.c file $ a' C1 E$ n  g0 J7 m
  10.      */   & m  `8 T, ~3 y$ M
  11.   
    ( q0 i# L+ h( Z) t
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/    2 z: g; `' L9 B( L
  13.   
    : t( b6 E5 i1 Z0 {" {
  14.   /* Copy the vector table from the Flash (mapped at the base of the application
    ' Z" z* w, U1 L: w: T
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  
    # ]: B1 K) M. z. R4 P4 I$ z6 G! {
  16.   for(i = 0; i < 48; i++)  . G4 c, M3 c, O4 E! {
  17.   {  - O! i4 G8 P" O3 Y( e
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  
    * T% C( @) d( H" H( ?$ x! \
  19.   }  
    2 q: k& A- M- z
  20.   ) n$ @( e8 Y( z: U
  21.   /* Enable the SYSCFG peripheral clock*/  , K2 R8 d4 W6 o0 Y+ {! B
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   , r9 d, X/ A9 D. K5 ]7 w
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  
    # d) `3 E( ^. x
  24.   /* Remap SRAM at 0x00000000 */  
    - ^2 C: @+ V2 I% S2 M
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
    . C: h+ t6 x/ Y) g6 q( j& L
  26.   
    6 S* Q* l( n2 x, o# r; G0 o# s/ U
  27. /...  
    2 H8 F0 O  V7 h/ h! c
  28. }  
复制代码
! `1 U/ a) g4 Z
: J4 u/ g& C+ t) w* O# U
打开对应的map文件,有如下内容:

2 a9 @+ @7 J/ G" A, n" w
  1. [plain]  view plain  copy- C2 ^: o+ e1 g
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  ' \- Q* {" F1 W9 B" g+ y
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
      o9 F8 d; W0 d% N+ X
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  
    7 s. B* _3 z, s* u* U% B
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  ; i0 ~+ R3 l* h9 P
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    ' @& S; |! a6 {9 ]7 @$ m# f7 A1 j
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  ! R* E$ C9 z& N6 m
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  3 @& r" W7 ^" k. f; g+ H2 P
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  
    ( Y1 D' E& O* v) K8 v& r
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  
      F+ ]! n; r6 w& m
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  1 F, o9 N8 {4 r* M) h& A
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  7 @" ]  O# G' g5 A3 h  g
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  
    . a8 C0 ~4 h( Z- a. I3 F* K  g, D. D
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  % v* L( I' S2 R
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  
    5 \6 F  Y2 [. Q) ]
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  
    7 o  E0 a9 }6 z" T$ B' v
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  - N1 q' y8 r  W  ^4 ^
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  
    $ r1 ?! ?$ b4 o; f8 a! V
  19.    Region+ \3 N! ~: v! T+ q
  20. Base                      0x08003504   Number         0  anon
    ' N6 w& a  N- b1 E/ N/ T
  21. Table)  1 D, M* `7 U' Y0 i
  22.    Region- j/ ?8 I$ l+ Y- h
  23. Limit                     0x08003524   Number         0  anon
    . v( ?) X! v' m6 J! ~( X
  24. Table)  
    / j& j7 {0 p! K) s( f- K
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  
    + ~3 r; u" k- I6 M: d
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  ' O7 g! Q8 L0 J3 G! I" O
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  
    & \$ o0 h2 }1 k) q4 {" g) d
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
    % a, ?1 ~% [# L
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  
    - R" H' g; L: s; Y
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  % b5 y4 {. J# I4 D  l& W
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  $ C4 R8 H3 a- q4 Z  k3 b7 w  p$ |
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  1 }; d+ {' p# A$ F8 `3 p) V
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码

0 [& e3 ^3 N- s  e' a5 L7 y如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。
! i& a3 Q( B- w4 Z& P* A
; Z# v0 E# ?7 K  Y9 X4 E- M
注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。4 S! n: E- V+ J, d% l6 s

. c  b. L/ @( ~' C1 p3 y
" y* N2 j) Y9 d9 J! {- ~# \, D3 IAR下移植
( T/ S4 m& o$ b* L6 ^$ v

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

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


1 ~) p5 J# C( j# q/ O2 v  ]) Y

20160728213900343.png

& N2 W; J' R; {" P5 ^


! r# ~4 H* Y# I- B0 P4 w

链接配置:

中断向量表:

( k( H! Y+ u2 R8 I7 o

20160728213954703.png


# @0 _0 c9 t, C/ T; @+ W' ?8 I


  f8 I! u# H1 u0 ^' }( h

内存映射:


# m% E6 i2 z0 Q+ {9 s# [. h

20160728214047079.png


( P' T0 T+ u8 L# @/ S

. |! p0 L% A2 P* e2 I  _

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

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

  1. Entry                      Address  Size  Type      Object  $ p9 X- L- M) h4 n
  2. -----                      -------  ----  ----      ------  
    # f4 f1 U2 _2 A; t8 ?4 [
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  ; A* H, V1 c; _, y" M6 h# y7 z
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  
    , M: I4 Z" c7 H( _  `
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  
    % V7 K/ @+ X: e% t$ c+ G- G% L( d' f
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  ) H. |6 }# `/ x  ^+ J" F% q
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  4 O, o" q; O7 T/ o
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  
    : ?: K$ {8 e/ ]3 l: q5 G
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  . n& J: t- h: y9 a& c6 `
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  
    " J4 ^" Y) ?4 k. z! D
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  + N5 O  {' k  X/ ~/ S
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  ) q3 M( H' s4 f: i6 U& _' A
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  
    . _% ]" |9 f$ w/ z
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  
    $ w! ]9 Y) w2 z+ G; P
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  
    7 a7 ~( T$ {, b" z# N
  16. Region6 z' \; w; n1 V; v1 ]$ }
  17. Base     0x080034fc         --   Gb  - Linker created -  , ^+ i: k& V0 u" w7 Z: P) d
  18. Region
    1 D$ w' T( z9 X; d
  19. Limit    0x08003510         --   Gb  - Linker created -  8 y4 E! a% ~6 _, s- z7 `2 q
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  
    7 H5 G0 e- u/ K  E
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  
    - Q* D3 M( S1 ^% L6 I7 `# _  l
  22. SYSCFG_MemoryRemapConfig  
    " j0 l: N7 J' f( K' ?
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  , i4 _3 H" [2 U& y
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  3 m* Y& W# |2 W* t: b  t; V
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  9 g% r; U+ a/ d. S* g
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
    / _: W2 s0 S0 p! ~. h1 N7 ~
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  , J4 {2 h) |& z' n
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  * E& k. Q) }. V9 u
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  2 K6 k+ V4 k$ c4 K& y+ s& q
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
    " Z6 m6 R  z9 j9 r! u! i
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  8 }9 N( c0 p0 r' L
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  7 E) Q# }3 [- N) m7 H/ k( ^( W
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  
    & |1 J! Z* L- e8 w* D- @0 ?' ?
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  ! C' f# f4 e2 U- v5 k% }3 Q7 G
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  $ Y9 H4 g; z! R% y% C4 U% P/ X
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  8 C8 L0 E8 ^! M9 Q5 b, @% a
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
    / B! ]( R8 l! M9 K" B" P; {; t/ F
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  
    4 Q( Z1 {  C7 Y( I( U
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  8 p/ ~  D/ O+ j: ?1 P
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  8 ]# R: `# M, x2 F+ X6 V1 V
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  
    ; [$ J. A7 x# f4 V
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  # c1 p) y& N! i* x) n% k5 ^0 y
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  
    ! P2 t' T; H2 H9 A" |8 a
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  2 v: T% C2 ]3 U  m1 @
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  & B( L1 N9 |6 q2 n! k+ b: _& W8 S0 X
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  
    2 Y% d$ D0 E. I/ W' S& K
复制代码

; `; \) T/ ~! O4 R" T7 \2 @6 ^如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。
6 C1 {& d. Q" n% c9 o% `! b6 O4 g5 L! g

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

! k+ `" i3 S- s$ |" M, a7 a

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

5 O$ D4 a# ^- B0 z5 @; w/ E1 c

& P$ J& q+ q3 U0 ]# S& ]
_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 手机版