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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序
" `  e  ^# a0 A. T工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。: r. ]  J# D# [4 m* [- l  O
! h8 }$ o( J% a+ }4 R. \4 R
0 O$ I6 U3 K, [0 @0 n
2 KEIL下移植
0 D/ ~7 ~+ R; @' \" A' UIAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。! h; z' {# M5 ?

. [& A* c8 K+ w下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,

- q$ Z# p( M$ {+ X7 G
% m+ b5 y/ k6 |

% t6 e" e. f5 X8 }3 L" A! E, g  @
20160728204029911.png

6 m2 D  v% J" N! d% w# ~3 G. G. P  t/ `7 R  \6 c3 x& c

$ [$ R5 u) [4 K+ Z, k- e; r并编译,结果发现原始的公式是编译不过的,如下错误信息:

1 L5 R, V( y4 ?  q! @5 x) n8 d5 Y
6 o" [) F+ J+ j8 N, ?/ Z
F6`I@6LD$B)$NXX9ZL7YH.png
$ W: X$ o) `" ~  J/ y* h; t8 B- Q
$ W0 Q" c. K: w) U7 f$ t9 e
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。' r% ^; k6 p. }
仔细查看代码,发现main函数之前这么一段:
% f# Y/ q& V0 O  ]* E8 f

. l1 B: s. }) T0 ]

, H0 i# f" d/ z3 a1 w' [
%OUHQSFZW]KE6YY14U8V{YX.png

6 }3 B( w/ N% I- n* a% b0 ~) U
+ i! U9 [5 h4 w/ f可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:
0 ^  a; X8 a) I+ V
/ H( A% Y, s' v5 y2 L$ N- R( z

* K7 u) H' C8 s& _9 d5 a; g% H
20160728203625097.png

$ h/ R, P* F  C( {+ B' e+ E' F1 L8 c$ {, ^  d1 Y

4 Y3 c( i8 d* X1 N7 q+ K) v! F" E再次编译,错误就会消失了。! P$ }/ p: G6 }$ r, v

# ]/ Z) ]4 s1 V" i另外需要将main函数内前面几行代码做些修改:

$ C- m& A" z1 c+ c* t
  1. int main(void)  
    8 J4 i* N# J7 L  d% Q
  2. {  5 L4 U6 J5 a# J" I3 t# t" ^3 c
  3.   uint32_t i = 0;  " p; F7 p: _) u1 Z$ u8 h
  4.   % ]6 s4 F. S- _9 A+ A
  5.   /*!< At this stage the microcontroller clock setting is already configured,  
    6 L# W4 J; D0 q4 P
  6.        this is done through SystemInit() function which is called from startup
    + r. S+ I, Q$ C% e3 D" V
  7.        file (startup_stm32f0xx.s) before to branch to application main. / k$ a+ x; K9 i$ A; \2 d
  8.        To reconfigure the default setting of SystemInit() function, refer to
    / T( D- F& X% k5 t2 j* p8 }6 X
  9.        system_stm32f0xx.c file
    1 _7 p; ^8 D; ^( ]7 _( E
  10.      */   1 b; o- J3 E! A: Y8 j* U
  11.   
    3 n5 X1 r# O, h& s
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/   
    ! ?/ v7 X! J  U2 _: u" F5 m# B
  13.   7 w$ m4 W: _- x- X
  14.   /* Copy the vector table from the Flash (mapped at the base of the application
    / S: I, o" M# Y3 [
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  
    1 v% ~5 ]' z8 j5 \
  16.   for(i = 0; i < 48; i++)  ; J" T% k0 c! e* I7 O
  17.   {  
    1 M( @1 p) d2 M2 r
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  
    5 g( d2 L% J. O; H- S3 l
  19.   }  4 L; h, k- Y8 U2 C$ {0 `
  20.   
    4 c: k9 R  F/ y, a
  21.   /* Enable the SYSCFG peripheral clock*/  4 L+ |6 m" J. ?5 p, G' [
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   
    9 `7 G( }/ \, F8 P* |9 n
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  
    ) e) W  T& p, O# z# y% `
  24.   /* Remap SRAM at 0x00000000 */  $ C8 _) A/ J! t2 G) w- i& X8 c
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  ) U" A* v4 X  }0 a$ j( ?3 J* V
  26.   3 \+ S' a# z6 I
  27. /...  - _1 E' L) y/ B% [+ g1 L/ }/ R, S
  28. }  
