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

【经验分享】STM32启动过程--启动文件--分析

[复制链接]
STMCU小助手 发布时间:2022-1-13 21:00
一、概述
1、说明
  每一款芯片的启动文件都值得去研究,因为它可是你的程序跑的最初一段路,不可以不知道。通过了解启动文件,我们可以体会到处理器的架构、指令集、中断向量安排等内容,是非常值得玩味的。
  STM32作为一款高端Cortex-M3系列单片机,有必要了解它的启动文件。打好基础,为以后优化程序,写出高质量的代码最准备。
  本文以一个实际测试代码--START_TEST为例进行阐述。
2、整体过程概括
  STM整个启动过程是指从上电开始,一直到运行到main函数之间的这段过程,步骤为(以使用微库为例):
①上电后硬件设置SP、PC
②设置系统时钟
③软件设置SP
④加载.data、.bss,并初始化栈区
⑤跳转到C文件的main函数
3、整个启动过程涉及的代码
  启动过程涉及的文件不仅包含startup_stm32f10x_hd.s,还涉及到了MDK自带的连接库文件entry.o、entry2.o、entry5.o、entry7.o等(从生成的map文件可以看出来)。
二、程序在Flash上的存储结构
  在真正讲解启动过程之前,先要讲解程序下载到Flash上的结构和程序运行时(执行到main函数)时的SRAM数据结构。程序在用户Flash上的结构如下图所示。下图是通过阅读hex文件和在MDK下调试综合提炼出来的。
5 j  Q# H9 ]1 x# X( i
092018031206060.png
, B$ A  O3 O5 H3 M  A
MSP初始值        编译器生成,主堆栈的初始值
异常向量表        不多说
外部中断向量表      不多说
代码段          存放代码
初始化数据段       .data
未初始化数据段      .bss
加载数据段和初始化栈的参数
  加载数据段和初始化栈的参数分别有4个,这里只讲解加载数据段的参数,至于初始化栈的参数类似。
0x0800 033c  Flash上的数据段(初始化数据段和未初始化数据段)起始地址
0x2000 0000  加载到SRAM上的目的地址
0x0000 000c  数据段的总大小
0x0800 02f4  调用函数_scatterload_copy
  需要说明的是初始化栈的函数--0x0800 0304与加载数据段的函数不一样,为_scatterload_zeroinit,它的目的就是将栈空间清零。
8 Y; T8 `1 f, q5 a
092032461983346.png
; I2 k; l% p1 c+ R* D
三、数据在SRAM上的结构
  程序运行时(执行到main函数)时的SRAM数据结构
( `6 d7 [3 S% c1 K2 ]3 \
092025271358977.png

