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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序. Q9 Z- q2 }. E7 j2 K, O5 b
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。
6 O+ m3 t/ i% ~0 X3 c' I5 {: T: q3 O# o# y4 \
4 m! y0 }4 A0 D& J: N+ D
2 KEIL下移植
7 I' M; Z# G3 {6 H- |; UIAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。  T* r4 |4 l3 D) \1 e+ ^' e3 f& P
- F! T6 ~, Z, z& V
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,
0 _' X, D2 @; Z" B& F0 J

) J- v% U  ?% d8 ^1 e. i4 A

! Y: e. ]5 R+ Y2 J  _1 E; p' H
20160728204029911.png

4 F/ k0 [, r9 F* N* c. g5 V9 B2 l  C
- D+ c2 @/ h2 B/ }) K) C7 [
并编译,结果发现原始的公式是编译不过的,如下错误信息:

* Q7 i9 y2 I3 J# m( x/ y- w/ g4 f/ v$ P5 t. P# o( \+ h4 f

4 h! `# _0 v& O% I* P4 X: O7 n
F6`I@6LD$B)$NXX9ZL7YH.png

- Z7 M8 Z+ N; C2 a3 \& H, p0 O0 E+ M# ?) h% ^4 V) T# |" U
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。
0 P' {. I+ F3 U仔细查看代码,发现main函数之前这么一段:

% W9 H5 [& |1 i/ ?* V# ^. v
' Z0 p4 j, ?- g. f, S
$ d' _' K5 f* P
%OUHQSFZW]KE6YY14U8V{YX.png
; A! \& G  N1 m9 o2 K

, a% G  I& O& _9 r; P1 g6 `- I可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

& g* N+ ^% g7 ~; b0 F
/ {& ~: i& x% x2 z/ M

7 ~9 g/ g7 K. t- X
20160728203625097.png
" p7 V; R3 c4 ^1 E  n1 O# M
) ?, ]0 G3 c4 w

+ a2 V& ^3 U( W& I, h  v再次编译,错误就会消失了。, h. g/ y; _; ^- J0 w. ?, x6 Y- [
5 P7 c6 J/ L# }
另外需要将main函数内前面几行代码做些修改:

1 u8 n' p' Q1 l9 D& X* G- F  m* q
  1. int main(void)  4 |' p* U9 j5 J; \2 C4 A2 y
  2. {  
    ( Y. {$ `& ?* j% W  h
  3.   uint32_t i = 0;  
    & `9 V' l9 S% J5 ^6 |
  4.   
    ) [, o+ s6 @% _% Q
  5.   /*!< At this stage the microcontroller clock setting is already configured,  4 f' ~1 ]# L% ]  w- P* w5 a& t( h
  6.        this is done through SystemInit() function which is called from startup
      O" |9 v$ m/ A/ Z% V; l  |. d
  7.        file (startup_stm32f0xx.s) before to branch to application main.
    % w8 x8 K4 G3 f% L2 n
  8.        To reconfigure the default setting of SystemInit() function, refer to
    9 k$ I% N5 Z/ v
  9.        system_stm32f0xx.c file
    & A( B$ W* j; Q( H
  10.      */   , B1 }& y) t) q
  11.   & `% o# D  }: @: v/ e- }
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/    / N7 i* [: o/ ], C
  13.   / Q3 N, r9 Y* `
  14.   /* Copy the vector table from the Flash (mapped at the base of the application ; l% C$ W8 B3 O1 m0 T8 {& r
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  
    3 A, I/ a3 o: O/ J% c/ C. z7 T
  16.   for(i = 0; i < 48; i++)  : Y4 q' i; B$ H9 W
  17.   {  : p3 b& t9 W. ~* w0 q- b* E' S
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  
      h+ U) n5 I4 e; ^
  19.   }  , l9 I+ \" l, ~" [& B
  20.   / [: n, y8 p# _3 k$ b: g
  21.   /* Enable the SYSCFG peripheral clock*/  : d9 x% a9 [  E8 \4 ?6 l+ o! J
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   
    - k- c# `6 F9 s' t* M, Y" S. @
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  
    + A3 ~. A3 e+ V. r3 l+ G. W
  24.   /* Remap SRAM at 0x00000000 */  
    " B& B3 K3 J5 _& T  b& ]
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
    - H# ~3 ~9 _& `/ v4 r
  26.   . s# G. F: B0 Q$ j7 Y9 O* K
  27. /...  
      c& W+ {$ t6 j  r/ X1 z
  28. }  
复制代码

6 x) E& G5 V  G# i6 {( b( K  `" n* n1 b$ g6 c& @1 ]0 `
打开对应的map文件,有如下内容:

. w2 B6 K# z) B2 B3 h
  1. [plain]  view plain  copy- F  M/ M% }  Q, k+ p( d0 p
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
    & m) B3 q! J" `
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  0 ?7 V. G' d9 ]% c$ P5 n
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  3 ?( F' q8 V% J* h# R' {  Y
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  
    8 d3 b4 k+ s1 G/ C
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    . G3 G1 H5 A! \/ c! t
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  $ A: g: V' G0 B# u7 o
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  : L0 a! W3 a; r
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  3 \! g9 E( h  E' W
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  6 b  i, L, b5 L) c, h
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
    6 A! v- c) I6 w
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  8 B+ C" B3 T4 w" i6 b3 G
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  
    . S/ m  @6 S5 g  X; d7 {* y
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  5 K4 }2 v( t0 p: l0 T' M
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  0 z: [( ]2 |  p! \6 `& i5 Q* `$ j' O$ B
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  ( S. g# a( p8 T9 G& k
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  9 r4 M  \" k0 n! _- v
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  * x* T! f0 u5 N- d; \" @  U7 f
  19.    Region/ W4 p* n! C, e: f( Z) e1 D6 r
  20. Base                      0x08003504   Number         0  anon
    5 g8 h  D8 _8 G% H; K1 j5 V1 ^
  21. Table)  
    9 U; H" s0 ?6 `, E
  22.    Region
    0 \9 E7 s8 M( m( a9 U! H/ L
  23. Limit                     0x08003524   Number         0  anon. I' r0 |' C/ }; g& i
  24. Table)  
    5 z2 H+ l- b; A! W$ e& B6 W' j
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  1 w6 z7 B- n8 M- A. I. k  @
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  
    9 Q/ t. o2 b6 X' Z% P  ~, P
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  
    & q! \- ?/ b6 h9 Y4 D3 L2 M! \
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
    # n3 M& l3 C, Q' s& V
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  
    9 z* E, P, Z1 V' v5 Y$ E& }' `
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  
    & ^5 U) L: P( F; @
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  
    9 p: m4 b9 {4 z. ^, C$ A4 T! Z$ ^
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  0 [) ~% j: n# X0 V4 ]: {
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码
$ O0 Q+ |% B4 V$ Q; \
如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

* [4 g: Y9 G2 X2 {) B  g6 c5 N- W9 V3 f
注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。
1 F9 W/ q: E* B$ k2 k: V# i8 L* Q% S' B% p

, Q9 Q, O4 c  v3 IAR下移植
" U6 b2 k% u  o+ u& y

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

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


  p! ?  G; E' W" L4 N) D. u# l) m

20160728213900343.png

; A/ D" ]7 A5 C  P. a& k4 u4 V


8 x) S, `& |; E, S6 U- v

链接配置:

中断向量表:


5 F6 ~; R5 H0 `

20160728213954703.png

- L/ u3 ~) ?! K' w" }


& k5 b' n3 N6 z; c$ r& S5 X

内存映射:


% J# |. X. I+ f; }  P: }

20160728214047079.png


, h/ |& r7 L/ f3 L

  [$ C* b! d0 l' W, i

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

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

  1. Entry                      Address  Size  Type      Object  
    5 p5 ?7 g/ _; q) f& P" f5 E( H
  2. -----                      -------  ----  ----      ------  
    + j/ [+ [' l% z( V0 X4 R" c! }- o
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  ' p& Z. F. n3 f2 I5 Y
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  , S: o+ c5 A/ N& q+ V
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  . H5 D# q2 a) ]0 ]$ ~) N2 U
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  
    . ?! B1 E' w, f7 Z4 J, }" ]
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  " z8 ]+ F- v, e
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  
    ; u" I( s9 h4 p5 \$ d, t
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  ; _% K/ T# Q( X) P8 a
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  0 V- x# g( P! P0 b. ]
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  1 M0 d+ l7 f$ Z; v, ?
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  9 k. q6 x" {8 \4 V& m6 q
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  
    : R# b3 Y) p! e  N% ^6 ?
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  0 X- Y3 N6 G' \$ ?
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  
    ) `4 S$ M+ a4 X+ j0 M9 a3 ?
  16. Region
    / V' J# F& Q( H( V. a
  17. Base     0x080034fc         --   Gb  - Linker created -  ) E3 i+ d2 q1 j! i; Q
  18. Region
    0 w/ V1 d! v% [$ o* `; a, c9 n% s
  19. Limit    0x08003510         --   Gb  - Linker created -  
    4 z2 P' D' c( }
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]    w6 _; C, I. @; M& v8 ^
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  * R: I8 B4 z2 a* M9 t
  22. SYSCFG_MemoryRemapConfig  
    + r6 n/ D  c4 ^1 B* I) A9 N) R
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  7 U1 @) ^8 d2 ]
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  % o- H& J3 s5 X$ i6 M9 ?
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  7 j4 x5 \( z! \: x" f
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
    ( j) o( z9 ^4 Q) ]: V9 J
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  
    5 d4 Y9 l! i: g7 i9 b3 ?
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  
    ' ]; ^2 l1 L0 q7 M
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  9 @/ B" D5 [% v' `  a
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  5 s4 N1 {7 A  J+ J2 ?4 g" p
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  + v. J8 Z8 O: ?# q1 M4 F
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  7 ?( R$ |- p7 r
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  : I2 ~0 u$ y. g/ B0 i
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  . Q! C  B8 J$ ~+ F2 U! D: w
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  
    $ K) L! Y+ x! K: ~$ ~2 }
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  
    9 y& a2 o& e1 q/ E7 i8 x
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
    6 T7 ?+ n$ [5 y
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  9 Q; q- W/ \, g6 l! [$ X3 E1 U- f: u
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
    5 |) ~7 s5 J; e# T$ a! U/ T+ A
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  + K3 ?) V# J1 A+ K9 z, Q
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  % {9 D+ D( z! B1 u& X' A4 r
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  0 m* t) G% f( m# N
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  
      ^; X2 k- C) P* A6 v" J. W" m
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  
    ) R1 |2 y3 m+ z; r0 }3 V( Z
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  
    6 V8 a6 C, g. S% E: ]$ ^  W
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  ( [) v. W. `$ i4 `; l# r" E
复制代码

0 N: H; W/ }6 _7 K如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。
0 k% M6 ^& t2 l. H2 G6 Z. O1 R0 v. e% X( b2 ~% [

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


' p" v& _3 p. c8 K6 G; g8 w  ~

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


/ e9 Z: w: F6 k1 D- n, N3 U. g* p- O' Y4 s" o
_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管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版