复制代码
( d! ^. ~2 B6 V; q" |7 F
/ a% W% Y' E  r7 Y
打开对应的map文件,有如下内容:
% y0 ~- ~6 S: Y0 A5 R0 q
  1. [plain]  view plain  copy' K1 J. l" W- x
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  , A* i3 L3 Z: K! V4 R
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  6 G5 Z: H) W7 e" w( ^6 t! ]5 }8 l% R
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  
    0 ]" }# d/ ]. M+ W9 ^. o4 B
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  
    ' @# v/ O8 V. d# G
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    : f$ ?) U" Y7 P. s; L1 s1 z& z
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  $ g* T. B! s/ {  i( R) `
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  ( x! u* Q4 V( M4 b+ e4 I5 K2 X& v
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  
    - p3 |( Z8 \$ x7 C$ Q) e. d. g7 Y
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)  
    ' H4 R. @2 s# b" ?- U8 H5 C9 W% A
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
    $ h  m" b9 l! n
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  
    * T5 T4 Q9 i) ~" y
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  
    5 a. n6 T+ o7 l
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  # d2 A" t4 S& N8 h7 t/ z9 f% M6 ^
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  7 U+ ^7 F& ~. F) V8 U9 n
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  
    + p* j7 J0 c7 J  g/ x: F
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  
    - v; s# c, U1 h, Z, \" z
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  
    : B$ P  m1 \9 f/ U9 `
  19.    Region
    ' M6 i  x" L9 }
  20. Base                      0x08003504   Number         0  anon
    ( s+ ~# s& l& N1 r
  21. Table)  9 H/ ^# y1 \7 v" f0 M  a
  22.    Region& }8 d& p8 l2 U, ~) |" w
  23. Limit                     0x08003524   Number         0  anon
    / O& G9 r  }0 r. F0 b; V* ^' W
  24. Table)  
    9 J# {+ T4 i+ C
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  : g" y  B: @4 k  W% q& x+ [' k9 \
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  2 b- E, e- |' e, R  N" K
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  
    * z( N7 G- v* e3 d3 `$ N
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
    $ G0 N0 @5 ~: V! `
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  $ m4 a( \% W8 E' Z
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  
    6 f# w2 c' Z+ G6 A9 d, S# o0 t
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  . n! {8 N$ Z$ `; _, b) K4 e
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  
    * s$ V4 P+ |, W8 _9 G1 z- b/ s
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码

; D7 ~+ A6 q. r7 b# d如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

- W8 A- B) h5 ?2 ]2 I
2 |1 \1 }$ w) B  x1 F/ c/ F/ I* W注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。- F2 z8 k+ x, @& u$ n

- D7 |: k/ I+ `
6 d9 u( h! d3 [$ \: R3 IAR下移植
  `) O, a) T8 t  {7 [2 a5 W

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

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

! [  I; N1 t" _. a$ `( j9 C

20160728213900343.png


9 D" a6 I3 Q& G& M( q) h8 q, |3 y


' _' L) J. `  R) C, I- p* `

链接配置:

中断向量表:


5 I/ ~6 e+ x: [7 p# h

20160728213954703.png


5 G: x3 `( b: y! s- |

% q" c- D4 [' c, ]/ O2 M& X

内存映射:

& J  L3 g; p! D5 {& _

20160728214047079.png

. T' E3 ?/ q$ U: Z


* Z& p0 @  Z( u; S+ Z6 g( u) n0 {

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

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

  1. Entry                      Address  Size  Type      Object  
    " i( R( a4 P$ M) H3 X/ o
  2. -----                      -------  ----  ----      ------  
    4 F. f) R' W. Q; ]8 a4 [- p
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  
    ) |! c7 H  ^/ Y4 V; Y% h
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  2 P! l1 _) z! _
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  
    7 Y$ G) t$ b2 A) K9 p$ M7 H. a
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  5 W+ ^( @+ \3 w  F4 H) f
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  
    8 N/ n8 l2 U* T0 p
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  . a$ o9 R$ A! v3 N/ C
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  
    & f& Z5 o5 l- o' I7 ^  x, t0 h
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  
    3 {0 C& X! `9 ?  J! y5 J5 }
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  - Z% |3 P3 ^6 E$ j) J" `' J
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  
    % c6 K* j, T) o) o
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  # t- {# O% M/ i; a8 l6 D
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  
    ! `4 ~) T* @2 U) a* N5 _
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  9 H+ ?9 h$ |7 m) M3 h, F
  16. Region
    # k3 N3 B8 _! V: C+ r! k$ Z" x# j
  17. Base     0x080034fc         --   Gb  - Linker created -  ) I# Q$ s, \, k+ D) J
  18. Region+ \; e) M4 W9 q% {
  19. Limit    0x08003510         --   Gb  - Linker created -  
    1 K3 b* d1 \4 @' N; k) _0 V8 ?- c
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  5 e5 Z; w; M# `1 u' R% b9 L
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  6 M: O  a& r; t; v3 u
  22. SYSCFG_MemoryRemapConfig  
    + \$ X9 C. x* A6 U1 h
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  
    , E7 Q3 }9 G& D# l/ R/ {
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  6 v" N% ]/ V6 O% s% \1 o0 b
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  7 B! t9 J1 F: Q! T1 z
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]    A6 f+ a9 V6 u( @% Y8 Q# a
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  : p1 n5 S8 ]* V# s+ M4 C
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  5 p6 X9 A7 @  J$ O+ I8 v
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  , `& E2 o2 _# v" u& J- Y
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  
    ( w* h+ N3 q9 c, g' g2 W2 i
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  
    7 f) s6 p8 ~$ o4 J) Z
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  
    + ^- o: I0 p# q* O" I+ c7 J
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  0 u2 D+ N- o: H& n* d
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  
    ) f& U7 B: Z$ U6 ?2 ~  b
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  
    . K/ {, v5 a: I; I6 n
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  : J% @- p& g1 i0 V/ w& o
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
    9 H. F( ]9 x* j8 T1 ?- |4 E6 B
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  ' @" B) D  ]/ U
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
    7 _+ m1 N# |0 ^8 r, E
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  - g& }4 z, q1 R0 d% u4 I
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  & r( B* q3 K2 R% w1 O
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  9 g$ [  Y; C4 F6 n
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  3 q) B$ R" k1 j
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  * A, T1 }+ O, d  J
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  
    / S/ K6 z3 s* v* }9 u3 b; x
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  
    8 K7 ?7 g2 M  c$ h9 q/ K. ]
复制代码

6 E0 }1 `/ f3 z, Z! n  m; b# {如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。
( J. {, [3 {9 b( Q$ I/ }* F9 z% j
4 |  P. T+ f+ L

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


: `; H2 I$ L3 }7 T, D

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


' z& `; L$ M1 G2 r) ]: J  ?  V8 W5 j6 h0 z5 I) d
_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 手机版