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

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

[复制链接]
STMCU小助手 发布时间:2021-11-22 22:03
1 前言STSW-STM32116是ST官网基于标准库的针对STM32F0的USART进口IAP示例程序
9 K3 W! h; v" o4 o7 y' f工程原本是针对STM32F051,本文将介绍如何移植到STM32F070,并针对移植的过程中的问题逐个处理。$ h5 V% Q: s1 z- ?7 {: e

- c" [- X2 v% i& C1 P8 }0 b( P: F

2 A" n# ]  l& b2 _. I2 KEIL下移植
+ i; }4 _) [) I0 M$ DIAP程序一般分为两个,一个是IAP,一个是APP,IAP存放在内置FLASH的0x8000000的起始位置,而APP则存放在离这个位置一定距离的位置,这个距离一定是大于或等于IAP本身所占空间大小,本例子为0x8003000。
0 G* R1 c/ R2 D9 H8 {) F8 p& |5 e8 G, N4 q
下载资源后,打开STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\下的binary_template工程,这个就是APP工程,首先用KEIL打开,修改device为STM32F070,

$ l& [3 T. r4 k3 D
* M; G8 [  Q: U- l% [: |. }8 D' B
+ l# Y4 H0 j+ x/ n1 G6 v
20160728204029911.png

& A' Q7 ^" ]3 ^+ o) i- Z
# D; U8 v3 o4 w5 S, H# i
) o: @$ e8 g/ |% R$ O" R
并编译,结果发现原始的公式是编译不过的,如下错误信息:

2 I3 r5 I+ p( |) C$ K* Y: X* X* O& W3 [$ k* `) R. Z

4 Z+ ^% b* U" }
F6`I@6LD$B)$NXX9ZL7YH.png

; ?# ^" O; r8 N8 g; A0 k" _) V4 s; l
从字面上判断为编译system_stm32f0xx.c文件生成的目标文件system_stm32f0xx.o中的数据段(.data)内的RW数据与main.o中的数据在地址0x20000000产生冲突。2 G# e* S: F% b1 T
仔细查看代码,发现main函数之前这么一段:

+ w* E. H, ^9 s
& N  K. S2 ^$ X: g, b- d

$ P8 d) L6 g' e* n) b( B9 F/ V0 G$ A
%OUHQSFZW]KE6YY14U8V{YX.png
$ D8 z& ^+ E  l) \
: H; Q* e5 o; S
可见代码是要将中断向量表VectorTable强制定义在内存0x20000000上,但是此地址与system_stm32f0xx.c定义的全局变量位置有冲突。于是,需要修改避免冲突。中断向量的地址是固定的,但其他全局变量的地址可以相应地移动下,并且APP的烧录位置为0x8003000,如下图:
: e; I6 y1 s2 e4 S0 [7 u$ E0 J: t2 r  @

1 ^5 W4 U0 h/ n  a3 _( w1 `6 B
8 r# J1 K% j/ A5 X
20160728203625097.png
' D. v) q3 \5 \: F' B5 |
: m0 m# ^% ~2 j/ A5 w

, j$ Y! M' O1 E+ z  G再次编译,错误就会消失了。
0 _$ C/ z/ ~$ f6 J0 v( Y4 Y! g& B6 P5 i8 i# A
另外需要将main函数内前面几行代码做些修改:

% m$ A  N% G* u
  1. int main(void)  
    ! ?; }7 g" N% `: h, A" D
  2. {  & S' N/ @3 n1 u" K: R
  3.   uint32_t i = 0;  
      F9 Z3 M& d& @9 n7 r6 {* O( p5 R
  4.   * q0 P1 E( ?% L& _6 }8 l! P8 S" c
  5.   /*!< At this stage the microcontroller clock setting is already configured,  
    ( Z! z7 z, {  X" [
  6.        this is done through SystemInit() function which is called from startup
    5 r' X0 a7 H8 X0 Z+ n, w
  7.        file (startup_stm32f0xx.s) before to branch to application main.
    ! L4 L% S4 L+ C  C' j0 S1 P
  8.        To reconfigure the default setting of SystemInit() function, refer to
    & L4 V8 L7 s' c- C6 f. n
  9.        system_stm32f0xx.c file , J+ O, O- K. Z
  10.      */   . J7 a: G; D$ Q$ u) S; P2 }
  11.   
    . g& I9 Y$ L7 j4 {* B! L! U
  12. /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/    - B5 E* x3 T, p' v6 _
  13.   ! C2 W! Y; ?' \7 R5 e5 G: u' t$ F
  14.   /* Copy the vector table from the Flash (mapped at the base of the application
    1 d1 m. Y- W0 O4 T% C, q5 l
  15.      load address 0x08003000) to the base address of the SRAM at 0x20000000. */  % U: O6 Z# G# ?# ]- x
  16.   for(i = 0; i < 48; i++)  ) p" Q* [) l& I0 @( k
  17.   {  3 E. e' |9 c5 l; v
  18.     VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));  
    - D! E6 i5 E+ ^( l
  19.   }  
    & S) H( A7 z/ f2 I! h- u
  20.   
    ) a8 v/ W) s; O8 E$ S
  21.   /* Enable the SYSCFG peripheral clock*/  . u/ F" u2 E* F) f$ ]2 r& P8 P& r, G
  22.   //RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);   
    ; E/ Z& ~! D2 @$ ]+ z! H" ^
  23.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);    //需要修改成这样  % B& u8 t& y8 ?/ ~/ w% }+ l& g
  24.   /* Remap SRAM at 0x00000000 */  
    6 a0 }7 A/ G) A: e* ]# A
  25.   SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);  
    # ]5 J2 o6 M8 A8 u. S( N4 b* x$ s1 r
  26.   6 O9 [! q9 ]5 O5 L/ P" P1 ~0 f& Z( v
  27. /...  6 ]  y4 e1 \( }" h2 p4 {) r- U2 H6 O
  28. }  
