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

【经验分享】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下调试综合提炼出来的。

7 ^3 |' ?$ z+ E5 d6 y4 n
092018031206060.png

. }0 M6 g  `0 f$ p# ^$ P
MSP初始值        编译器生成,主堆栈的初始值
异常向量表        不多说
外部中断向量表      不多说
代码段          存放代码
初始化数据段       .data
未初始化数据段      .bss
加载数据段和初始化栈的参数
  加载数据段和初始化栈的参数分别有4个,这里只讲解加载数据段的参数,至于初始化栈的参数类似。
0x0800 033c  Flash上的数据段(初始化数据段和未初始化数据段)起始地址
0x2000 0000  加载到SRAM上的目的地址
0x0000 000c  数据段的总大小
0x0800 02f4  调用函数_scatterload_copy
  需要说明的是初始化栈的函数--0x0800 0304与加载数据段的函数不一样,为_scatterload_zeroinit,它的目的就是将栈空间清零。

) W- n- k; _) G' Q# W/ ]* `
092032461983346.png

# A$ X( h1 o+ ^/ t/ Q9 l( `% Q2 W
三、数据在SRAM上的结构
  程序运行时(执行到main函数)时的SRAM数据结构
: d! z& o) H1 @' \+ g3 q8 @
092025271358977.png
/ C6 ?  [% F# z  W1 j7 z
四、详细过程分析
  有了以上的基础,现在详细分析启动过程。
1、上电后硬件设置SP、PC
  刚上电复位后,硬件会自动根据向量表偏移地址找到向量表,向量表偏移地址的定义如下:

: q7 O: C! _( J! q( R/ F9 F4 }
092045343233846.png

4 s; t. U9 p2 Z- h; b3 r
  调试现象如下:

, S. f& Q: E7 }; b, ]
092046570579821.png

- j# @2 I) b5 L) r, N
  看看我们的向量表内容(通过J-Flash打开hex文件)
  N( J- B) X. ^$ ?
092048562138825.png

8 g) j. I: ~. r
  硬件这时自动从0x0800 0000位置处读取数据赋给栈指针SP,然后自动从0x0800 0004位置处读取数据赋给PC,完成复位,结果为:
SP = 0x0200 0810
PC = 0x0800 0145
2、设置系统时钟

0 i# K4 f" k7 f# C) e1 m. y2 g
092052446511680.png

, g$ o9 J  D5 ~& J/ @1 e/ W2 }$ ~
  上一步中令PC=0x0800 0145的地址没有对齐,硬件自动对齐到0x0800 0144,执行SystemInit函数初始化系统时钟。
3、软件设置SP
  1. LDR   R0,=__main  
    9 i" q: ~: U& Z5 O" I. V
  2. BX   R0
复制代码
& N2 L/ X* M2 `8 t: |
  执行上两条之类,跳转到__main程序段运行,注意不是main函数,___main的地址是0x0800 0130。

" J$ m5 ?# H( [7 J& E5 W5 Z
092100522921657.png

. c- S3 z5 r" v$ M" s) [
  可以看到指令LDR.W sp,[pc,#12],结果SP=0x2000 0810。
4、加载.data、.bss,并初始化栈区
  1. BL.W     __scatterload_rt2
复制代码
  进入 __scatterload_rt2代码段。
  1. __scatterload_rt2:+ S! S) E- F6 O/ b# P2 {
  2. 0x08000168 4C06      LDR      r4,[pc,#24]  ; @0x08000184
    & B& @: N7 [! H7 g
  3. 0x0800016A 4D07      LDR      r5,[pc,#28]  ; @0x08000188. O9 M9 v: }3 ?8 r& L) p
  4. 0x0800016C E006      B        0x0800017C
    4 w, S' A( U3 i* Y( p# M# J  d4 v
  5. 0x0800016E 68E0      LDR      r0,[r4,#0x0C]
    6 j8 V8 a3 o; _- l8 x# o1 B# N5 k# E
  6. 0x08000170 F0400301  ORR      r3,r0,#0x01
    ! S$ i+ {/ ~' ?
  7. 0x08000174 E8940007  LDM      r4,{r0-r2}
    ' N+ C) D$ K% f4 B; [
  8. 0x08000178 4798      BLX      r35 F" _7 m1 f( R9 ?# b' h/ K# g
  9. 0x0800017A 3410      ADDS     r4,r4,#0x10' G6 D  z+ |" v/ @" M  Y( z
  10. 0x0800017C 42AC      CMP      r4,r5
    9 ]. `- J5 m& z' V1 e
  11. 0x0800017E D3F6      BCC      0x0800016E- t  Y$ j7 ]: R. @. n/ d3 c" H' ~
  12. 0x08000180 F7FFFFDA  BL.W     _main_init (0x08000138)