( D6 u; T; R1 {
四、详细过程分析
  有了以上的基础,现在详细分析启动过程。
1、上电后硬件设置SP、PC
  刚上电复位后,硬件会自动根据向量表偏移地址找到向量表,向量表偏移地址的定义如下:
+ u8 X7 B- F" g
092045343233846.png
6 q& m# d: j2 q) n2 }  }+ s- X
  调试现象如下:

0 u5 v( w2 d6 k# W$ G1 [( e) ?
092046570579821.png

9 D) \! b  R  f5 K
  看看我们的向量表内容(通过J-Flash打开hex文件)

/ {6 @2 A" x2 o$ P; T
092048562138825.png

3 G& N7 v$ R+ e& h8 j9 Z& ~
  硬件这时自动从0x0800 0000位置处读取数据赋给栈指针SP,然后自动从0x0800 0004位置处读取数据赋给PC,完成复位,结果为:
SP = 0x0200 0810
PC = 0x0800 0145
2、设置系统时钟

# m( p/ ~; r, d7 X" }
092052446511680.png

2 t: h8 m% u; y' e( i' C8 n) {
  上一步中令PC=0x0800 0145的地址没有对齐,硬件自动对齐到0x0800 0144,执行SystemInit函数初始化系统时钟。
3、软件设置SP
  1. LDR   R0,=__main  . d( P* v4 n9 l
  2. BX   R0
复制代码
& j8 l" V1 \& w6 Q: `# G
  执行上两条之类,跳转到__main程序段运行,注意不是main函数,___main的地址是0x0800 0130。
6 E4 z+ c. ?( @! a5 U' n1 S6 n
092100522921657.png
& j! L  x8 L$ L/ B9 ]" u# U9 y
  可以看到指令LDR.W sp,[pc,#12],结果SP=0x2000 0810。
4、加载.data、.bss,并初始化栈区
  1. BL.W     __scatterload_rt2
复制代码
  进入 __scatterload_rt2代码段。
  1. __scatterload_rt2:
    , Z" u. W! f2 c3 N5 M
  2. 0x08000168 4C06      LDR      r4,[pc,#24]  ; @0x080001847 S2 P# [% x% G" i
  3. 0x0800016A 4D07      LDR      r5,[pc,#28]  ; @0x08000188( H$ p( p2 W6 b
  4. 0x0800016C E006      B        0x0800017C
    " t! r. F& o4 t. {
  5. 0x0800016E 68E0      LDR      r0,[r4,#0x0C]
    ) w) V9 V7 D# p4 _& ~% q# t
  6. 0x08000170 F0400301  ORR      r3,r0,#0x013 \' {0 L5 V# H+ \" o: A- i
  7. 0x08000174 E8940007  LDM      r4,{r0-r2}% D1 N( C9 a$ J! X* }
  8. 0x08000178 4798      BLX      r32 P3 j# K+ S5 g. v6 m( @* y
  9. 0x0800017A 3410      ADDS     r4,r4,#0x10
    # [) v) R: j0 Q* M7 p
  10. 0x0800017C 42AC      CMP      r4,r5, z+ H* L: ]7 k, c' w% B
  11. 0x0800017E D3F6      BCC      0x0800016E9 f/ D9 O" ]1 q  {, u' v9 \) S0 G9 a
  12. 0x08000180 F7FFFFDA  BL.W     _main_init (0x08000138)
复制代码
$ s% z) H$ j9 y6 u! i6 q# u3 ]) \
  这段代码是个循环(BCC 0x0800016e),实际运行时候循环了两次。第一次运行的时候,读取“加载数据段的函数(_scatterload_copy)”的地址并跳转到该函数处运行(注意加载已初始化数据段和未初始化数据段用的是同一个函数);第二次运行的时候,读取“初始化栈的函数(_scatterload_zeroinit)”的地址并跳转到该函数处运行。 相应的代码如下:
0x0800016E 68E0      LDR      r0,[r4,#0x0C]0x08000170 F0400301  ORR      r3,r0,#0x010x08000174  
. P' j+ k; l* J0x08000178 4798      BLX      r3" @( Y# _0 B7 m3 ]8 y" J  ?
  % T5 A% M8 a! C0 ?* K- w( p
  当然执行这两个函数的时候,还需要传入参数。至于参数,我们在“加载数据段和初始化栈的参数”环节已经阐述过了。当这两个函数都执行完后,结果就是“数据在SRAM上的结构”所展示的图。最后,也把事实加载和初始化的两个函数代码奉上如下:) p; u- O8 H8 ?1 V; N
  1. 0x0800016E 68E0      LDR      r0,[r4,#0x0C]
    % }& }0 F5 P- l) S, I! g
  2. 0x08000170 F0400301  ORR      r3,r0,#0x018 r/ Z3 P6 L1 S9 `
  3. 0x08000174  ) }+ i4 N4 D+ ?. r( }% c% `7 S5 r
  4. 0x08000178 4798      BLX      r3
复制代码
当然执行这两个函数的时候,还需要传入参数。至于参数,我们在“加载数据段和初始化栈的参数”环节已经阐述过了。当这两个函数都执行完后,结果就是“数据在SRAM上的结构”所展示的图。最后,也把事实加载和初始化的两个函数代码奉上如下:
  1.                  __scatterload_copy:% o* f% A& e( x$ \; K# q1 f
  2. 0x080002F4 E002      B        0x080002FC6 ?# N9 Y+ g; k: r: \2 U/ j
  3. 0x080002F6 C808      LDM      r0!,{r3}; r& t$ I$ `% Y
  4. 0x080002F8 1F12      SUBS     r2,r2,#4
    * s# P. D1 w" ~1 b% ?: m& K7 V. ~1 T
  5. 0x080002FA C108      STM      r1!,{r3}) Z7 |9 E/ D! Q$ ~& F; }) a6 \5 L
  6. 0x080002FC 2A00      CMP      r2,#0x00; Y2 q+ o" s; ~
  7. 0x080002FE D1FA      BNE      0x080002F6& z# ]# L# A. `2 Z
  8. 0x08000300 4770      BX       lr$ O, l) G) ?+ \: c3 U$ `
  9.                  __scatterload_null:& i: E" h& A6 k- K% z6 [
  10. 0x08000302 4770      BX       lr
    9 E! |" o4 N$ l) ^! d5 K( y8 P3 ]- Y
  11.                  __scatterload_zeroinit:/ I3 h0 x$ C' z) N
  12. 0x08000304 2000      MOVS     r0,#0x00
    & ^/ H' n! X/ _+ x, F
  13. 0x08000306 E001      B        0x0800030C- u- Y* t, x. _+ h+ z
  14. 0x08000308 C101      STM      r1!,{r0}% D0 T& |( }, K& u- X. B- J( }5 L
  15. 0x0800030A 1F12      SUBS     r2,r2,#4
    - R( H8 `, U1 x3 k' O# T9 R* V: W
  16. 0x0800030C 2A00      CMP      r2,#0x000 @6 h  @+ g, ~) b" f/ ?- V( p
  17. 0x0800030E D1FB      BNE      0x08000308
    & x) U! b: D; }+ c  K6 b1 f: Z
  18. 0x08000310 4770      BX       lr