复制代码
2 U) q3 t( E* c* S  g+ _& s7 C

- ^" j0 g0 r7 s3 v4 J5 m打开对应的map文件,有如下内容:

$ @- `, p$ c: M+ H5 A
  1. [plain]  view plain  copy, x& {4 X5 a' F/ {0 i0 P* s
  2. GPIO_PIN                                 0x08003470   Data           8  stm320518_eval.o(.constdata)  
    1 \/ A2 L. t# x  [# ~. l
  3.    GPIO_CLK                                 0x08003478   Data          16  stm320518_eval.o(.constdata)  
    ! [6 u8 a; y& d5 O
  4.    BUTTON_PIN                               0x08003488   Data          14  stm320518_eval.o(.constdata)  
    # x* z0 B; z" ?' @* e8 F) r5 s
  5.    BUTTON_CLK                               0x08003498   Data          28  stm320518_eval.o(.constdata)  
    ; v1 g. V4 n" o# i: G, H
  6.    BUTTON_EXTI_LINE                         0x080034b4   Data          14  stm320518_eval.o(.constdata)  
    + W" S5 r4 h9 r# x# `8 @- n
  7.    BUTTON_PORT_SOURCE                       0x080034c2   Data          14  stm320518_eval.o(.constdata)  
    ) S- b1 F5 v& K- C5 N) m1 b& D/ S
  8.    BUTTON_PIN_SOURCE                        0x080034d0   Data          14  stm320518_eval.o(.constdata)  
    4 [9 z' q% ~0 P; Z) J/ ?9 ]
  9.    BUTTON_IRQn                              0x080034de   Data          14  stm320518_eval.o(.constdata)  8 r# Z3 s, @/ q2 g1 l! g, t
  10.    COM_USART_CLK                            0x080034ec   Data           4  stm320518_eval.o(.constdata)    w$ [! @; O7 y+ R. e0 N
  11.    COM_TX_PORT_CLK                          0x080034f0   Data           4  stm320518_eval.o(.constdata)  
    # ]2 g/ |' o- X. V0 T
  12.    COM_RX_PORT_CLK                          0x080034f4   Data           4  stm320518_eval.o(.constdata)  
    3 U# M/ d0 W1 ~# v
  13.    COM_TX_PIN                               0x080034f8   Data           2  stm320518_eval.o(.constdata)  2 V# O+ {6 l) P8 G7 L: a; b
  14.    COM_RX_PIN                               0x080034fa   Data           2  stm320518_eval.o(.constdata)  
    5 H% B2 r3 {: |* U( X9 i9 y6 i
  15.    COM_TX_PIN_SOURCE                        0x080034fc   Data           2  stm320518_eval.o(.constdata)  $ g) l0 z! U& q; p! f' a, W; R; Y
  16.    COM_RX_PIN_SOURCE                        0x080034fe   Data           2  stm320518_eval.o(.constdata)  - j0 I' X# s& T; l' s0 I" Y# H
  17.    COM_TX_AF                                0x08003500   Data           2  stm320518_eval.o(.constdata)  1 n  o. O  x. Q' Q% I& {2 `3 t0 `  M
  18.    COM_RX_AF                                0x08003502   Data           2  stm320518_eval.o(.constdata)  7 `  ~5 p' o8 \( |
  19.    Region+ |. D' B' N; P8 B
  20. Base                      0x08003504   Number         0  anon5 w2 R0 T8 ~  |0 a
  21. Table)  1 d( N: k# m3 |6 M1 ?3 X
  22.    Region9 x/ b  B7 l) R# b
  23. Limit                     0x08003524   Number         0  anon
    ( s/ j/ V- ]) K& s
  24. Table)  
    " X$ X9 g. Z# z
  25.    VectorTable                              0x20000000   Data         192  main.o(.ARM.__AT_0x20000000)      //向量表位置为0x20000000  5 T  c& G3 G& G/ S6 f9 V
  26.    SystemCoreClock                          0x200000c0   Data           4  system_stm32f0xx.o(.data)         //其他全局变量的起始位置为0x200000C0  
    7 m& X, ~3 E: O' a* K0 x
  27.    AHBPrescTable                            0x200000c4   Data          16  system_stm32f0xx.o(.data)  $ w+ @. E" I. O' N& z5 E, X6 g( |
  28.    GPIO_PORT                                0x200000d4   Data          16  stm320518_eval.o(.data)  
    3 R: D8 B; [5 e# H% J0 r. v
  29.    BUTTON_PORT                              0x200000e4   Data          28  stm320518_eval.o(.data)  8 k0 L2 I$ S# j4 m+ |( z% p$ K
  30.    COM_USART                                0x20000100   Data           4  stm320518_eval.o(.data)  
    , S3 _% D3 ?  |% `1 B4 o. A
  31.    COM_TX_PORT                              0x20000104   Data           4  stm320518_eval.o(.data)  
    ( Y. `4 s+ l7 i1 b7 |/ f
  32.    COM_RX_PORT                              0x20000108   Data           4  stm320518_eval.o(.data)  
    ; }3 e- X# w$ X5 I
  33.    __initial_sp                             0x20000510   Data           0  startup_stm32f0xx.o(STACK)  
复制代码

, o6 }/ y# ^: t4 f" V# j8 R$ V9 N' P如上所述,中断向量表被编译在0x20000000,内存的起始位置,而system_stm32f0xx.c下的全局变量SystemCoreClock被KEIL编译成放在紧挨着的0x200000C0的位置,与预期完全相符。分别将IAP与APP烧录进FLASH,测试可以正常运行。

- P" `1 U( y5 B- H% i
0 W  p# ?$ {6 c注:在KEIL下,必须存在IAP才能调试APP!,这点是与IAR不同的。0 x( f- V! \* l% }! H. g1 H8 ~1 z
0 j# x# I0 x; U1 J+ x

. Y' |" _: l3 X1 e3 IAR下移植

; E% [- d. c  c7 M" s

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

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

+ b6 t3 l# t) r

20160728213900343.png

& p$ I4 w8 i5 \6 w$ b


. V7 b& W4 |2 m  n1 g

链接配置:

中断向量表:

2 X- m3 x- I) e! ]% ^

20160728213954703.png


. l; [/ @) r* r


% M1 k( n; C  ]/ k, h* B3 c7 L

内存映射:

5 D- F- \5 g( H5 u0 X! i+ k8 }) s! a

20160728214047079.png

. L( l3 E- Z4 x, {


5 X4 s( R  t* i

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

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

  1. Entry                      Address  Size  Type      Object  
    1 g, t) F5 |) Z+ e. F7 Y
  2. -----                      -------  ----  ----      ------  
    2 ^# Z7 @+ c+ ?: H4 ~) v; v( \
  3. .iar.init_table$Base   0x080034fc         --   Gb  - Linker created -  $ r& I! F& r2 `* }5 m9 `& r3 H
  4. .iar.init_table$Limit  0x08003510         --   Gb  - Linker created -  
    1 \7 {" Z9 c. C7 r! T: m
  5. ?main                   0x08003511        Code  Gb  cmain.o [4]  
    ! ?$ M3 C9 Z: h
  6. CSTACK$Base            0x200000d8         --   Gb  - Linker created -  
    : V4 U7 n( n, F; v* F
  7. CSTACK$Limit           0x200010d8         --   Gb  - Linker created -  
    / U6 X# W( w5 i, C
  8. Delay                   0x080031e3  0x10  Code  Gb  main.o [1]  7 \( c: H# n8 S5 P& b% L- @" J
  9. GPIO_PIN                0x080035a0   0x8  Data  Gb  stm320518_eval.o [1]  
    * T4 s" Q5 p! T3 l* B: ~
  10. GPIO_PORT               0x200000c0  0x10  Data  Gb  stm320518_eval.o [1]           //stm320518_eval.c文件内的全局变量GPIO_PORT数组存放在0x200000c0  $ d& D4 n* r+ i& C
  11. HardFault_Handler       0x08003573   0x4  Code  Gb  stm32f0xx_it.o [1]  6 [% ^" ?% Q; E5 a; _8 E' @% o3 q
  12. NMI_Handler             0x08003571   0x2  Code  Gb  stm32f0xx_it.o [1]  
    0 d4 b' E% Y+ A( \) @7 t
  13. NVIC_SetPriority        0x080030c1  0x84  Code  Lc  main.o [1]  / N; i3 d2 _( s5 c3 Y
  14. PendSV_Handler          0x08003579   0x2  Code  Gb  stm32f0xx_it.o [1]  
    5 `( k/ o+ j6 e+ A
  15. RCC_APB2PeriphClockCmd  0x08003229  0x20  Code  Gb  stm32f0xx_rcc.o [1]  + w  S7 y+ [, v& C7 _& A
  16. Region8 c7 |( u1 V: r% H6 t2 y
  17. Base     0x080034fc         --   Gb  - Linker created -  8 N& y% b0 g$ @& _1 e. K
  18. Region! w) {5 h" C) |; L: w
  19. Limit    0x08003510         --   Gb  - Linker created -  % p3 D+ r7 {# [6 }
  20. STM_EVAL_LEDToggle      0x08003315  0x26  Code  Gb  stm320518_eval.o [1]  2 n2 {; U' Z% j" c
  21. SVC_Handler             0x08003577   0x2  Code  Gb  stm32f0xx_it.o [1]  
    % ^3 a7 m8 A2 u; s( ~: t9 A1 G
  22. SYSCFG_MemoryRemapConfig  
    . J4 {. H0 r' \1 _- R% c4 p
  23.                         0x0800324d  0x14  Code  Gb  stm32f0xx_syscfg.o [1]  ) L. ^0 R5 L" h
  24. SetSysClock             0x080033b7  0xbe  Code  Lc  system_stm32f0xx.o [1]  : h  H/ |+ [  W& ]: I9 |
  25. SysTick_Config          0x08003145  0x32  Code  Lc  main.o [1]  1 D$ o) v- o9 A+ R6 B
  26. SysTick_Handler         0x0800357b   0x8  Code  Gb  stm32f0xx_it.o [1]  
    " k7 v5 v# M, d. j/ i; N5 _
  27. SystemCoreClock         0x200000d0   0x4  Data  Gb  system_stm32f0xx.o [1]  4 i/ \- m2 M% _( X
  28. SystemInit              0x08003349  0x6e  Code  Gb  system_stm32f0xx.o [1]  ) x+ t: E/ P& Q0 K: c  C
  29. TimingDelay             0x200000d4   0x4  Data  Lc  main.o [1]  ' b5 e& J  ]# l" B0 G( ?
  30. TimingDelay_Decrement   0x080031f3  0x16  Code  Gb  main.o [1]  + A7 j/ a) \7 E( O: O3 F
  31. VectorTable             0x20000000  0xc0  Data  Gb  main.o [1]           //向量表编译位置为0x20000000  $ T. p4 \! |6 b3 D9 n
  32. __aeabi_idiv0           0x08003345        Code  Gb  IntDivZer.o [4]  
    : q2 f8 B5 [0 R% u( D  L  n2 i
  33. __aeabi_uidiv           0x08003265        Code  Gb  I32DivModFast.o [4]  
    " T4 G  r& I9 W; K6 b  w% L6 F
  34. __aeabi_uidivmod        0x08003265        Code  Gb  I32DivModFast.o [4]  % u4 H; `5 l; W" n  e* D& E7 y
  35. __cmain                 0x08003511        Code  Gb  cmain.o [4]  $ R4 c& c4 p+ p. z) a3 ~- e# G! u
  36. __exit                  0x08003545  0x14  Code  Gb  exit.o [5]  
    , g$ ]# r. m) Y
  37. __iar_copy_init3        0x080034a5  0x30  Code  Gb  copy_init3.o [4]  
    4 a+ T* y3 f; U% C6 p# h
  38. __iar_data_init3        0x080034d5  0x28  Code  Gb  data_init.o [4]  1 l7 P. ^& _2 `: O( G" {
  39. __iar_program_start     0x08003595        Code  Gb  cstartup_M.o [4]  
    ( K& {( |+ ?* f5 ~
  40. __low_level_init        0x0800352b   0x4  Code  Gb  low_level_init.o [3]  , F0 K& c% z: q: \3 x% n* N3 i
  41. __vector_table          0x08003000        Data  Gb  startup_stm32f0xx.o [1]  
    # \: I* F7 E# G  `' T
  42. _call_main              0x0800351d        Code  Gb  cmain.o [4]  - z1 \- ^5 n8 z3 Y
  43. _exit                   0x08003539        Code  Gb  cexit.o [4]  ! f+ @5 T( Y  i% l# D3 v7 A
  44. _main                   0x08003527        Code  Gb  cmain.o [4]  
    1 d' ~* y5 D* [# c7 e
  45. exit                    0x0800352f   0x8  Code  Gb  exit.o [3]  
    0 t* z: W3 {/ U3 l9 g* e
  46. main                    0x08003177  0x6c  Code  Gb  main.o [1]  
    / l1 z$ h- d& h5 r* ?- L
复制代码

; Y% x9 d7 x# g* v9 B" M) e如上所示,在IAR编译下,中断向量表被编译在0x20000000,内存的起始位置,而stm320518_eval.c下的全局变量GPIO_PORT被IAR编译成放在紧挨着的0x200000C0的位置。分别将IAP与APP烧录进FLASH,测试可以正常运行。, J$ Z$ J$ t- u* `3 E& X9 ?" }
6 h4 o4 @% h* a

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


1 t  o; [. B# E5 Y, m

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


7 m+ a1 V7 p& j, U; `
# ~& f5 B' }: W0 [: O
_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 手机版