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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序2 z5 R, ^0 H$ I/ R9 _- d
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。1 ]# c0 v% y# [: V

- I3 F5 s' _" d, V* |3 v* X5 o0 i

% {" J) y& k& s6 W! x. b2 KEIL下移植; a! E/ P, d  Y, R9 _; S
IAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。
: d( M( O% Y+ b9 u: z7 h( c- I" b$ O: \( ?+ y6 ?
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,
$ \3 B$ l; s: f; I

  h7 ?- j+ A0 G4 }
7 X6 ]. z8 @% o
20160728204029911.png

7 x  t. q7 Y& }( b3 h1 i) h7 }6 ^3 ]2 s% {
; t' b; r9 s4 {1 L: p8 v
并编译,结果发现原始的公式是编译不过的,如下错误信息:

* f! O; T; W; a( J8 m/ K% R9 Z/ H" \
: R+ w4 J, U6 L6 z; s! I5 z( y, n
F6`I@6LD$B)$NXX9ZL7YH.png

8 g1 [& j* m3 t: n7 Q% C) O) t: h: `  q% B% k
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。, n8 D  U+ C- B( K1 j$ B. |2 s
仔细查看代码,发现main函数之前这么一段:
' G( D% N: e: G7 b9 [- B+ v' {

3 g$ s0 c5 Z+ X5 B6 i4 D0 O. u. U

- s7 B' ?: t9 P# w* |
%OUHQSFZW]KE6YY14U8V{YX.png
: a7 c& ^1 r* U5 s
$ Q2 S; V2 P0 O4 m4 ?/ S' U2 m3 i/ f
可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:
3 W2 O( j8 r4 D6 O

8 P8 h. Q* U' J" S' |

) S( z1 {3 J3 m
20160728203625097.png

+ F4 u( v8 a) m: m+ G
% k8 r/ R( O$ @3 ?/ \) m3 \% C; V3 V, Y% h' F9 w( C: O! G: c6 p
再次编译,错误就会消失了。6 j' \6 J! _. W1 Z' o2 F
7 v# o2 s, y9 f* w
另外需要将main函数内前面几行代码做些修改:

( ~4 D4 u( l; w* X
  1. int main(void)  
    8 f! f7 U* @8 o$ P5 q
  2. {  . Q, L1 @) D9 l; x- T
  3.   uint32_t i = 0;  ( {3 P3 g( O, T/ U! O
  4.   
    ' Q' t  G* z0 M- |6 G* e
  5.   /*!< At this stage the microcontroller clock setting is already configured,  
    0 C: \# X% b# N' D$ P" P
  6.        this is done through SystemInit() function which is called from startup 5 w3 E6 b: n! z4 a* o
  7.        file (startup_stm32f0xx.s) before to branch to application main. 4 O( }, }, R$ K
  8.        To reconfigure the default setting of SystemInit() function, refer to , \* Y+ ]. u$ \* H/ `+ u* L
  9.        system_stm32f0xx.c file : L. ~! u: |) Y3 j5 X! W* s
  10.      */   
    ( S0 ]' C% g# N6 R$ u
  11.   5 i2 G! S6 X4 G9 r
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/    5 O  q6 n3 t5 v- W
  13.   
    # A- y- m) I) E: m% y. B" y! O
  14.   /* Copy the vector table from the Flash (mapped at the base of the application , E& }0 y! v# r. U2 m% @
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  
    9 e7 k7 Q1 C& D. |
  16.   for(i = 0; i < 48; i++)  
    / \/ A) Y+ t* G5 O8 p4 @* a7 F* a: y
  17.   {  - J% l: s$ @, k4 [
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  % U) ]9 T/ l* k$ p
  19.   }  & |+ [" Y+ q: x* |1 K. E- [" y6 C4 v- c
  20.   
    ) o3 @# c" T7 A. I- [1 L
  21.   /* Enable the SYSCFG peripheral clock*/  
    ; x6 M4 ~' Z7 U* I, r) N$ v* L
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   0 G" _8 c0 r+ t, p
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  . o; r# G& W3 B! F' _
  24.   /* Remap SRAM at 0x00000000 */  
    4 U: c7 Z) R/ \9 `( x4 f1 S4 G; G) t
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  ' l( Z: s4 F% I% [1 y; e: Y
  26.   
    1 E1 d' g# s1 n# g; k
  27. /...  
    5 r6 [0 V, A; l5 w+ v
  28. }  
复制代码
& Q- \* a6 Y' P$ {6 X3 q1 {
1 [1 W0 D* k: f# i4 d. Y
打开对应的map文件,有如下内容:

8 q# R! T2 w8 s' b1 j0 S7 ~- k  v
  1. [plain]  view plain  copy  F/ m( x6 Q' T. l  m% J( [  \/ n. I  s
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
    $ g, N2 d* i4 C+ T3 Q0 E+ y, U- X" V
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
      d4 J1 Q$ Q1 @5 f  ]
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  
    % r+ v5 w& G6 P
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  7 C& J! X! T  H3 |* }8 O
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    9 M5 _- d2 Q: F  C
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  + D7 G9 D- d. o: A& V
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  
    5 C  q( ~5 A# X* M1 P
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  
    3 m) O+ i! p9 I$ R
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  1 R7 L' r9 c' M& J5 Y& @7 ~4 K
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  7 c% B9 N  H* [- }* t. X, n
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  ! B" G: k1 h/ y
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  
    3 D" U# `  s0 n, k6 c' J
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  ; H3 c* a4 p1 j+ W. I/ [
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  $ L7 z7 o1 \0 K' Y, T
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  
    * f( }- j6 `; G2 H
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  # T: e7 }" D  L9 c0 J
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  ) p, r) s. Y& u
  19.    Region
    1 g) H. ~: L1 H7 @& [
  20. Base                      0x08003504   Number         0  anon0 l. W9 l4 ~( C, s
  21. Table)  
    * n! C5 ~- B, J0 \6 _
  22.    Region
    4 `: [- _8 N* S, n3 \  L: x
  23. Limit                     0x08003524   Number         0  anon
    ; g' j+ L( |! Y" u5 `1 b/ _7 L
  24. Table)  & W2 J' ~+ H1 A0 a; {- n
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  0 g: f2 M/ f" E1 v5 _  f" I) Z
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  , X6 C7 d$ T! l0 p- A
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  6 Z/ s4 z6 l% m' e  I$ o
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  $ N5 e1 l; y6 W; N& t% Z, b
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  9 E- ]1 v3 w! z- ^4 R1 ?
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  
    $ l  O3 Q, k, W/ [. W$ y: N
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  
    1 T4 A. }9 `1 O, X, q- M
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  0 l" K# g9 @8 b: t
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码

' N. I( |$ ^0 p- ]如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

* I/ T9 b1 e* D4 D! N$ q1 z2 F' l- [
5 r' X$ D  Z# w; r0 l2 W7 [# q注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。  u0 X3 \- L, ~/ u2 q7 a+ f' K

* f+ N& X/ W7 V2 R, {' T4 D1 F; m0 e2 H7 O4 n2 n0 i" ?  z
3 IAR下移植
& y4 x* _8 ^* W8 Y4 x6 t0 [1 f0 Z" F

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

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


2 ~) J8 n% x9 c9 D. h4 s1 I) C! l

20160728213900343.png


9 P0 q' b8 f* C$ O* _


' w* H6 S3 p: t) p5 x- {

链接配置:

中断向量表:


* p8 M/ C* R7 z* ^% ^

20160728213954703.png


3 ?8 z, F5 f/ ^

. W$ c) T$ p* e: Q

内存映射:

6 b# x$ O$ C- f+ J

20160728214047079.png

; T# {* E2 f3 j* W: j+ U

. N5 z6 z; u# D; }3 O% w$ w0 f2 J. P

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

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

  1. Entry                      Address  Size  Type      Object  & S$ P& r4 E1 l& s! r
  2. -----                      -------  ----  ----      ------  
    % o) h+ j9 J. F, r0 S
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  " N$ G. h6 t! M4 E3 t- C
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  
    ' s( O0 [/ f$ Q7 }1 x
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  / U* B: N$ q& X0 F$ T* w8 q' @
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  / s; l6 H- t: i, T
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  ' u7 ^8 T7 |4 v3 {$ E8 W' j1 _4 p
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  
    $ [9 r; m6 a9 E0 k4 O- G" \
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  
    : W7 S4 H# f  P) N4 C9 M) u8 Q: c
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  2 @4 O$ N" V, R9 O8 _
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  % O1 Y- X; H1 O! W4 O0 B
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  
    ; w9 S- ~. ?9 H5 V" I0 u
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  % T0 M5 k( t) a" K: x
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  
    ; I7 ^0 F# p% `$ h
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  
    $ i) i+ O5 L9 J; k
  16. Region
    . Z7 J5 s* j/ g; P- a% K
  17. Base     0x080034fc         --   Gb  - Linker created -  
    5 b3 }/ {: x# h! E, n& }2 ]
  18. Region
    ( B. R5 Y2 x% V% h3 O
  19. Limit    0x08003510         --   Gb  - Linker created -  8 V4 A1 ^# F# U1 C& S+ F) u
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  
    1 w; t4 ?) U0 o0 h
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  6 T1 _1 g6 r$ n/ @6 K
  22. SYSCFG_MemoryRemapConfig  9 Q$ d# V8 A; P' P
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  - v# `; r* p4 i3 z
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  5 u% b# d! {0 T# z
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  ) T+ ^+ ^# E7 m( p" K0 v( D& f
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  3 `' W2 _9 R3 f
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  
    0 s2 h& F7 K+ g  J/ ]. ]# x
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  : w5 h0 J( x. }- F9 [' j4 D
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  2 d8 w( O/ j! R9 Q
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
    - g7 }3 ^; ?: Z" o6 m
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  
    4 @* p5 j  Z( u' h- |
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  
    % @, X7 q& T- D9 t  ?. x% r
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  
    $ D2 W: c, \; n/ ~9 e+ B. `
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  " F7 I( M6 r+ z& X* C
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  / q/ z8 B9 s  r* r; C0 J8 [
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  ; ]; v& M2 ~* m2 _' z& i! }7 n
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  / u% D8 P2 [" x" d  P9 e4 i: ]
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  
    . U0 {3 Z6 w! V' m9 n
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  , f9 o$ g4 {* T
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  
    : Q+ ~7 H* j' t- h7 e* \" l( }) L6 r
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  ' n  v/ b1 K1 y" {; s/ g
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  + {6 P% ?  P  A0 U# c
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  
    2 j* `0 }7 z! h/ n5 O  l
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  - N# E  N6 y0 v3 L9 V. R
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  
    % z' b9 {3 o' j6 j- |3 F5 D4 K
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  ; h2 P% J6 D9 ~0 |. S/ F6 G+ t' L
复制代码

1 O" n2 \7 o7 S' ]1 |( J4 x( _# a8 E如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。
) q1 X2 E6 L$ e- w- ^3 w5 X" \. D* Z! E0 u

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

+ Q8 M% R  d$ i1 w' `4 E

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


# y: h/ e) Q3 q4 o1 o0 L
! Y' r6 q& L1 w$ [
_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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版