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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序0 a9 q# y& e3 w3 i# P7 V
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。
' |$ X1 \. M9 g+ O4 J
; Y% ^2 n+ }5 ?) _. E! l

! Y5 d+ X1 [% p9 }, m! }2 J2 KEIL下移植
5 L: i+ W0 b6 t; XIAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。
5 P( I4 v/ K& w$ k) F9 L! _  F) c( d8 m% A& _  ]: C7 ~
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,

* v% z: x8 g, }7 ]: Y7 C& ?. o
4 P3 q" T' V0 L$ S6 n" N

+ q/ X" |8 r% p0 J4 t4 x. h
20160728204029911.png
6 ~. Z" e* }; P& {

( ~7 }9 S: h1 m
: ?4 Z) r+ P5 J4 C' e5 c" O+ W
并编译,结果发现原始的公式是编译不过的,如下错误信息:

1 K  A; O. g- Z% d) v4 i0 z& j% R7 r! E, H0 X, J3 D# g8 i
2 x  B# K8 B. u2 k& z
F6`I@6LD$B)$NXX9ZL7YH.png
! h4 `/ O1 h, R9 s

3 P3 y  a- _0 _  C% Z9 z6 K
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。2 K; ]0 }! P" C
仔细查看代码,发现main函数之前这么一段:
8 L1 f4 P$ y1 G- }
. |$ D: `& h7 z

; d/ @, I9 O. A8 ], l  M
%OUHQSFZW]KE6YY14U8V{YX.png
# e) e! A$ z" @# Q  Z

, T3 Z/ O* s' W+ R& N可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

0 \4 {* Q/ d+ l  k1 |! @6 X& }
& z) v1 b, A6 f/ r) J
) c( J5 {+ ^; B/ \
20160728203625097.png
( V3 X' Z2 P2 D1 I2 c: M* ~* ~

" r* g9 c/ {4 P- D8 Y8 o* Z6 u* w3 }$ _' d1 v
再次编译,错误就会消失了。% u( W3 j# Y7 ?
& U1 M. j7 r; J5 j$ ]9 \, N
另外需要将main函数内前面几行代码做些修改:
( d  u* R9 Q# h2 b% h/ R' m
  1. int main(void)  - O- `- E9 L7 h0 {9 F6 a, J
  2. {  8 a- A; |+ ^5 G9 r( S' F# C$ Z& k
  3.   uint32_t i = 0;    p  J( I; |1 m3 p4 H
  4.   . |0 [9 b/ D7 Z2 a: p& k
  5.   /*!< At this stage the microcontroller clock setting is already configured,  $ ^' W. S4 y4 |+ v' `
  6.        this is done through SystemInit() function which is called from startup ) z2 L6 b) B+ g. M+ g! s
  7.        file (startup_stm32f0xx.s) before to branch to application main.
    ' i2 t  O3 {& u
  8.        To reconfigure the default setting of SystemInit() function, refer to
    & s2 E2 [, e; v2 b  Z1 l
  9.        system_stm32f0xx.c file
    " a: j; F$ ^. t' m1 D6 L
  10.      */   
    0 z6 Y, {8 t! u$ {
  11.   
    1 y  C" T" D) o8 W- J" t0 y
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/   
    ) t2 `$ ~5 R& `+ I
  13.   
    # P  ~) v2 g" \# N# P* l: d
  14.   /* Copy the vector table from the Flash (mapped at the base of the application 8 ?/ f% a6 k' X) A
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  
    : z: A; s$ N4 T5 m: G; w9 V$ r1 B
  16.   for(i = 0; i < 48; i++)  
    $ w/ J* |( T$ d: i; x) k
  17.   {  
    ' T5 G4 f& m/ G  V- D8 e
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  
    / }  v% k0 P; y3 G/ t7 r( t0 T
  19.   }  $ [! P. Z$ ~6 p7 W. x0 Y
  20.   
    5 E3 ]! E3 m: z6 k0 l# q' Z) f
  21.   /* Enable the SYSCFG peripheral clock*/  
    * W& \# T$ \) u" Q( U  l$ O4 p
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   . |! T0 P, v2 |9 }1 U
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  ; N, `; S" f& v7 a4 V5 R- B; B  A
  24.   /* Remap SRAM at 0x00000000 */  * _$ ^1 n" ?3 m2 m* w; T) }: U$ F
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  8 T4 k# @) n) U7 D
  26.   + W0 D9 S# D' G3 M! q4 u! g
  27. /...  0 t/ Z9 T; S% D( U) t
  28. }  
复制代码

9 ]; @; k' U$ }- x6 `) O$ s5 A: P/ R
打开对应的map文件,有如下内容:
# G/ x/ L+ l5 Y/ f& K  g5 B
  1. [plain]  view plain  copy
    7 p  @6 H) Z7 s; y
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
    # Z; d! k3 j$ f  n
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
    ( q4 y5 v& D5 b' u' ]
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  : |8 x& t5 P& m- H% T- G% F
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  ' c- B" X$ u4 M% W2 q* @, j
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  " n" N7 g2 s) I: P- A) m
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  ( E8 p5 x5 ]$ F
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  
    4 K; l3 i9 m/ s. B) k
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  . N) j) S- A+ h
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  
    , \; d3 V; u4 F/ `4 R- v
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
    * x8 Q- C: i" Z8 y
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  
    # [' w8 S! \% f; d7 m6 f* X
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  
    6 ~2 O' `5 ^3 \) {6 W. m) s% l* [1 f
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  
    5 _4 Z1 S- q: Q1 o, l' b% A
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  
    5 X$ l0 k9 @) g7 A
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  
    9 B$ |5 S7 D+ r/ l& K+ a" o+ [+ F
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  
    + A( a6 t& D5 Y! U8 g) y0 k: _
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  3 C# W( A0 \) _5 \+ p
  19.    Region, a. x) N; }5 b) k  a& V! k& d0 [
  20. Base                      0x08003504   Number         0  anon9 a, O; H; d# S) E
  21. Table)  
    4 h3 w3 C, W0 }) b
  22.    Region* y. P6 k; Q! U; ]
  23. Limit                     0x08003524   Number         0  anon
    ( q" c' T3 W2 W; u6 F& Y
  24. Table)  
    & C9 N7 V, m8 o, Z. b1 y, x, v
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  
    # ^& s9 x3 O  S) X. Q
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  : U) ^. m8 F' y$ b' n
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  ' M  D6 t* @" \, k
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
    1 |5 X% y  Z+ Q' [; y) ?  C
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  2 {8 r2 a7 t' c& L+ ?3 M5 [
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  6 s8 P( q  u: |% H* G* K, V0 Z
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  
    , R4 J% C% q/ g6 S4 I" |" }
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  9 p4 R6 V: c. O' `' e6 E' V$ S
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码

* P) V+ n1 k0 [0 r如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。
! |$ U0 X% x- X( t
% N; S3 q$ U6 A" a1 n4 L  v
注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。
% E7 p& c* K* n" `% a/ T2 b  Q  l
3 S6 D: \6 m7 x: }5 @  k* D5 T8 P2 v$ d0 f2 q  Q
3 IAR下移植

/ }. M# V$ }8 a

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

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

