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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序+ p* x) J# Q4 T; Z, Z- {
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。: Q0 x9 E* H  p+ d" k# M

9 n$ g* s; g4 G- |3 B6 J
: {2 t" ^4 n6 U1 E
2 KEIL下移植# i1 ]$ n4 J3 F* {% {7 G6 X1 I9 p# D; z
IAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。
3 j( @" ]% T' y% I8 G1 C/ ?) ]" x- [4 X7 Y: m% K# R
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,

% @' c8 a" w/ A; ^0 j( ^+ W/ c- W* _/ u# v( ~- ]. u' g4 v# M* H
9 j4 Z3 V% L8 [' T; b
20160728204029911.png

- |$ B) V) g1 K0 G/ k
2 j9 D7 ^% Z6 ?# U+ R6 t6 a' }

# S& X; ~3 p" ^% F4 P并编译,结果发现原始的公式是编译不过的,如下错误信息:

; _0 B" j+ \: n1 q% P& h0 j. ~: }9 F/ W% g. u

" b9 M2 L- `1 e* N9 K4 |
F6`I@6LD$B)$NXX9ZL7YH.png

1 n- g) Z$ E9 @6 E% f8 {2 I" D) t2 X
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。
( R. o1 S/ x: s' V; n仔细查看代码,发现main函数之前这么一段:
8 j& x2 O. \  p% y6 [

5 @# [  n8 J" O/ w, B6 N8 v1 C

: x( C$ \3 ~% l. d. I" ?
%OUHQSFZW]KE6YY14U8V{YX.png
8 R3 U; [9 F5 u8 Q* Y) Q
3 _$ e, M$ I. F. n
可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

6 U, B/ n: ]9 x
/ z4 |# _  O1 }% t+ A: O; K4 R
. z  @. m. w2 ~/ J- v
20160728203625097.png

4 c* x4 c, ]) P  b0 A0 W: B) c5 A5 k6 E  C9 j
' j; Q$ X; q* Y; s% ], y5 U2 i/ }% B! x
再次编译,错误就会消失了。: J5 N) u) d. O) l9 ]; X

" q3 R5 _, @' ?* k8 ]0 W另外需要将main函数内前面几行代码做些修改:

, [# e( u" {; N+ w
  1. int main(void)  3 J4 X& L2 C( Y6 `' `, e" p
  2. {  ! j0 P% a. A  Z8 Y$ [+ W. r
  3.   uint32_t i = 0;  : b! E, e  n, \  E
  4.   
    7 ]( R/ h% b! ]# e
  5.   /*!< At this stage the microcontroller clock setting is already configured,  
    - n7 a% k+ H2 @% u
  6.        this is done through SystemInit() function which is called from startup
    4 x" J+ U" [" d& H0 x
  7.        file (startup_stm32f0xx.s) before to branch to application main.
    5 Z9 h. l2 ]5 B! u- O1 d+ _' w
  8.        To reconfigure the default setting of SystemInit() function, refer to
    9 f8 q4 s0 I6 y2 U1 W4 V' t7 r3 Z
  9.        system_stm32f0xx.c file $ `3 `6 G. d* ]" p  H& Q
  10.      */   
    ! v5 _: G1 H2 }4 x
  11.   5 @" @& j+ l; F5 p+ {) E% ^
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/    3 s& W- O3 m3 b% `( w& w
  13.   
    % [$ C" P" N& t; @* v7 m$ q
  14.   /* Copy the vector table from the Flash (mapped at the base of the application 9 V2 ^/ ~' T+ T4 G" K0 S3 p$ s
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  
    . \" H& z" Y) l9 `' z% q5 B
  16.   for(i = 0; i < 48; i++)  ) H1 i- B9 J. s' b" r7 g
  17.   {  1 G' }8 T/ ]7 W9 a! S. J6 @! c
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  . F& W3 C4 k- J0 Q; ]
  19.   }  
    3 u$ ^9 T  |: l, o/ [4 _8 B
  20.   - P9 k- @! N2 j1 e- ?/ x/ a
  21.   /* Enable the SYSCFG peripheral clock*/  - p! f8 m' ?$ Z2 R9 h6 i8 M
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   " b2 ]* s* T7 F2 P! F: k
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  / r2 J4 e6 k8 z6 \- k* G
  24.   /* Remap SRAM at 0x00000000 */  
    ( n  g' i1 Y" }( I/ z2 Q5 Y
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
    * N4 w9 m5 v, z; p4 M
  26.   
    , R! m# J6 H8 M; s! C
  27. /...  1 c* n* U) H  i8 ?1 [& b& k9 B
  28. }  
复制代码

7 F: N" d7 ~' j: h0 V, D. @% W3 [: u: m, A: R9 |6 c
打开对应的map文件,有如下内容:

# q4 a. U( D2 C# D4 F
  1. [plain]  view plain  copy& U& S( M, u" x9 ]
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
    ! r$ g9 i8 }5 ^' k+ {
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
      Y3 {+ n* c7 h/ p# u9 s, T
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  9 B' S' F' z. n( z  e- h
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  8 P+ s" T' `* @0 L7 _
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    7 P: B/ t; S) B# o# [
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  % {2 e8 q, P  \5 Q" i
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  9 ]& F5 K2 B1 u3 m
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  - w) m# N* ?4 y0 `7 I: x2 ~6 ~, r9 e
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  1 ^1 W4 H1 @. Z& r) }( X3 X" b
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
    , z4 F7 i5 K+ k3 P( U" n9 w
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  8 |) K5 [& A% O: v
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  . m& ^4 i* y0 v8 B# h/ w+ _% Q
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  ' y( R0 y# v& i( ~$ i
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  
    0 Q1 e1 b1 v- P) @
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  
      U# v+ B9 G1 b4 G" k5 m. T
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  , W# C1 N1 [) p8 H
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  
    8 A! `& h8 |9 S% |& [( o
  19.    Region
    8 ]- w' C8 v- }. v
  20. Base                      0x08003504   Number         0  anon( Z& f! d# _" S, w
  21. Table)  - P8 I- Y, ~8 c2 t7 O+ q3 x+ k
  22.    Region
      k0 M% B. w5 z: c6 x
  23. Limit                     0x08003524   Number         0  anon
    ; B# t7 e7 u% g9 l
  24. Table)  4 c9 w1 h. i3 Z7 ~" K2 `
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  
    7 L! l# X" E/ c- J8 B+ K
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  , V4 ]' L  T' ]% W
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  
    . g4 o4 m. o2 t8 e3 i1 n8 H( U
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
    + O+ U: A; u0 g
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  
    " a- Q& m1 _9 Y; B
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  7 o4 J% E$ o) b6 H
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  ) P1 r( i7 w7 O0 y( F
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  
    6 B& b3 A% u4 X& ]. y  X6 Z7 n8 V
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码
- p3 i7 d3 J( P6 N& z0 S# j
如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。
, k' r% w2 I5 L; u/ b6 L6 W. ]

8 r! l$ ~" N1 Z注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。/ I3 V* w$ A! c  q
$ X" h3 `$ i# i/ W% U& i$ D
9 d+ \( @: j6 U: T9 k
3 IAR下移植
* z) V: A' ?. X. R1 p" e

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

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

& A& f1 b: t  H* n" v

20160728213900343.png


2 ^, i+ j5 b% w/ ]


( q( w; D) ~6 l7 T9 M- I6 e! x9 u

链接配置:

中断向量表:


4 V4 p. b0 D5 f2 G" f/ Y8 A% {

20160728213954703.png

  f2 ^- W  G7 i- d; \9 ?6 h9 J


2 b2 y2 O5 J1 V3 {! s: r

内存映射:


8 o% d9 Y& Z9 H" h" T- k  h" s6 X

20160728214047079.png

0 t1 }( Z, a2 c8 R4 b

4 D8 ~/ Y; w7 t5 [( c" V" M# [

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

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

  1. Entry                      Address  Size  Type      Object  ) c5 J4 D6 n, t5 g$ |: C" a
  2. -----                      -------  ----  ----      ------  
    + o, p2 U, S1 U2 v- e4 Z  g
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  
    : U* O/ F2 n/ D; K
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  
    9 X+ X3 n, q% k4 a- |" o& R
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  
    1 H3 c3 n) T3 ]9 q1 Q! r2 d
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  ( ?6 ~) f( k& @7 {/ p1 {
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  * g7 O' H4 D3 N" x6 Z
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  % R" K: @1 m! B) ?; C" h9 j7 |: U
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  : ~* E1 u( i/ |
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  
      R) ?& X# j* R4 _8 u/ q" e" N; \8 R5 [
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  
    7 {) [; O# W  ]6 S
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  ! y* G9 D2 d3 \5 N
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  : C+ U9 {, i7 v$ @2 Y
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  
    # ~& [% n& c% {* N+ N( S* C. G1 N
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  
    / y1 E- y& [8 p+ J6 r( e& h& }- t
  16. Region
    5 h$ j6 u; ?0 L4 Q: q# `5 N
  17. Base     0x080034fc         --   Gb  - Linker created -  * _, M+ K  B4 }; B1 ^- \2 g# l- E
  18. Region# @! g8 W4 A3 L& S) a
  19. Limit    0x08003510         --   Gb  - Linker created -  / k1 ]7 J3 z3 ^2 b  Z, ?
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  
    : j4 y/ m, H5 ^1 _
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  
    ' N5 R* K# n1 M* i. w
  22. SYSCFG_MemoryRemapConfig  
    ; P% v( e2 R) @( s/ T
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  6 G7 Q# K1 B7 [6 J
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  . c, _' S1 O) e9 |4 }
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  
    ; \. q5 [1 }( j. }# X" B
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
    , k2 o) i2 m  F/ r
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  
    $ u( T% b" v" i0 t# m- ]0 F. t) E
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  
    2 h0 ]2 G7 G, T$ H( X
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  
    7 u. H& T8 S0 ?1 x* S5 v2 e9 U. x
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
    ; W1 o' T) J: I
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  8 z8 |$ m! T; ~' y0 z
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  
    & C9 r9 `0 c# U2 r5 _/ V9 x
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  
    + h( Z+ v' y+ R& y) i$ r
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  
    ; d6 d' [0 I6 V) M
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]    ?# ^7 w( w, x' Z
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  
    ; ~7 T5 K9 B8 K  P4 d9 W1 ~2 I1 E
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  : F* y" |* g6 h  g- v# T% {, d
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  
    * F+ S; L* m- ]" s9 k8 |1 v
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
    / J. v& i: f$ u$ |( x1 G
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  
    / y; x" f$ _' C+ }" U' g& ]4 W7 i
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  * v9 h3 y6 A; h
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  
    8 n$ W( _0 `7 A
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  
    0 w! g; H) V8 X; u
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  
    8 t' \( l. q- R5 Q' V. {5 W
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  
    8 h* H' ^1 s- j) ^6 w( p8 o
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  
    / j0 T# ]0 l+ K( X
复制代码

: `; z: e& H3 j4 W如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。& b. v2 l3 W# X0 o% Y* Y
' L  H8 Z7 \2 X* P3 [3 V) {* j9 z5 Q

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


1 p6 M3 _0 o6 z9 U! g- n

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

; F5 o$ v7 P& a
& g! U1 f$ 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 手机版