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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序* r6 T6 a" ~  ~& `9 U* Z
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。
, I- o" g2 ?. G2 F" I' Z' ?' r! \8 A  L# ^) V6 z/ X: H

1 H( q- o8 m/ e% T# c$ X5 z2 KEIL下移植
5 s$ ^' E1 T* iIAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。/ N5 G! c0 |* r& |( Y
- B: x+ F& D2 I+ M. r4 h" h0 |
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,

+ g+ E  K( S, I9 c% h# X; P7 s- O7 [# R& R
0 P. u; P$ h6 [; ?# B4 D+ F& r$ ?
20160728204029911.png

  J5 A# j  m/ R: N
0 N% u# c/ F. k: C; _) C5 B) P' h
- m; L  V; r0 ?( S2 @+ W! z
并编译,结果发现原始的公式是编译不过的,如下错误信息:
' W/ F7 H/ d# V( \, P$ J# n
) l: a+ w  y' K! s, G9 C* w7 S6 C7 v
6 s+ L" \8 m& [/ ^+ Q
F6`I@6LD$B)$NXX9ZL7YH.png
7 j7 g) ^/ |" H

5 q  @3 W2 R, `$ f7 s
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。3 _# u, J1 a2 t
仔细查看代码,发现main函数之前这么一段:

7 y; {# q( h* t; H' y
0 y; o2 `; M, {- [' @' A. m

% w/ O2 D% V1 X# O2 b% r
%OUHQSFZW]KE6YY14U8V{YX.png
3 q  F" G* h- L: Y2 z* F

- l* S' ^' l1 x" B4 @* ?& b可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:

# ~% P" N( c8 e9 I
  h* y6 t: E" q* C& M
" p: g7 h4 K" [& @* x+ G; h
20160728203625097.png
6 D# e1 E; M" a

% M" X7 l& I% C% v' N5 C4 w1 L5 W. a8 q8 D. k6 X- \
再次编译,错误就会消失了。# z6 i2 J5 B# n# M
/ J6 I1 S$ c1 m0 I
另外需要将main函数内前面几行代码做些修改:
" \! t7 T, }4 U: ^8 ~% I4 p, @
  1. int main(void)  
    ' }& A, e5 b, s' e# i  r
  2. {  
    7 g; t$ K0 w$ A% ]& g% X1 o
  3.   uint32_t i = 0;  6 |7 k6 a9 _! E& I; B+ I# t; q3 }
  4.   ' @7 K9 G+ d0 ~% E4 i- l6 Z5 f
  5.   /*!< At this stage the microcontroller clock setting is already configured,  7 ?, L4 }6 O0 X" c$ z
  6.        this is done through SystemInit() function which is called from startup 9 Z3 t+ t! ~6 m( g6 O; M
  7.        file (startup_stm32f0xx.s) before to branch to application main. ( G. j  ~9 i% q. p
  8.        To reconfigure the default setting of SystemInit() function, refer to 9 J: U8 @5 Y7 ~
  9.        system_stm32f0xx.c file
    4 f* v, g: M8 X
  10.      */   
    " a# O; ]7 C0 p) K$ ?- W; |; u& y: b
  11.   
    $ w. p  L: z- O+ r! q, U
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/   
    ! P+ j. M" p0 e, J+ Z+ A' P
  13.   
    . Q0 [( _0 P4 N1 Y( [4 x+ k. U* B
  14.   /* Copy the vector table from the Flash (mapped at the base of the application 5 _5 }$ ?( w) x% T
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  & i$ f+ p' L) y: `/ H7 a. j, Y
  16.   for(i = 0; i < 48; i++)  
    1 P% ]. J* X; g1 Z! O+ T. b
  17.   {  0 k0 m3 @9 p9 X) w# e2 k$ a3 [
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  8 q0 I6 G! M! n1 L
  19.   }  
    , _4 E* ~* o5 {0 M# h6 ?
  20.   ! V# h& z5 @) {- c: E4 T% q$ c
  21.   /* Enable the SYSCFG peripheral clock*/  
    $ }) C' [0 g* P; z1 J
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   
    3 ?& r& x( C$ u. y/ A& Z% f+ z
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  " X/ O# c: M; f* E! f" z
  24.   /* Remap SRAM at 0x00000000 */  
    8 Q! x: a! G' l8 y  W( n, {
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
    ) H! }' v2 G( y$ K/ x
  26.   $ K, |2 n( ~+ A
  27. /...  
    ; L! c" r/ y9 ^6 B* `
  28. }  