复制代码
, d0 K& E! j2 S( i
5、跳转到C文件的main函数
  1.                  _main_init:: K  e/ r3 s+ ]" a0 n
  2. 0x08000138 4800      LDR      r0,[pc,#0]  ; @0x0800013C
    ) i) p7 l& T5 }: N1 ^
  3. 0x0800013A 4700      BX       r0
复制代码
/ Y# k: f- i! c; G7 \0 x
, \& z; L4 t3 s( L3 g6 `+ _
五、异常向量与中断向量表
  1. ; Vector Table Mapped to Address 0 at Reset' Z: `5 f& c* T. ]1 l) J) B% t' K
  2.                 AREA    RESET, DATA, READONLY
    + C2 }) b" k" o. c5 g+ H
  3.                 EXPORT  __Vectors
    $ |( B# N  V/ U
  4.                 EXPORT  __Vectors_End
    9 u; m& x% ?1 h1 [/ F" {8 \
  5.                 EXPORT  __Vectors_Size
    2 x; }7 @5 [" U4 H

  6. 1 g0 x* M2 R* z/ R" L/ C% T/ }1 ?7 x" Q
  7. __Vectors       DCD     __initial_sp               ; Top of Stack
    6 G  `/ H2 W0 T: [% X
  8.                 DCD     Reset_Handler              ; Reset Handler
    * v' G. `7 q1 q  p) P
  9.                 DCD     NMI_Handler                ; NMI Handler
    * w2 j3 S# S8 U+ Q" l( E
  10.                 DCD     HardFault_Handler          ; Hard Fault Handler
      [$ b0 A8 z, }- i: B  Q0 M1 y
  11.                 DCD     MemManage_Handler          ; MPU Fault Handler
    + V4 m$ B" r; o% ~6 H
  12.                 DCD     BusFault_Handler           ; Bus Fault Handler' w; u. f  e3 A4 g/ S& J7 K  S
  13.                 DCD     UsageFault_Handler         ; Usage Fault Handler6 u, x. o1 i  t" B' T( u
  14.                 DCD     0                          ; Reserved: p5 C" B; P/ B5 y" _5 i; ^
  15.                 DCD     0                          ; Reserved
      k8 a6 x; T* K8 @
  16.                 DCD     0                          ; Reserved
    8 L% B8 }/ \! ~6 J5 z# }8 D+ d
  17.                 DCD     0                          ; Reserved3 l8 }5 e. E2 A0 ^
  18.                 DCD     SVC_Handler                ; SVCall Handler
    4 I3 v9 Y) q$ l- `' d, S
  19.                 DCD     DebugMon_Handler           ; Debug Monitor Handler! T- J+ p; O  j* H
  20.                 DCD     0                          ; Reserved9 M/ o; b/ Q. J' {9 a3 l
  21.                 DCD     PendSV_Handler             ; PendSV Handler/ n4 H. s6 `% i6 x  ]
  22.                 DCD     SysTick_Handler            ; SysTick Handler  T: d. A! }: ~% [- N! S: C0 d  g, D
  23. 8 y- y4 ]2 a( c) s
  24.                 ; External Interrupts
    + _. i  W! ~  z: S- G/ k$ }* f8 l
  25.                 DCD     WWDG_IRQHandler            ; Window Watchdog
    $ H# ?, a" W. b' \" A
  26.                 DCD     PVD_IRQHandler             ; PVD through EXTI Line detect9 m/ c# Y$ E& X# d3 R) K% f0 [
  27.                 DCD     TAMPER_IRQHandler          ; Tamper6 `* ~, l  O+ y
  28.                 DCD     RTC_IRQHandler             ; RTC
    0 G8 r0 \% G; r2 E/ m) Q
  29.                 DCD     FLASH_IRQHandler           ; Flash
      H) V( J; k9 Z" K2 W8 W! r
  30.                 DCD     RCC_IRQHandler             ; RCC/ q* R; l1 X' B/ Z+ i$ \! N; }  x
  31.                 DCD     EXTI0_IRQHandler           ; EXTI Line 0! d+ p+ e; g( T7 ]  V
  32.                 DCD     EXTI1_IRQHandler           ; EXTI Line 1
    + M. C) Y1 m( Q" b2 G6 f
  33.                 DCD     EXTI2_IRQHandler           ; EXTI Line 2( z- T; }( n) P5 ^! `. _
  34.                 DCD     EXTI3_IRQHandler           ; EXTI Line 3- D$ F  U% q- W- L5 l( R- n5 R
  35.                 DCD     EXTI4_IRQHandler           ; EXTI Line 4% G; w/ f3 _8 L( x$ A$ I
  36.                 DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
    1 M2 m2 J5 Q, g4 h+ p
  37.                 DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
    " e" G- u' r6 \4 x3 u" o: e
  38.                 DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
    " |* m' [' s  P2 L" E' _; L
  39.                 DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4  @6 J- z3 G8 e, Y, f7 E# ]4 p
  40.                 DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
    2 A$ Q5 s9 X! l# H
  41.                 DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
    ' v. e1 x) y  U5 \: K
  42.                 DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
    # o; l$ T* ?; a2 _1 r  y
  43.                 DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2' y" D$ r* m  y) o+ c# L- X8 k
  44.                 DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX6 z* W1 n: T6 r3 a4 j/ u, O
  45.                 DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
    + d$ j* ~2 R& p
  46.                 DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
    % y3 i' O1 Z( V( b6 `2 Z
  47.                 DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE0 x6 u( x3 \* s' B8 L
  48.                 DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
    & _1 G; K; v% H
  49.                 DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
    ) K, B( V/ z+ x0 d# {2 I6 e
  50.                 DCD     TIM1_UP_IRQHandler         ; TIM1 Update2 q. U. V! e2 {) s: m; x
  51.                 DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation; W7 d& [: w/ g2 W8 Z4 N; l" m
  52.                 DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare7 C1 P5 O# {! t9 L# p% w. B  `) `
  53.                 DCD     TIM2_IRQHandler            ; TIM2
    9 }* n2 U+ G1 s& U$ ~
  54.                 DCD     TIM3_IRQHandler            ; TIM3
    8 d7 |7 s' Q7 Z% R: Y, {' {
  55.                 DCD     TIM4_IRQHandler            ; TIM4
    / }4 ]# r* D! `& V. M
  56.                 DCD     I2C1_EV_IRQHandler         ; I2C1 Event. b* l/ z, D/ W. S6 ]+ Q3 f( X4 v
  57.                 DCD     I2C1_ER_IRQHandler         ; I2C1 Error7 Y* m! H# r2 t8 t3 `3 _+ S
  58.                 DCD     I2C2_EV_IRQHandler         ; I2C2 Event
    4 K/ |- W% m1 H: V2 C6 }. v7 @
  59.                 DCD     I2C2_ER_IRQHandler         ; I2C2 Error
    : I* s  q0 b8 l
  60.                 DCD     SPI1_IRQHandler            ; SPI1
    2 E2 ]9 p& j# _
  61.                 DCD     SPI2_IRQHandler            ; SPI2
    * E0 x* O' u/ P  M& j# d& l
  62.                 DCD     USART1_IRQHandler          ; USART1
    ! }2 _. F8 S6 L2 z
  63.                 DCD     USART2_IRQHandler          ; USART2
    . t6 s- [1 ?: X$ |3 ~' J
  64.                 DCD     USART3_IRQHandler          ; USART36 D% q0 Z+ F1 k  h
  65.                 DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..103 F3 _0 i, L" [3 b
  66.                 DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
    1 C5 d7 Z8 l/ b- |! A3 ^) o
  67.                 DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend) N; W3 O; e; P% l, P- ~" S5 z
  68.                 DCD     TIM8_BRK_IRQHandler        ; TIM8 Break# f, G. |6 j* }: j! V- p
  69.                 DCD     TIM8_UP_IRQHandler         ; TIM8 Update
    4 k7 |$ N; Q# e5 L3 ~) j
  70.                 DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
    ! X! M) Y  Y- v8 h0 G
  71.                 DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
    ) L( Q, j, R0 Y2 ]4 Q7 i/ W
  72.                 DCD     ADC3_IRQHandler            ; ADC30 m0 S% r/ _; q& G
  73.                 DCD     FSMC_IRQHandler            ; FSMC
    7 x, R/ |8 k( C) P3 o
  74.                 DCD     SDIO_IRQHandler            ; SDIO
    + l( F' o; O4 `
  75.                 DCD     TIM5_IRQHandler            ; TIM5" \+ r+ T4 Y" }9 s9 ]8 L& R, V& o
  76.                 DCD     SPI3_IRQHandler            ; SPI3% v$ {# q6 v( B, Y  ?5 K
  77.                 DCD     UART4_IRQHandler           ; UART4! f& F8 B; {' u$ N$ O2 x
  78.                 DCD     UART5_IRQHandler           ; UART5
    7 N, @) \7 S+ z- c" u# }% I2 d; |
  79.                 DCD     TIM6_IRQHandler            ; TIM6- F4 |1 K: V3 W4 S8 r" i, k. ?' l
  80.                 DCD     TIM7_IRQHandler            ; TIM7
    - v# j' J6 l7 z, E
  81.                 DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1& E. e8 D0 @% ~; ~# W
  82.                 DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
    # k. t$ J6 E7 Y5 j, W
  83.                 DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel36 m; k5 C% X0 [; {% N7 g
  84.                 DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5: h4 X/ r/ U& S
  85. __Vectors_End
复制代码

! S* M4 `6 `, o" Y* l2 B
  这段代码就是定义异常向量表,在之前有一个“J-Flash打开hex文件”的图片跟这个表格是一一对应的。编译器根据我们定义的函数 Reset_Handler、NMI_Handler等,在连接程序阶段将这个向量表填入这些函数的地址。
  1. startup_stm32f10x_hd.s内容:; c2 ]$ Q: O1 ?2 o2 C; a. l

  2. ; L/ w6 u6 I) W2 u
  3. NMI_Handler     PROC9 E9 z' c5 x+ h) p. J5 ]" ~
  4.                 EXPORT  NMI_Handler                [WEAK]
    5 U2 c5 ^/ w$ ?& p: P* X" B/ C
  5.                 B       .
      J* ~; P, ?5 d
  6.                 ENDP$ i  b& p: A9 W& P0 @

  7. 7 P5 e; A6 a7 K  z3 L% y

  8. 1 U: C+ ^% V; q9 ^  K0 C
  9. stm32f10x_it.c中内容:
      c8 a$ ~) s" H7 S5 u
  10. void NMI_Handler(void)7 M# [/ R& D" L
  11. {) @& L. a! j# [$ k5 W3 J, `
  12. }
