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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序4 U! n& c; z/ ^! N% N; |
工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。
; a: g( O. j4 ~9 j) F2 v9 B$ |: H4 G
" e4 |; O7 Z1 V- e( e8 M
2 KEIL下移植3 W4 w+ D( E: e/ F
IAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。
; i. g" \+ z# ?7 W9 _0 z4 I. l' s% h6 v5 H% M" t3 D
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,
7 ?6 @+ l# h3 H
6 S6 H8 L+ m7 T+ Q+ A

" U8 A/ H4 a& y: X$ @9 R* w5 k* x$ z
20160728204029911.png
4 ^. o  o! R3 J2 _7 O
# I2 T" }$ X- @0 H6 h
/ k# C" z! q' o0 n2 ~+ _
并编译,结果发现原始的公式是编译不过的,如下错误信息:
+ k- X9 b2 F6 N# {; a: {2 Y) Y

8 U2 T+ S7 f  _

) b( X1 b6 G" J- T8 `
F6`I@6LD$B)$NXX9ZL7YH.png
% y8 R3 n' ?; w, e

* n: f: r1 k$ {' L" N
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。
$ {4 j! Z" }4 C1 [9 E仔细查看代码,发现main函数之前这么一段:

7 V" @/ m% y7 X% J' `) f/ J/ Q' l: l# R! v; R+ l

. t" D3 s2 g( O- V3 J, E2 V% N
%OUHQSFZW]KE6YY14U8V{YX.png

& x4 d! r# F- z1 J  i7 ^9 G
! R8 G* `" I, L- V" B9 u' S可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:
0 m5 K! `( a: s; A; ]* Y/ V( o7 I. k

3 p! t  M1 o) E  G9 }$ J  E

7 T: c4 k: Y) B9 Z$ e1 B% M
20160728203625097.png