复制代码
  e/ R/ X$ L. J2 d: \9 n2 Z8 {' q

  O% _& I: `( g4 f打开对应的map文件,有如下内容:

, l9 C/ b% j( R  f! j3 q
  1. [plain]  view plain  copy. @8 a, f2 T: }+ j
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
    ; p3 S/ u" ^0 u
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
    * H' |; I0 }3 w0 W7 c
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  
    $ x: |2 s" ?5 Z" T1 C# ^
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  $ m" R$ @0 X/ U# }% x
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  & `" l6 {$ J4 F' M3 J
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  
    : w) z, {2 u( j% r: C! \) }) L
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  1 [# A3 b3 q7 R( r3 `. b! ~
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  4 }1 ]" @( {0 H
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  
    6 f. {/ T& m/ w1 P- f: W- z
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  ; d& F# w" h, U. ?) |! m  Y: n
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  
    # L( k& i- S, n) G
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  
    - q  P0 y( Q) S0 O: k; b6 p0 c2 F
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  
    2 R) U! k# H( w
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  4 _+ v) a7 @! b( c- }6 w$ N( Z
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  ! `1 B, Y% R* B# w+ J* p
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  
    - X5 B! p5 n+ q; r% b5 q1 u: @0 w
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  $ }% F. h) T8 F7 ]8 g8 }
  19.    Region
    / R0 i4 A/ v. G) r5 u; |) N
  20. Base                      0x08003504   Number         0  anon
    9 P% B5 _. P6 C$ H2 o6 p1 l' }" T
  21. Table)  ! h! J8 y4 ]0 M2 E( l
  22.    Region
    $ R8 {/ K0 b, E# |7 y' {) R3 Z; t' E
  23. Limit                     0x08003524   Number         0  anon
    7 F7 j4 E2 ?' j0 }" x) s1 d
  24. Table)  
    * e/ w, x* |; P1 N
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000    l% j  d& P5 t  J* U; l. h
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  1 ]( E. ?& ^- @- n1 t
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  7 M5 u# S! N# c/ f" u& Y+ O
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  % u0 U2 F* a  l8 R" S6 m- a/ d
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  2 X! ~1 t* f7 i! w# v# d) f+ S7 U4 F
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  & M8 V5 n( l' X7 Z9 O! @: }
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  
    ) }7 \; K6 j1 O, A) _
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  6 L2 G2 Y# K% x. m! L. Q* L: }
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码
' R% D: S, s9 ?
如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

) q0 r) }# a% L6 j9 c7 j7 L1 x; h3 B2 X8 t  e
注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。4 E. \, {1 v4 O8 F( ]
* S" C5 _! t' x  g

) G9 r! t7 H9 `3 IAR下移植
% W7 z6 d8 g5 k8 X7 Y2 Z6 p

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

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


5 v7 v! e+ h: ]0 W* j" }

20160728213900343.png


# K; H, Q+ L; u  ^! x; ^9 q

; E1 E. O, |5 M9 G( l

链接配置:

中断向量表:

0 x5 ^; i5 r7 R/ v- F

20160728213954703.png


: i1 g, ^6 h! P5 [% i


& A% U) M5 k7 U2 v2 u! e6 G

内存映射:


. Y. x2 C' r; ?: F: C1 Z: j: e

20160728214047079.png

6 r! f* Y3 x; c# ~9 y) x


7 k/ W3 z. h: d

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

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

  1. Entry                      Address  Size  Type      Object  7 h% \' ^( Q0 T: W
  2. -----                      -------  ----  ----      ------  # O$ A7 Z( Y2 G5 }! L' X8 I4 s( W8 G
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  
    ; p8 ?  N  ^; f  T7 C
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  6 W& p1 q1 F" D; h' `! l
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  & n: Y; }; F  R$ X& e9 \
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  ; [) h1 k  U( s' i' l/ v. L( I' Q
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  ; p! l+ Y9 W( v2 _; p: h
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  4 H8 P: f- \4 \$ X% z
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  
    2 W* j) D$ Y; D
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  
    3 S0 [5 Q; D, s/ a1 Q; E
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  
    ( Z8 R5 k. i4 b$ M
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  
    , f8 @1 m$ s9 X. w
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  
    ( I* X1 ^& E% v6 A/ H$ X# J
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  
    & U6 w1 W2 K8 g, G
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]    a* Q" L$ ^5 P6 }
  16. Region7 {) c2 Z) e) B4 G
  17. Base     0x080034fc         --   Gb  - Linker created -  
    : ~3 Q+ Q" B" l. s7 h$ L
  18. Region6 o- G- A+ k7 ]6 I: O  _0 Y# R
  19. Limit    0x08003510         --   Gb  - Linker created -  
    . H& c& [5 B$ w+ R* I# M
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  
    8 p0 |$ G4 h5 F( C) o, n: F
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  
    * g7 s8 G( e7 f, M# i
  22. SYSCFG_MemoryRemapConfig  
    3 }7 Y* l3 _3 m2 S
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  
      N+ R6 ?, ~9 e' ~. T. _2 [
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  % T& n# g5 Q$ S8 g' Q$ h2 p# [7 y
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  * |9 [' {' r# n9 ~1 G2 f
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
    - G; e8 E7 ?+ d# m( B
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  
    % G8 N; n  X7 t
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  . F3 k* a/ ^2 r+ w8 o. ]
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  * v* W- g+ C' i
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
    # E! Y- P) c$ \$ I" L
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  $ F9 U- H( C3 f% O
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  ) T. k" v  e/ O7 G9 W. X8 M, g
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  & N4 i) }+ T- L+ n( l
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  
    5 R1 B& d2 B( C, m  V/ j# l. [
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  
    - S  ~9 a5 o8 t
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  & I$ }" A; `8 T. e
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
    $ g# X* l& \. O( O+ h" E/ I6 p7 r1 J
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  
    , f) V8 N- \6 P5 L0 v3 d
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
    6 W- o) T3 T/ r( X' _- A/ w
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  ( K% ^. O7 A& c4 C+ _& h" J
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  
    ; j9 j: N4 m' }/ I3 M/ F
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  * t! v* `' e% ^' |% h* f. h
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  
    ) w' B8 s: D# u8 b+ E- j3 x
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  + @9 L/ x, l* f( u4 M" @' t
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  5 L; y; O+ @" |& `' e5 v( y
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  
    / \& b/ I! ?" S2 k1 S
复制代码
3 }& d2 p( ~! L& Z8 }0 s, {
如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。
- v& u. A1 X- Z' ]4 d$ ?  e- s6 k, {3 h: i  W

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


$ S" E% [5 n; ?. h8 C) Z

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


, j4 o2 Y% `4 ~0 F4 ^4 K
2 f$ M" w) c+ ?9 [' |$ J& j
_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 手机版