复制代码

& D# j6 ]9 E0 D% k0 p
  这段代码是个循环(BCC 0x0800016e),实际运行时候循环了两次。第一次运行的时候,读取“加载数据段的函数(_scatterload_copy)”的地址并跳转到该函数处运行(注意加载已初始化数据段和未初始化数据段用的是同一个函数);第二次运行的时候,读取“初始化栈的函数(_scatterload_zeroinit)”的地址并跳转到该函数处运行。 相应的代码如下:
0x0800016E 68E0      LDR      r0,[r4,#0x0C]0x08000170 F0400301  ORR      r3,r0,#0x010x08000174  " B, i/ r/ f: z
0x08000178 4798      BLX      r3, s. z+ l5 H7 L. v+ N
  5 O! k1 Q4 {" n; }
  当然执行这两个函数的时候,还需要传入参数。至于参数,我们在“加载数据段和初始化栈的参数”环节已经阐述过了。当这两个函数都执行完后,结果就是“数据在SRAM上的结构”所展示的图。最后,也把事实加载和初始化的两个函数代码奉上如下:, U- ?- N; c2 m" w6 T
  1. 0x0800016E 68E0      LDR      r0,[r4,#0x0C]5 f/ Q4 J1 E- o: L! W& Y
  2. 0x08000170 F0400301  ORR      r3,r0,#0x011 ]$ E* w! K7 q0 y
  3. 0x08000174  5 b( b+ b- k% w& b: s7 b
  4. 0x08000178 4798      BLX      r3
复制代码
当然执行这两个函数的时候,还需要传入参数。至于参数,我们在“加载数据段和初始化栈的参数”环节已经阐述过了。当这两个函数都执行完后,结果就是“数据在SRAM上的结构”所展示的图。最后,也把事实加载和初始化的两个函数代码奉上如下:
  1.                  __scatterload_copy:
    5 k( s1 z, ?4 V8 \
  2. 0x080002F4 E002      B        0x080002FC& {- X0 s, l$ }2 R% `$ V0 [
  3. 0x080002F6 C808      LDM      r0!,{r3}
    1 W2 ~3 u& [9 n8 X
  4. 0x080002F8 1F12      SUBS     r2,r2,#4
    8 e( ^' V: N7 D2 R& W% T, V
  5. 0x080002FA C108      STM      r1!,{r3}: P) U* Q& r7 K
  6. 0x080002FC 2A00      CMP      r2,#0x005 o% L( k' A4 [7 u8 w2 G
  7. 0x080002FE D1FA      BNE      0x080002F63 }  q! l; D  z' N
  8. 0x08000300 4770      BX       lr/ y4 E, g  Z/ _) g; \
  9.                  __scatterload_null:- H2 R7 O! o8 u; }+ n  M+ K
  10. 0x08000302 4770      BX       lr
    4 U/ c  H/ r3 v  O+ K! t" d
  11.                  __scatterload_zeroinit:" I: \! `) G' ?- [) m# f
  12. 0x08000304 2000      MOVS     r0,#0x00
    , @* X' h; f: X) b. y
  13. 0x08000306 E001      B        0x0800030C
    2 G7 I1 u2 s! E6 o1 X8 g
  14. 0x08000308 C101      STM      r1!,{r0}& |9 x3 z# J3 g. i
  15. 0x0800030A 1F12      SUBS     r2,r2,#4
    7 l5 C  K. i5 K7 R
  16. 0x0800030C 2A00      CMP      r2,#0x00( t' Z/ K+ G1 \
  17. 0x0800030E D1FB      BNE      0x08000308+ y8 p. v/ t1 D! }  {
  18. 0x08000310 4770      BX       lr
复制代码

* ]# d6 U+ E( I6 i6 B, T$ g9 c
5、跳转到C文件的main函数
  1.                  _main_init:
    0 P" [- B2 Z4 w/ T7 v- Q, z
  2. 0x08000138 4800      LDR      r0,[pc,#0]  ; @0x0800013C1 V5 H" x% r- m* ~
  3. 0x0800013A 4700      BX       r0
复制代码

- P+ B' z  k7 G% ?/ M) P, o; i
  p5 X. Z( K* T: o- |" C, @' B
五、异常向量与中断向量表
  1. ; Vector Table Mapped to Address 0 at Reset! a: b- ~# @. _4 ^  R5 n2 T0 s3 f
  2.                 AREA    RESET, DATA, READONLY
    % W3 g. \1 \) \8 b% a9 F& T/ W
  3.                 EXPORT  __Vectors9 O! m2 ^, m5 l- v+ P
  4.                 EXPORT  __Vectors_End
    ; q. [* Z' ^" u6 _) j/ T
  5.                 EXPORT  __Vectors_Size7 \- X% m# m$ \/ b# R

  6. $ U0 s5 U$ p6 o& i/ _$ {3 V
  7. __Vectors       DCD     __initial_sp               ; Top of Stack$ v9 O# K3 O% i8 n
  8.                 DCD     Reset_Handler              ; Reset Handler+ w# K9 k( s/ w  h0 k4 C
  9.                 DCD     NMI_Handler                ; NMI Handler" T+ q2 V9 B1 y6 E5 W
  10.                 DCD     HardFault_Handler          ; Hard Fault Handler2 G3 P9 a; d  b& ~- p
  11.                 DCD     MemManage_Handler          ; MPU Fault Handler
      n' u* r+ w6 r* [$ F
  12.                 DCD     BusFault_Handler           ; Bus Fault Handler3 u% I1 ?- q' o7 r) s+ u
  13.                 DCD     UsageFault_Handler         ; Usage Fault Handler
    8 \# k0 u9 ?8 |! X8 J1 y0 Q1 \# I
  14.                 DCD     0                          ; Reserved
    - T  Q/ {# Z- R; u5 ]) r
  15.                 DCD     0                          ; Reserved' c% D2 N2 E/ R4 J/ S  U/ _
  16.                 DCD     0                          ; Reserved) U/ S' v5 m6 u; C. d; l
  17.                 DCD     0                          ; Reserved  d3 b% ~3 P7 B1 C, N/ f
  18.                 DCD     SVC_Handler                ; SVCall Handler# j6 {% Z7 }5 g5 [0 A
  19.                 DCD     DebugMon_Handler           ; Debug Monitor Handler
    2 d7 P0 y% q' q2 m! G
  20.                 DCD     0                          ; Reserved% W  Q* o8 k; m: h3 U! V/ v
  21.                 DCD     PendSV_Handler             ; PendSV Handler( U& x$ E: ]: J+ c0 h$ G( |
  22.                 DCD     SysTick_Handler            ; SysTick Handler
    , f7 J' P; ~( I; T8 ^  W; ?# I$ S

  23. 2 {( ?; W3 n7 s& U( ?0 ~4 d* B# x
  24.                 ; External Interrupts* F* p9 Q2 q, X  h
  25.                 DCD     WWDG_IRQHandler            ; Window Watchdog3 k: Y$ W) b5 {1 x
  26.                 DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
    0 K5 v) s. X7 i* h
  27.                 DCD     TAMPER_IRQHandler          ; Tamper
    3 ]9 L  r9 X5 N1 E) ~7 I1 _
  28.                 DCD     RTC_IRQHandler             ; RTC
    & h" y: A+ b- O7 T- v; k
  29.                 DCD     FLASH_IRQHandler           ; Flash
    8 g: I& K5 X& ]# D( p3 D
  30.                 DCD     RCC_IRQHandler             ; RCC, D) {# g/ R% U5 f" m8 U5 d/ I
  31.                 DCD     EXTI0_IRQHandler           ; EXTI Line 0- W8 j0 S' V- z* x
  32.                 DCD     EXTI1_IRQHandler           ; EXTI Line 1
    % i5 Q$ _5 P* @) ]
  33.                 DCD     EXTI2_IRQHandler           ; EXTI Line 2
      Q' e) K6 n$ {7 c1 x
  34.                 DCD     EXTI3_IRQHandler           ; EXTI Line 3$ I, X7 l1 E$ b  S  y
  35.                 DCD     EXTI4_IRQHandler           ; EXTI Line 4
    & g& z4 i' Y5 `8 z
  36.                 DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
    $ }" n1 r+ J$ z: }, _, R
  37.                 DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2. o# j% M( |4 ]% _6 H
  38.                 DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3, n$ W" [" l6 m9 s8 [0 U
  39.                 DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
    7 R6 r: ^6 o( X3 S8 _$ K! h
  40.                 DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
    & A( I/ R. B7 }$ s2 m# y
  41.                 DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
    / B  ^4 m( k$ Q' d. ^3 ~7 B+ F
  42.                 DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 71 j" {5 Z" G  k. N* C
  43.                 DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2- g! M* w* k5 n& {9 r
  44.                 DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX9 T9 g( o! m! a7 b
  45.                 DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX08 q+ Z& n3 T5 k
  46.                 DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
    * @+ f$ A4 P. }, H  V+ ~8 {' z# B
  47.                 DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE2 w% D8 L- p7 b! q5 _. H# q
  48.                 DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..57 W$ L: M9 ^0 q
  49.                 DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
    ( V/ N4 ~* }" v  S8 d
  50.                 DCD     TIM1_UP_IRQHandler         ; TIM1 Update
    : E$ h( Q# O1 t6 w% o
  51.                 DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation& m. E# N% d) ]' b' R$ p  X( }
  52.                 DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare6 ^, p3 E% ~7 \( g& K, J
  53.                 DCD     TIM2_IRQHandler            ; TIM2
    ! |$ a) c7 S. u7 M$ ?) \! L4 \
  54.                 DCD     TIM3_IRQHandler            ; TIM3
    $ z# k( D3 o4 m( w1 l! j& P
  55.                 DCD     TIM4_IRQHandler            ; TIM4
    $ B3 m' V' r3 k3 B" K
  56.                 DCD     I2C1_EV_IRQHandler         ; I2C1 Event; c9 l, n2 t9 K2 t
  57.                 DCD     I2C1_ER_IRQHandler         ; I2C1 Error
    2 P# U* `  B6 C8 J
  58.                 DCD     I2C2_EV_IRQHandler         ; I2C2 Event
    ) _" k5 v* M5 C8 w
  59.                 DCD     I2C2_ER_IRQHandler         ; I2C2 Error
    6 s* T! E8 L4 C( I
  60.                 DCD     SPI1_IRQHandler            ; SPI1
    4 _* B4 B& S/ _- q" D; b9 H4 _
  61.                 DCD     SPI2_IRQHandler            ; SPI2
    * s: ^0 f3 r+ z7 y6 z( l2 a
  62.                 DCD     USART1_IRQHandler          ; USART1$ ]% N8 ~9 ]) Y" D' _# q+ ^4 U% Q
  63.                 DCD     USART2_IRQHandler          ; USART2
    0 b. a4 B" R8 [% k9 z! ?8 s
  64.                 DCD     USART3_IRQHandler          ; USART3
    ) k& H9 A4 K- Z! z# [
  65.                 DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
    & k% G* b7 h- F! k' E
  66.                 DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
    : I9 I5 N: V4 \- \% @! m0 m4 r
  67.                 DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend5 K- R5 t- L" C$ r- ~
  68.                 DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
    ( E$ H  H; [4 f/ H/ x
  69.                 DCD     TIM8_UP_IRQHandler         ; TIM8 Update- e, T4 G7 h8 _  {( u: G
  70.                 DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation  u$ I: K* {8 w: R+ C5 A
  71.                 DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
    + O  c; g8 }$ V9 P" E, F5 D
  72.                 DCD     ADC3_IRQHandler            ; ADC3# {  ^; k! i" K7 D
  73.                 DCD     FSMC_IRQHandler            ; FSMC& ]- S) q8 ~  e4 y7 R8 F5 c6 p2 J
  74.                 DCD     SDIO_IRQHandler            ; SDIO
    - ~! q; O4 s" ^; e+ r4 k
  75.                 DCD     TIM5_IRQHandler            ; TIM5
    % ]! ^% j, |; m
  76.                 DCD     SPI3_IRQHandler            ; SPI3
    2 C6 O5 e. Y$ E4 Z1 d
  77.                 DCD     UART4_IRQHandler           ; UART4
    3 C+ @$ t" a4 ]. j. f* q. d
  78.                 DCD     UART5_IRQHandler           ; UART5
    9 O  ?! l. e  z  ~5 c* }
  79.                 DCD     TIM6_IRQHandler            ; TIM69 [: Y" W) h) {
  80.                 DCD     TIM7_IRQHandler            ; TIM7" j3 \% R6 U1 t) @
  81.                 DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
    6 _' ?* p0 G3 R6 Z' x
  82.                 DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel22 m# y+ o& V6 i; I% L) X
  83.                 DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel30 I  {8 x* M6 Z3 v
  84.                 DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel55 D8 a" \5 Z( c, o/ L' X! F
  85. __Vectors_End
复制代码

8 j1 \8 z% p& |! n4 q( n
  这段代码就是定义异常向量表,在之前有一个“J-Flash打开hex文件”的图片跟这个表格是一一对应的。编译器根据我们定义的函数 Reset_Handler、NMI_Handler等,在连接程序阶段将这个向量表填入这些函数的地址。
  1. startup_stm32f10x_hd.s内容:
    / ~( d' N. p' K" f7 T

  2. % F! b3 E$ {& V8 A7 q) v; e" h  F
  3. NMI_Handler     PROC
    # d! C, x7 @0 y5 B& A" @
  4.                 EXPORT  NMI_Handler                [WEAK]
    , W) A0 ^0 ?; H2 R0 J" {
  5.                 B       .' K5 Q8 r; y; ?" a
  6.                 ENDP
    * k% \% z- {% @, @. l, c3 `/ s* ~

  7.   b' M' Y7 b% n5 @0 L, k
  8. 1 s& }& r1 t; V4 H5 p2 f# Q! S
  9. stm32f10x_it.c中内容:) U" ~8 d1 P0 ?) y
  10. void NMI_Handler(void)/ X0 ~& {# U; B; A  H4 K. F( k
  11. {# G; Q" y# l$ r/ ?# \& x1 ^1 L
  12. }
复制代码
7 Y4 F2 m4 G! c/ j" I+ Y
  在启动汇编文件中已经定义了函数NMI_Handler,但是使用了“弱”,它允许我们再重新定义一个NMI_Handler函数,程序在编译的时候会将汇编文件中的弱函数“覆盖掉”--两个函数的代码在连接后都存在,只是在中断向量表中的地址填入的是我们重新定义函数的地址。
六、使用微库与不使用微库的区别
092134086673127.png
8 m8 p# R4 E1 k' A2 x. d7 X4 p
  使用微库就意味着我们不想使用MDK提供的库函数,而想用自己定义的库函数,比如说printf函数。那么这一点是怎样实现的呢?我们以printf函数为例进行说明。
1、不使用微库而使用系统库
  在连接程序时,肯定会把系统中包含printf函数的库拿来调用参与连接,即代码段有系统库的参与。
  在启动过程中,不使用微库而使用系统库在初始化栈的时候,还需要初始化堆(猜测系统库需要用到堆),而使用微库则是不需要的。
  1.                  IF      :DEF:__MICROLIB
    $ X9 c2 a: ?% O2 L/ k: k
  2.                
    2 g$ j; a4 w9 u+ v* r2 m; J+ m
  3.                  EXPORT  __initial_sp) G+ P$ ^; M/ |9 n7 ^
  4.                  EXPORT  __heap_base' B$ B6 j: c2 K8 w: ?
  5.                  EXPORT  __heap_limit
    / C  J7 \& V4 P# {! q
  6.                
    7 w3 m" F6 \# p! Y( ^
  7.                  ELSE! C: O7 R7 p  ?  _: V7 @& A* C
  8.                 ' H3 z/ S+ c/ m% s
  9.                  IMPORT  __use_two_region_memory
    " S; y! i" {' V4 V* c9 ~; F
  10.                  EXPORT  __user_initial_stackheap3 d4 u; c3 t. u7 B- X
  11.                  
    9 P, L. U: w! |. d7 m
  12. __user_initial_stackheap- s; o: q' j0 J) F/ g- x3 X7 Z

  13. 3 n/ n  |. o  }  M# o8 [6 ^
  14.                  LDR     R0, =  Heap_Mem
    5 x! U  X) w: g* b1 e9 {; _) C0 _* b
  15.                  LDR     R1, =(Stack_Mem + Stack_Size)- A6 W" v( u- w# L/ g
  16.                  LDR     R2, = (Heap_Mem +  Heap_Size)2 @5 |: `- W( M% g" k# S+ ]
  17.                  LDR     R3, = Stack_Mem
    / ^4 l- _/ \1 F% i
  18.                  BX      LR" ]! z. U7 V! L; J  C7 A

  19. 5 N% f* O: O8 F8 J
  20.                  ALIGN
    ! J* ~, P& C/ p
  21. 5 B5 C3 ~  P; x
  22.                  ENDIF
复制代码
/ h' s, n+ I: c$ l  t# a$ V4 h0 x
  另外,在执行__main函数的过程中,不仅需要完成“使用微库”情况下的所有工作,额外的工作还需要进行库的初始化,才能使用系统库(这一部分我还没有深入探讨)。附上__main函数的内容:
  1.                   __main:
    ) r4 l# V* |' f6 P
  2. 0x08000130 F000F802  BL.W     __scatterload_rt2_thumb_only (0x08000138)
    3 i0 K* @) p. z: L: \/ k1 j- p
  3. 0x08000134 F000F83C  BL.W     __rt_entry_sh (0x080001B0)
      k) V' k5 U- ^. t5 M4 i
  4.                  __scatterload_rt2_thumb_only:
    ) r, g' r& O9 e7 v% }7 ~
  5. 0x08000138 A00A      ADR      r0,{pc}+4  ; @0x08000164, f( I2 K+ h  m8 Y
  6. 0x0800013A E8900C00  LDM      r0,{r10-r11}
    8 b8 \. @( s  x
  7. 0x0800013E 4482      ADD      r10,r10,r0
    . a4 C5 }0 Q3 g$ p1 O1 q2 W7 t* r  H; R
  8. 0x08000140 4483      ADD      r11,r11,r0
    # T9 f# f3 S" H
  9. 0x08000142 F1AA0701  SUB      r7,r10,#0x01/ E' |- e; f( ^" t+ X& m
  10.                  __scatterload_null:
    / P5 x- T) A2 T' b' h) W; G
  11. 0x08000146 45DA      CMP      r10,r11) a1 ~0 M% T9 V
  12. 0x08000148 D101      BNE      0x0800014E) [% [  ?  L9 V# I
  13. 0x0800014A F000F831  BL.W     __rt_entry_sh (0x080001B0)  V2 s% z* H6 I1 c" m' g; {
  14. 0x0800014E F2AF0E09  ADR.W    lr,{pc}-0x07  ; @0x08000147
    / x# H5 G& B' u. x
  15. 0x08000152 E8BA000F  LDM      r10!,{r0-r3}' H- h# `1 l# b% l4 t
  16. 0x08000156 F0130F01  TST      r3,#0x01
    : l* |, h/ w+ d7 e* f. F
  17. 0x0800015A BF18      IT       NE
    ( L3 |7 a* e4 r' f+ H9 O9 g
  18. 0x0800015C 1AFB      SUBNE    r3,r7,r3/ B  c3 I1 N) H  v, s' U$ W% G
  19. 0x0800015E F0430301  ORR      r3,r3,#0x01
    0 @8 s: m, F& K1 c
  20. 0x08000162 4718      BX       r3
      [6 N1 S6 o5 u1 O7 M
  21. 0x08000164 0298      LSLS     r0,r3,#10
    & O! b. i$ z/ X/ m
  22. 0x08000166 0000      MOVS     r0,r0+ g' @0 B0 P* Y1 b* |
  23. 0x08000168 02B8      LSLS     r0,r7,#10
    / r2 h0 b( J: \* r9 y4 S3 y
  24. 0x0800016A 0000      MOVS     r0,r0. e( \4 @# H) a  ^3 R9 T
  25.                  __scatterload_copy:/ H" A/ Q$ Z, [& z6 j% \
  26. 0x0800016C 3A10      SUBS     r2,r2,#0x10) q2 [5 }  D% o3 q
  27. 0x0800016E BF24      ITT      CS
    * C) L* i4 m$ H: G
  28. 0x08000170 C878      LDMCS    r0!,{r3-r6}/ Q" _, W: ?- q. f" y% M: x' U
  29. 0x08000172 C178      STMCS    r1!,{r3-r6}! D) G0 U2 B2 ~5 P! T3 ?$ U5 c% Z
  30. 0x08000174 D8FA      BHI      __scatterload_copy (0x0800016C)( }: g# p! x8 u. M+ W
  31. 0x08000176 0752      LSLS     r2,r2,#29
    2 V: \' i7 M& ^9 \& j* T5 O' e+ N5 l; Z3 p
  32. 0x08000178 BF24      ITT      CS% V4 y( G* |, w0 \" ?- X% X
  33. 0x0800017A C830      LDMCS    r0!,{r4-r5}
    . @$ o1 S% a, q0 r6 V' R; K  H& g
  34. 0x0800017C C130      STMCS    r1!,{r4-r5}& o( }' P  E: ?8 B: E8 r7 W
  35. 0x0800017E BF44      ITT      MI
    ' _# ^. j7 v7 ?/ M0 x# r9 R# |# `
  36. 0x08000180 6804      LDRMI    r4,[r0,#0x00]9 |+ h, e* Q9 U) C8 G
  37. 0x08000182 600C      STRMI    r4,[r1,#0x00]% i! S% n5 N) q, }& M& U) E
  38. 0x08000184 4770      BX       lr
    $ w: o2 `/ I8 S1 A% N& H
  39. 0x08000186 0000      MOVS     r0,r09 ?* _0 B- C! X. \9 T9 w# X# B
  40.                  __scatterload_zeroinit:
    # ~; G: c6 q) k' J5 T6 E, ]
  41. 0x08000188 2300      MOVS     r3,#0x00! @* }( U3 c; A2 |! X4 s
  42. 0x0800018A 2400      MOVS     r4,#0x007 t5 X0 A5 r5 u
  43. 0x0800018C 2500      MOVS     r5,#0x00
    . D3 A4 w0 a' ?# S3 a  P
  44. 0x0800018E 2600      MOVS     r6,#0x00' d' M! s5 E. Z# K- j
  45. 0x08000190 3A10      SUBS     r2,r2,#0x10
    : Y& _! {# u. R* A4 n2 f. J; j
  46. 0x08000192 BF28      IT       CS! g( U8 N& u* a- S# n% @
  47. 0x08000194 C178      STMCS    r1!,{r3-r6}5 U9 b( }+ R8 Z; I
  48. 0x08000196 D8FB      BHI      0x08000190( C. }# k5 H# S
  49. 0x08000198 0752      LSLS     r2,r2,#299 \4 ~8 ^, \, N1 ]
  50. 0x0800019A BF28      IT       CS4 b2 [& Z1 W* T+ w6 h( J, W: U
  51. 0x0800019C C130      STMCS    r1!,{r4-r5}7 o. l& N+ l+ o; k" z$ p
  52. 0x0800019E BF48      IT       MI
    , D' k' B! F2 w/ o! i; F* M0 m
  53. 0x080001A0 600B      STRMI    r3,[r1,#0x00]  ]# P$ r# v6 S5 I# E
  54. 0x080001A2 4770      BX       lr  `: E' ^5 W6 `3 D# H* j) d
  55.                  __rt_lib_init:
    2 _( r8 ]) A+ F4 v9 |4 q
  56. 0x080001A4 B51F      PUSH     {r0-r4,lr}1 V( F* k: G0 m! K" |5 t* S
  57. 0x080001A6 F3AF8000  NOP.W   
    ; v9 ?5 H$ J; L; M
  58.                  __rt_lib_init_user_alloc_1:7 @' V4 T" q, O" }5 @
  59. 0x080001AA BD1F      POP      {r0-r4,pc}
    6 q, [# o6 i: ~5 g8 ]# f
  60.                  __rt_lib_shutdown:4 v. ~+ W2 H  W- Z+ X# S% f
  61. 0x080001AC B510      PUSH     {r4,lr}
    8 L4 l# `: b# L0 Z
  62.                  __rt_lib_shutdown_user_alloc_1:
    # H7 t% j& Q/ F$ r+ F+ z+ x4 C* h9 [6 {: a
  63. 0x080001AE BD10      POP      {r4,pc}
    ) N; M+ y5 ^7 Y* P5 r0 X/ ?
  64.                  __rt_entry_sh:
    0 g  c! ?8 o0 b
  65. 0x080001B0 F000F82F  BL.W     __user_setup_stackheap (0x08000212)" e; ^! {, C0 _& q6 O+ d5 ?' A
  66. 0x080001B4 4611      MOV      r1,r2
    ! e1 t0 j/ E1 b# P) l+ a
  67.                  __rt_entry_postsh_1:' Q6 D& ~, M  ^- J6 p/ u2 ?1 H
  68. 0x080001B6 F7FFFFF5  BL.W     __rt_lib_init (0x080001A4)
    8 I! N% e7 v2 I* B" `' O% \6 U
  69.                  __rt_entry_postli_1:" V$ u1 I! T, z9 y4 c0 J& W; f: k
  70. 0x080001BA F000F919  BL.W     main (0x080003F0)
复制代码
) X  R: O7 [0 E! x+ I( j1 l4 b
2、使用微库而不使用系统库
  在程序连接时,不会把包含printf函数的库连接到终极目标文件中,而使用我们定义的库。
  启动时需要完成的工作就是之前论述的步骤1、2、3、4、5,相比使用系统库,启动过程步骤更少。
! C  Q" i3 c0 Q* r" z

5 L7 R$ U# d( b# J% a% t( S
收藏 评论0 发布时间:2022-1-13 21:00

举报

0个回答

所属标签

相似分享

官网相关资源

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