+ {  b, U! Y( K3 ~& H
: d# ^) x: {1 ]; W7 m. D  U, ^/ c, V! o
再次编译,错误就会消失了。6 p( h- Z& q* \$ H

1 D1 \+ q) G1 C8 D/ l/ O% ~另外需要将main函数内前面几行代码做些修改:

% K; d- g" W  M- z& s" T- R4 [1 E
  1. int main(void)  / O! e8 y! W2 `. B! ^$ t) l
  2. {  
    - Z4 l; Q8 O! k* W' I& W; ?9 k
  3.   uint32_t i = 0;  
    4 l# X( E1 e! ^  z
  4.   ) ^/ p, i6 h- }+ h
  5.   /*!< At this stage the microcontroller clock setting is already configured,  
    ; G7 `* j7 C% T& j0 j
  6.        this is done through SystemInit() function which is called from startup , ^, y* [7 d+ h9 t  w% b9 w
  7.        file (startup_stm32f0xx.s) before to branch to application main.
    ! F  X0 X: _3 n5 f
  8.        To reconfigure the default setting of SystemInit() function, refer to
    1 k+ J0 w- v; \9 n. c* ]+ {
  9.        system_stm32f0xx.c file " T4 P6 `+ ~- F% q6 _3 M
  10.      */   
    ! Z7 ^5 l1 L) _% t) I  W
  11.   % Y1 G, h( Z6 ^7 t( ]3 ], J. E- k
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/   
    & J) _( ^+ Q* [6 e0 \9 z5 H
  13.   
    / }! J' v# A/ ~7 D4 u+ c, r
  14.   /* Copy the vector table from the Flash (mapped at the base of the application ' X! M2 _' Z5 ^; ?. r/ c2 ^" H
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  4 }8 K$ C+ h3 Y. e
  16.   for(i = 0; i < 48; i++)  & n- G( c& O# J) d/ X) e
  17.   {  
    , a/ U+ ?; t6 h# S5 U
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  $ C  x5 x% E4 `$ N7 @- z4 B4 N1 m
  19.   }  
    - e% m/ U1 P2 Y! N; j
  20.   ; i& h8 ]8 k: U* {
  21.   /* Enable the SYSCFG peripheral clock*/  
    # m8 ^" N9 Z8 X! H8 ?0 `
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   
    ' x4 `- A( [: k$ Q8 K9 O3 C8 B
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  
    ) ^$ C& G5 B/ t" I: P6 I4 n
  24.   /* Remap SRAM at 0x00000000 */  * l/ {! b4 ^" D( P2 R
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
    ! I4 @* c3 R/ [  A
  26.   
      Q, \0 P2 U  C- e3 _  _7 i; G
  27. /...  
    7 f0 \( a- F# W' _* H$ t5 l5 V! w
  28. }  
复制代码

! C6 Q. U/ ^1 U0 W. @& G. P
, Q( r$ H( z( W' Y+ \% Q/ l8 Y6 b" Z打开对应的map文件,有如下内容:
- I1 j# b3 e  d" s  w
  1. [plain]  view plain  copy/ b  ~  ~) Q3 n* H5 v
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
    ( w& S, u+ c: K  f
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
    7 `8 j* w' m! b  _" R8 O
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  ! a8 E: O7 ~! \, n6 o
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  
    2 H, m* d0 p+ O) @& g
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    : t! g0 V0 m8 K, q) H
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  6 B, C0 X: f  H4 B
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  
    ; ?/ j1 E7 L2 Q# k
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  " W, @/ U) e5 z. i) G; `, z/ F
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  
    ' \, k. K) A( t8 X
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
    ' `3 c& O* K: L
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  / f0 G" v* l& T" e" y9 Q
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  6 K" e  i: V/ S
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  & ?$ n' f+ Y) m' Z9 G/ o
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  " T4 O% D) E  x; @) W4 \
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  4 `6 \/ W# P* Y% x2 K
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  / d  f4 M! o3 G' U/ L% o
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  
    % I0 Q7 I# O1 x$ x* j2 t8 Q4 t4 ^9 U
  19.    Region! G6 {8 }& _& |* K3 w% j  t
  20. Base                      0x08003504   Number         0  anon4 I# e$ {: }; c4 M$ I
  21. Table)  
    # g/ o! X* g3 }3 A
  22.    Region; h( C9 D6 s1 H
  23. Limit                     0x08003524   Number         0  anon
    : G8 F  s6 Y% X* U, Q) A9 K
  24. Table)  
    * l( d9 _( ?3 G" {" u: @4 Y
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  " ]6 C+ [  k; g0 W1 n" l
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  
    * w0 ]4 G* ^8 ~( o/ V4 R- a
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  
    2 N7 R  k+ v% u% B$ N
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  3 q$ r# q+ a% l0 Q3 V: k
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  
    - E- t! d* J% l1 n5 c# F
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  1 L. `9 C* V* R5 W1 a9 D% @: _% M
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  , {6 j1 |9 x' O# `
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  
    , {0 g3 G4 r  j' j; @
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码
+ h2 l0 M4 L. s' I. N
如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。
# D4 Y  s, |- T' p' {8 L, r
6 n. j- m' h: B  t
注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。- {7 Q9 t) ?+ Q2 b: S% L5 h9 P& S/ f

: n5 E- J6 R; K3 ^' y
8 o* d* T8 v. C3 IAR下移植

9 `) @+ J* ]; L5 A3 _1 K0 H3 }

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

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


& i: y. W$ N8 m  t% a8 q

20160728213900343.png

4 |3 ]3 ]" H) ~3 I


0 e* Q6 [( V- d% M" _3 q( l

链接配置:

中断向量表:


( G1 k) l( H5 n" y& [# ?

20160728213954703.png


: S( U) i, C+ J4 j2 N- G/ G


7 V! t. Y$ n% X7 J6 F

内存映射:

  o/ y$ E1 ^- c) H4 K5 U: |

20160728214047079.png


' T% i  Q3 y  X, A

4 P' E6 Y: b" ?; S9 ^

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

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

  1. Entry                      Address  Size  Type      Object  9 N1 \" z9 y) a0 L% i, G
  2. -----                      -------  ----  ----      ------  
    ; }! V9 _; T% v+ w' @- i
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  
    / I( D% `. x; [/ w
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  2 R( z+ A+ l8 t3 T: }6 Z
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  7 l5 _3 K. k$ D& R# c5 O
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  2 U* Q: G& ]8 \+ S
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  
    4 Y9 ^' y) t# w5 ^. F6 d. H8 U
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  % l7 |* z4 {; o! W
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  
    # t! \/ |# T4 u) ^' d0 X) c: i% F
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  # e( ~+ ~' a: f. P  U  P3 F
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  
    9 e  ^, _: ]/ R. g
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  + Z$ A; t* D7 N% N+ {
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  & O4 L( A8 I5 q1 N  m. Q
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  7 w( z/ G! |& H2 p+ U
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  
    + P1 J+ \: x  x* n
  16. Region3 c1 ]5 A% W* s7 h8 Q  j7 v
  17. Base     0x080034fc         --   Gb  - Linker created -  ( f' b. z% Y& l: _4 L
  18. Region8 I& `5 _* z0 F+ `/ T) f$ s, [
  19. Limit    0x08003510         --   Gb  - Linker created -  
    $ O( G* X6 b8 t. l+ n
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  8 `% u) _: e& l$ G
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  & c3 V9 B. i0 x6 b, p
  22. SYSCFG_MemoryRemapConfig  3 C- e* f7 z0 g# I; _
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  
    # q. h: a. m5 j2 ]2 h; h
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  5 o- V3 U* f; t
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  , H' F6 z; d3 ]7 L. [# V/ q
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
    , f1 a0 g0 i1 V% P, |
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  
    ' u1 q( w( v9 |; h
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  
    , G' P& J1 S$ P6 B' S
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  ) B/ w( V6 z% h; C
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  1 ^6 d- m- c+ Y2 c6 ?
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  
    8 V* r* v3 ?% F% c6 S
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  & a% f) k6 W7 L7 H7 E8 |7 E( }+ E
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  
    & Q: P, }* H- k3 c* a6 V; {& V
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  ! k2 r0 X! G; G$ ?# S* n+ k
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  
    8 c( k5 ~$ O. ?/ u, Z: Q9 Z
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  7 o+ k( q9 V* p6 q" F; }
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
    # ]# x. h; S6 l- T
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  
    . A- n4 D2 ^1 \/ k. U1 M: H! R
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
    3 h( k) R% ^! B4 o% A: z; _- z
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  7 `" I  X6 {- m1 s/ l
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  . q! h) q3 N# C) _5 z
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  
    : |+ m) r0 s% e/ o$ }- ^( \
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  $ j" q$ U. i4 @- f3 }" `2 v- j
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  9 B& z! J8 {' q7 U! @
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  * s: ?8 E9 ~4 h1 P8 `
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  
    5 v; d3 Z+ Y8 d, b2 D: y* x; _; O
复制代码

" [8 b$ f% {4 J. W如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。) Y/ u( ?* _* H* f4 E: }( Y4 _
' b2 m; o9 |! c) u( Z

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


! u/ f2 y3 A( i& v- k9 ?

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


% S6 |- ?9 W& W( h# q) e8 X' `7 Z$ C( z
_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 手机版