复制代码
: o; Q, q" M- T1 G2 G: z/ z2 E
  在启动汇编文件中已经定义了函数NMI_Handler,但是使用了“弱”,它允许我们再重新定义一个NMI_Handler函数,程序在编译的时候会将汇编文件中的弱函数“覆盖掉”--两个函数的代码在连接后都存在,只是在中断向量表中的地址填入的是我们重新定义函数的地址。
六、使用微库与不使用微库的区别
092134086673127.png

# s2 K! {( a# q. S7 o
  使用微库就意味着我们不想使用MDK提供的库函数,而想用自己定义的库函数,比如说printf函数。那么这一点是怎样实现的呢?我们以printf函数为例进行说明。
1、不使用微库而使用系统库
  在连接程序时,肯定会把系统中包含printf函数的库拿来调用参与连接,即代码段有系统库的参与。
  在启动过程中,不使用微库而使用系统库在初始化栈的时候,还需要初始化堆(猜测系统库需要用到堆),而使用微库则是不需要的。
  1.                  IF      :DEF:__MICROLIB5 H; ~1 e, o* n) A4 h' \
  2.                
    & ~* }- l: f' W' |" [. J
  3.                  EXPORT  __initial_sp
    - J' h7 `# S8 V8 u5 E+ N9 P
  4.                  EXPORT  __heap_base
    % j; f% e2 I: W6 u4 y; E
  5.                  EXPORT  __heap_limit
    & N" I" q; N# G/ K) @6 J  _6 ]) J
  6.                 / R) i* ^) ]# P- g8 l
  7.                  ELSE
    - P7 _6 Z9 [+ g/ \2 F* [
  8.                
    - D) L8 a# f* l  D
  9.                  IMPORT  __use_two_region_memory3 G. f4 G8 S7 F1 A4 W) r
  10.                  EXPORT  __user_initial_stackheap
    0 V/ s9 u& {, E% o( G: s
  11.                  
    + z1 [8 Z" h6 a* W
  12. __user_initial_stackheap' S* f8 j; }- ]* D) Q
  13. # V5 @, I/ @' H: {2 K2 Y6 e) A7 o4 Z
  14.                  LDR     R0, =  Heap_Mem
    ) b: _) M; s" q# ^% K/ ~3 ^
  15.                  LDR     R1, =(Stack_Mem + Stack_Size)+ D2 K4 t$ c9 c/ L2 L& K+ N# w. T
  16.                  LDR     R2, = (Heap_Mem +  Heap_Size)
    . n: o9 O. @* f% r, I4 e1 S
  17.                  LDR     R3, = Stack_Mem7 }. `' f9 Y/ r
  18.                  BX      LR
    9 Z8 S$ y1 `2 l6 Y( X
  19. ( c) L: j( p; z5 g3 ?3 s
  20.                  ALIGN$ u( }3 b7 y# w% \
  21. 8 V7 U9 _7 k( C) ^
  22.                  ENDIF
复制代码
* U" J" f  r# `# m" |# T
  另外,在执行__main函数的过程中,不仅需要完成“使用微库”情况下的所有工作,额外的工作还需要进行库的初始化,才能使用系统库(这一部分我还没有深入探讨)。附上__main函数的内容:
  1.                   __main:) j9 [/ i6 T( ?3 }4 D0 p
  2. 0x08000130 F000F802  BL.W     __scatterload_rt2_thumb_only (0x08000138)
    5 b7 h5 I% z8 T9 Q% s) m
  3. 0x08000134 F000F83C  BL.W     __rt_entry_sh (0x080001B0)
    7 K; n  @, R4 j' V* K2 e% u) M* S
  4.                  __scatterload_rt2_thumb_only:
    6 w' n2 H4 }6 P5 ]; W7 M/ |0 S
  5. 0x08000138 A00A      ADR      r0,{pc}+4  ; @0x08000164
    , R" S5 @: `. E" }, q
  6. 0x0800013A E8900C00  LDM      r0,{r10-r11}
    % u( W# a9 v! F* ]3 @: V8 x
  7. 0x0800013E 4482      ADD      r10,r10,r0* j- j. z1 X- P4 a3 c) M
  8. 0x08000140 4483      ADD      r11,r11,r09 S3 z8 [' K) U
  9. 0x08000142 F1AA0701  SUB      r7,r10,#0x01
    8 z: a2 P' F& I! o
  10.                  __scatterload_null:: B5 H% v3 m6 W! C7 k/ e
  11. 0x08000146 45DA      CMP      r10,r11
    " @' ^: s1 h( K. S% Y6 K) V$ i) P% i4 ]
  12. 0x08000148 D101      BNE      0x0800014E
    ) q9 ^& C% F4 d: u6 {% Y4 G6 y
  13. 0x0800014A F000F831  BL.W     __rt_entry_sh (0x080001B0)
    - s( n! ?, l4 ~# m
  14. 0x0800014E F2AF0E09  ADR.W    lr,{pc}-0x07  ; @0x08000147
    ' `+ }/ r$ G, G( U7 D
  15. 0x08000152 E8BA000F  LDM      r10!,{r0-r3}8 C0 r! `  P+ ]$ o( s
  16. 0x08000156 F0130F01  TST      r3,#0x012 e8 O! B" ?. x' _" N& C; F0 _1 o. F
  17. 0x0800015A BF18      IT       NE% q% \" O4 [/ z* W
  18. 0x0800015C 1AFB      SUBNE    r3,r7,r3
      v) f- E) d& i: a: u
  19. 0x0800015E F0430301  ORR      r3,r3,#0x01
    7 z& s: Y% Q: z9 e8 _" h
  20. 0x08000162 4718      BX       r3
    6 G4 U: h1 G; [9 @
  21. 0x08000164 0298      LSLS     r0,r3,#10
    " d, `9 e( c8 P
  22. 0x08000166 0000      MOVS     r0,r0
    % b; m6 K& Y2 x
  23. 0x08000168 02B8      LSLS     r0,r7,#10
    " {/ H' [6 c, e6 t; _6 O( h9 E
  24. 0x0800016A 0000      MOVS     r0,r0
    4 l9 Q3 r* d% x5 W  |  a
  25.                  __scatterload_copy:, Z" i6 _, q+ i! j! I8 ?; Q
  26. 0x0800016C 3A10      SUBS     r2,r2,#0x10
    2 r. Y0 [: Q5 p* T$ |9 {8 y! H1 b
  27. 0x0800016E BF24      ITT      CS( z* _8 Z! E6 ^0 x
  28. 0x08000170 C878      LDMCS    r0!,{r3-r6}; A6 h/ Z6 z% [- K- u1 n1 u
  29. 0x08000172 C178      STMCS    r1!,{r3-r6}
    * f& P) ~. s. B( Q# L+ g- K
  30. 0x08000174 D8FA      BHI      __scatterload_copy (0x0800016C)2 G; K5 H( u' d9 j2 Z
  31. 0x08000176 0752      LSLS     r2,r2,#29
    9 y4 `+ j5 u3 ~4 D- c* v7 m
  32. 0x08000178 BF24      ITT      CS8 v6 r2 M* Z/ h* r  ~
  33. 0x0800017A C830      LDMCS    r0!,{r4-r5}  ]& K! T: G4 F) V$ o
  34. 0x0800017C C130      STMCS    r1!,{r4-r5}
    - R0 r' h$ D2 _: P' S
  35. 0x0800017E BF44      ITT      MI
    9 A# J$ X# k1 |; F! M1 [
  36. 0x08000180 6804      LDRMI    r4,[r0,#0x00]
    ; p; J2 g7 Q2 u" F0 m) m% X: `) C
  37. 0x08000182 600C      STRMI    r4,[r1,#0x00]) {) Q2 M' R* P/ G& i
  38. 0x08000184 4770      BX       lr
    7 M. B" n! d: {. V: L" J/ x) y8 G# e
  39. 0x08000186 0000      MOVS     r0,r0
    . Z: u- Z! ]* m6 M" {9 F! _/ t# y
  40.                  __scatterload_zeroinit:  h9 L( }, c$ p' e# Z& [
  41. 0x08000188 2300      MOVS     r3,#0x00
    ' P. h) p; x9 F1 X; u: S
  42. 0x0800018A 2400      MOVS     r4,#0x00
    5 M1 o7 Y, Q6 ~  ]+ t
  43. 0x0800018C 2500      MOVS     r5,#0x00' X1 N8 |; N) Z+ r; F# y
  44. 0x0800018E 2600      MOVS     r6,#0x00
    2 t2 B0 |8 B- T( K
  45. 0x08000190 3A10      SUBS     r2,r2,#0x10
    & S5 P4 _. r" C- S; u
  46. 0x08000192 BF28      IT       CS3 t% O7 a4 ]' N5 b
  47. 0x08000194 C178      STMCS    r1!,{r3-r6}
    & L/ _) v" x! W- a) F1 G
  48. 0x08000196 D8FB      BHI      0x08000190% U( e, x' u" U( ^0 i+ Y
  49. 0x08000198 0752      LSLS     r2,r2,#29
    0 R) W% W+ g6 ^+ O) H
  50. 0x0800019A BF28      IT       CS" w8 t0 D7 d: W' g/ R' {
  51. 0x0800019C C130      STMCS    r1!,{r4-r5}: ?. c; M6 `4 Z) O) I& q$ \
  52. 0x0800019E BF48      IT       MI
    : f: T  R% G0 q! Q: v1 s  S+ K
  53. 0x080001A0 600B      STRMI    r3,[r1,#0x00]0 ~6 s4 l8 A$ n1 q; E9 G
  54. 0x080001A2 4770      BX       lr
    0 Q7 y$ E/ g7 h  i# |2 }9 d
  55.                  __rt_lib_init:
    # F* q, |  v7 U7 u9 \) w9 i
  56. 0x080001A4 B51F      PUSH     {r0-r4,lr}4 c$ @7 G2 n3 i  t
  57. 0x080001A6 F3AF8000  NOP.W    * Y0 k) I6 \1 @; ~7 A3 r8 S( p
  58.                  __rt_lib_init_user_alloc_1:
    + ]% h1 B8 Z" L
  59. 0x080001AA BD1F      POP      {r0-r4,pc}
    # D3 L7 Q7 e5 k2 m1 J1 A
  60.                  __rt_lib_shutdown:# }, I- f# }2 r, L/ E( R
  61. 0x080001AC B510      PUSH     {r4,lr}1 o4 z2 \9 |6 [2 g
  62.                  __rt_lib_shutdown_user_alloc_1:
    6 L$ O( T; _% F5 f
  63. 0x080001AE BD10      POP      {r4,pc}8 G% B7 v- n; y
  64.                  __rt_entry_sh:* }. ~8 ~6 D/ M) V* x
  65. 0x080001B0 F000F82F  BL.W     __user_setup_stackheap (0x08000212)8 g& }+ t9 P. `2 Z8 f  N6 u* N
  66. 0x080001B4 4611      MOV      r1,r2
    3 C% h4 z5 N& o( v
  67.                  __rt_entry_postsh_1:
    : F. y# |7 {5 J/ U
  68. 0x080001B6 F7FFFFF5  BL.W     __rt_lib_init (0x080001A4)/ o6 Z( ^* E5 U8 M! X- F
  69.                  __rt_entry_postli_1:' Y6 z/ n5 V% h' H
  70. 0x080001BA F000F919  BL.W     main (0x080003F0)
复制代码
& m/ F: R" V4 L$ C
2、使用微库而不使用系统库
  在程序连接时,不会把包含printf函数的库连接到终极目标文件中,而使用我们定义的库。
  启动时需要完成的工作就是之前论述的步骤1、2、3、4、5,相比使用系统库,启动过程步骤更少。
0 Z2 d0 [, ]% [) Q- i
4 o! `; o& z& C* K
收藏 评论0 发布时间:2022-1-13 21:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版