* M* ~0 v" N2 |* U

20160728213900343.png

9 q7 ^2 M+ V+ r  `

. A7 H; ?/ j" [9 B& s

链接配置:

中断向量表:


2 R: p1 U8 @  _& r2 {; [

20160728213954703.png

, Y) I' Y& b* k+ z5 A

( N! ~/ N( q/ p( F1 I

内存映射:


( c: ^' x: H1 N! i7 k. g

20160728214047079.png


& a" F& u4 b9 g2 x* |$ b: H2 H


9 ^( e8 r( {# E6 }* K) `

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

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

  1. Entry                      Address  Size  Type      Object  ' [- J0 Z  ^0 D0 U( t+ |
  2. -----                      -------  ----  ----      ------  " t; P' P2 L) r; k( \! v% J* x
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  # Z% d6 r3 ~: C! y8 J
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  
    0 p1 I& _. A) U) E$ a% z6 o
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  
    " h9 ?/ G  j# z2 |! @2 d( x
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  5 i5 q5 t6 _4 t( T6 Z4 y" x
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  1 a, D2 }5 Q& q# J) a2 e5 u4 y3 n
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  2 S' X6 z+ i  T7 T8 Z1 _/ G' G
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  ! x' c0 X2 n6 ^4 n3 C9 U/ f, f
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  
    , Z8 F. W+ j7 p  i* ^1 C! m" c
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  : y: L  ], l; k" w
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  $ R( P: B- V) h5 D( Z+ \
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  . |! Q6 u8 n6 h: t
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  2 u" [+ Y) g0 A) W
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  7 [% I" D& c6 p  y. u) d1 u
  16. Region- `6 @/ O* q; M9 C, Y, {7 ?
  17. Base     0x080034fc         --   Gb  - Linker created -  
    ) j* X9 S# L1 l( }
  18. Region) p) d1 P, _7 v5 \! m
  19. Limit    0x08003510         --   Gb  - Linker created -  : Q* w: n, g; j7 z+ t1 \& j
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  
    - n. K. Y4 U  R2 b1 G. B8 p
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  $ {( C4 w; ~; {8 |/ [; {
  22. SYSCFG_MemoryRemapConfig  
    ) Y  x8 m# f6 x, v, Y
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  
    ) `3 X. ]+ N2 `
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  
    / `2 E& W: G9 {2 W
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  
    $ H: P# F1 V! f1 l- N
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
    : ]/ `6 G" C  {
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  % G6 \. W9 O. G+ n1 f
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  9 p) J1 S5 |7 c0 x2 Y
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  
    # |# U& b$ z. @8 t" N  `
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
    * d1 m) N: S- ^  |# J0 A0 |
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  
    & r1 l4 F6 h" X; A) F7 P) m( \
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  
    . j& w4 U( N5 D& @! Y0 a5 @5 o
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  
    , h  s( Y& {# e5 A0 U
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  4 e/ _- h, N' m" `: p$ W( @
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  
    % j8 a& n8 \% H- r
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  + U- \- [& h4 |0 D+ Q" ~
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
    9 t+ S$ o; X$ _1 i( Y) W
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  " o, e7 E# }) z4 |/ y8 l
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
    ) p4 m! `- j. z% L* l
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  
    ' B/ \; X8 t$ O) q
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  3 m6 p' C& d. u  b2 ]0 H5 r
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  . m1 _2 C7 Q. j/ {( G7 l
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  
    0 _5 `0 K  r3 `
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  : A! x9 q, O; `; c2 K1 B" |
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  
    ( t! T7 S8 `* D
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  , ~$ A0 U8 ]! T3 s
复制代码

2 i' i/ E' q7 k- v8 Y, p( M. K7 @如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。) n. D+ H7 {- y  f% {9 |  Z

0 w2 a0 X1 N" u- o/ S

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

8 X/ x# `; K* h" L

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

! j, k+ N7 p2 X' O/ }" J+ ?$ r; k
, N* i5 t6 U0 r8 ~5 ^* n, p
_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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版