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

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

0 y8 n" T2 a4 M4 G7 d$ K% F
092018031206060.png
$ V4 \7 q+ B6 W7 F
MSP初始值        编译器生成,主堆栈的初始值
异常向量表        不多说
外部中断向量表      不多说
代码段          存放代码
初始化数据段       .data
未初始化数据段      .bss
加载数据段和初始化栈的参数
  加载数据段和初始化栈的参数分别有4个,这里只讲解加载数据段的参数,至于初始化栈的参数类似。
0x0800 033c  Flash上的数据段(初始化数据段和未初始化数据段)起始地址
0x2000 0000  加载到SRAM上的目的地址
0x0000 000c  数据段的总大小
0x0800 02f4  调用函数_scatterload_copy
  需要说明的是初始化栈的函数--0x0800 0304与加载数据段的函数不一样,为_scatterload_zeroinit,它的目的就是将栈空间清零。
1 ]+ t$ i. w: W& M
092032461983346.png

0 l. r8 h# E" k, F2 C
三、数据在SRAM上的结构
  程序运行时(执行到main函数)时的SRAM数据结构
- }4 m4 E0 r% f- c
092025271358977.png
- d6 Y. |+ @8 g- K( D- q- Y
四、详细过程分析
  有了以上的基础,现在详细分析启动过程。
1、上电后硬件设置SP、PC
  刚上电复位后,硬件会自动根据向量表偏移地址找到向量表,向量表偏移地址的定义如下:
8 X' u( M. t' a+ ~) O4 I7 o" X
092045343233846.png
+ ~4 ~; _. l% M0 l2 @+ A
  调试现象如下:

% r3 o6 m9 D! W( ~6 z
092046570579821.png

8 u3 P$ ~* ^3 }9 i
  看看我们的向量表内容(通过J-Flash打开hex文件)
8 v5 @: c6 X8 H8 ~& [9 D7 f4 d
092048562138825.png

7 r6 N* a* Z2 ~  b. p9 o: l5 s' S
  硬件这时自动从0x0800 0000位置处读取数据赋给栈指针SP,然后自动从0x0800 0004位置处读取数据赋给PC,完成复位,结果为:
SP = 0x0200 0810
PC = 0x0800 0145
2、设置系统时钟

8 g4 ^% o3 f3 l7 W3 {7 V* U$ F
092052446511680.png
; {- n: b1 `2 r: e4 p' l2 X/ z$ q
  上一步中令PC=0x0800 0145的地址没有对齐,硬件自动对齐到0x0800 0144,执行SystemInit函数初始化系统时钟。
3、软件设置SP
  1. LDR   R0,=__main  $ D6 ?% J; P1 J  p1 e/ u
  2. BX   R0
复制代码

( b. U" X" a( G7 V( U
  执行上两条之类,跳转到__main程序段运行,注意不是main函数,___main的地址是0x0800 0130。
7 }- b1 {' }$ Z
092100522921657.png
( Q6 g( ~7 m, M2 d- N
  可以看到指令LDR.W sp,[pc,#12],结果SP=0x2000 0810。
4、加载.data、.bss,并初始化栈区
  1. BL.W     __scatterload_rt2
复制代码
  进入 __scatterload_rt2代码段。
  1. __scatterload_rt2:: j" r* T% L, Y" d
  2. 0x08000168 4C06      LDR      r4,[pc,#24]  ; @0x08000184) S8 G  f' Q* S- [9 J. H) ?# j
  3. 0x0800016A 4D07      LDR      r5,[pc,#28]  ; @0x080001883 u, N( b6 z% D1 C
  4. 0x0800016C E006      B        0x0800017C
    & V3 L; a1 [$ ?% H& ]9 v" k  _, U1 W
  5. 0x0800016E 68E0      LDR      r0,[r4,#0x0C]. W6 q; _- m6 k$ Y( k
  6. 0x08000170 F0400301  ORR      r3,r0,#0x01! D$ y$ P' S* d% j+ U! X0 b+ x
  7. 0x08000174 E8940007  LDM      r4,{r0-r2}
    : \/ r; A9 T" [4 H
  8. 0x08000178 4798      BLX      r3$ F& p: M! l, q$ E: q) q
  9. 0x0800017A 3410      ADDS     r4,r4,#0x10
    4 ~4 I) n& Q2 ]3 G- `' r
  10. 0x0800017C 42AC      CMP      r4,r52 g7 m7 F5 E6 s. v8 a$ q# G) ~3 C
  11. 0x0800017E D3F6      BCC      0x0800016E
    6 ]" T4 Y- x* P/ N
  12. 0x08000180 F7FFFFDA  BL.W     _main_init (0x08000138)
复制代码
' B  p+ a9 H+ i; `
  这段代码是个循环(BCC 0x0800016e),实际运行时候循环了两次。第一次运行的时候,读取“加载数据段的函数(_scatterload_copy)”的地址并跳转到该函数处运行(注意加载已初始化数据段和未初始化数据段用的是同一个函数);第二次运行的时候,读取“初始化栈的函数(_scatterload_zeroinit)”的地址并跳转到该函数处运行。 相应的代码如下:
0x0800016E 68E0      LDR      r0,[r4,#0x0C]0x08000170 F0400301  ORR      r3,r0,#0x010x08000174  $ D, G( I* u/ s, y- @( \
0x08000178 4798      BLX      r3# x6 r% M: T+ A6 X
  
: w6 P1 x2 q) {$ N) h! n( S4 G  当然执行这两个函数的时候,还需要传入参数。至于参数,我们在“加载数据段和初始化栈的参数”环节已经阐述过了。当这两个函数都执行完后,结果就是“数据在SRAM上的结构”所展示的图。最后,也把事实加载和初始化的两个函数代码奉上如下:
0 d! Z5 G  X5 q8 H2 Q
  1. 0x0800016E 68E0      LDR      r0,[r4,#0x0C]
    , q. Y2 N1 Y& p
  2. 0x08000170 F0400301  ORR      r3,r0,#0x014 j( [1 Z$ T5 Z$ D4 K9 O
  3. 0x08000174  ! X5 e6 I- o' t% K5 a2 R4 [
  4. 0x08000178 4798      BLX      r3
复制代码
当然执行这两个函数的时候,还需要传入参数。至于参数,我们在“加载数据段和初始化栈的参数”环节已经阐述过了。当这两个函数都执行完后,结果就是“数据在SRAM上的结构”所展示的图。最后,也把事实加载和初始化的两个函数代码奉上如下:
  1.                  __scatterload_copy:
    ( q7 y: I1 i) G" t
  2. 0x080002F4 E002      B        0x080002FC
    / ^6 L/ l- u9 R( n
  3. 0x080002F6 C808      LDM      r0!,{r3}2 B: T6 d+ s7 E8 [; C
  4. 0x080002F8 1F12      SUBS     r2,r2,#4/ e% y' v! Z# f$ N
  5. 0x080002FA C108      STM      r1!,{r3}
    . p% I# J, r2 }( I% U
  6. 0x080002FC 2A00      CMP      r2,#0x00  l5 Y9 {" b) G  C- W& t1 X
  7. 0x080002FE D1FA      BNE      0x080002F6, N  H: }' h1 M
  8. 0x08000300 4770      BX       lr
    : u+ ^' h! e' Z, L
  9.                  __scatterload_null:. k% ?# i9 r1 d) u
  10. 0x08000302 4770      BX       lr
    ; T; y8 |. M1 f$ o( Q
  11.                  __scatterload_zeroinit:
    6 M6 G, f5 c% E$ g' j. |
  12. 0x08000304 2000      MOVS     r0,#0x00
    2 |3 N+ s' I" I' r5 z+ L  H3 C
  13. 0x08000306 E001      B        0x0800030C1 s5 R/ v' f5 F# y+ k9 z
  14. 0x08000308 C101      STM      r1!,{r0}
    # y  _) }; _5 T1 l
  15. 0x0800030A 1F12      SUBS     r2,r2,#4. K6 F/ I  f+ n/ h; q! v& t+ ?
  16. 0x0800030C 2A00      CMP      r2,#0x00. ?. V& ]- K5 W$ H) u2 f' Y
  17. 0x0800030E D1FB      BNE      0x08000308
    2 o# e1 }1 V3 C7 ?$ E) u8 s8 r
  18. 0x08000310 4770      BX       lr
复制代码

+ J; r% k6 _5 P/ p
5、跳转到C文件的main函数
  1.                  _main_init:# b* U& c" W2 M1 L3 X" p0 ]
  2. 0x08000138 4800      LDR      r0,[pc,#0]  ; @0x0800013C0 b7 }& X; S8 a8 g- Z4 k. _+ i
  3. 0x0800013A 4700      BX       r0
复制代码
+ E/ e! e3 z8 |  [
9 w& i9 p8 y# R% U$ X
五、异常向量与中断向量表
  1. ; Vector Table Mapped to Address 0 at Reset
    7 G$ u1 J; b& o, w0 A# v% O
  2.                 AREA    RESET, DATA, READONLY3 V( o, W- `  l% T  u; l% i$ c* ^
  3.                 EXPORT  __Vectors1 O  T. w- y7 _, G9 P  z" h7 O
  4.                 EXPORT  __Vectors_End
    & T1 k- s& g6 Q( y+ _; `
  5.                 EXPORT  __Vectors_Size4 V+ ?# v! b0 b4 E8 l
  6. 5 W( \7 o0 i* F& m
  7. __Vectors       DCD     __initial_sp               ; Top of Stack
    ) Q( r& J2 i+ D! ^+ ]+ I6 D
  8.                 DCD     Reset_Handler              ; Reset Handler
    , k5 k4 l- b# J4 ]
  9.                 DCD     NMI_Handler                ; NMI Handler
    9 J+ b% c& k. d6 v
  10.                 DCD     HardFault_Handler          ; Hard Fault Handler
    ) \7 p! S% `" l: e, b- E5 t  A4 E( N
  11.                 DCD     MemManage_Handler          ; MPU Fault Handler
    0 R. S/ ]+ T: {0 o
  12.                 DCD     BusFault_Handler           ; Bus Fault Handler
    7 k! b) `" V0 a- {% m" u
  13.                 DCD     UsageFault_Handler         ; Usage Fault Handler
    7 ]3 H8 [+ _. B* t4 o0 ~; n0 [
  14.                 DCD     0                          ; Reserved
    2 o7 |2 J' H' P
  15.                 DCD     0                          ; Reserved7 q8 g/ ]6 X1 T; R1 s) |/ m
  16.                 DCD     0                          ; Reserved( `- ?* P# q2 f) G. @# ~
  17.                 DCD     0                          ; Reserved# b8 c: B: `, Y3 G0 b# U3 a
  18.                 DCD     SVC_Handler                ; SVCall Handler
    * P$ Q+ ?& q; B3 A, j
  19.                 DCD     DebugMon_Handler           ; Debug Monitor Handler
    3 o' h2 b$ u! \" w0 K" N1 G
  20.                 DCD     0                          ; Reserved
    * |* F$ d: O2 Q7 W
  21.                 DCD     PendSV_Handler             ; PendSV Handler
    5 o- |7 L8 {$ I; K9 i, t6 ]
  22.                 DCD     SysTick_Handler            ; SysTick Handler; q  k/ L2 p6 M+ K" F$ L$ n' [9 K" y

  23. ' k; D4 L* U- _" Q4 {
  24.                 ; External Interrupts
    % f( i2 n9 ~3 `: M* E( d/ H
  25.                 DCD     WWDG_IRQHandler            ; Window Watchdog6 U) J* k* K9 Y3 w) [8 v
  26.                 DCD     PVD_IRQHandler             ; PVD through EXTI Line detect, }. ~: s& o! I% |+ t5 s
  27.                 DCD     TAMPER_IRQHandler          ; Tamper' e5 h( p# P* o3 p% c+ h) k
  28.                 DCD     RTC_IRQHandler             ; RTC. H# y' ?3 i# ]4 i$ v) I8 E* P
  29.                 DCD     FLASH_IRQHandler           ; Flash9 X0 `- y' B0 H$ c% l# s4 R
  30.                 DCD     RCC_IRQHandler             ; RCC
    & i7 G$ }5 H, C" t$ P% h& K. u1 q9 E
  31.                 DCD     EXTI0_IRQHandler           ; EXTI Line 01 {) p" e7 G" D* C: U% c& i0 v
  32.                 DCD     EXTI1_IRQHandler           ; EXTI Line 1
    & F6 e; q5 f: n2 b1 p& n* f6 p, L
  33.                 DCD     EXTI2_IRQHandler           ; EXTI Line 2
    & e7 z& y+ i- P! l% [4 G1 [. R
  34.                 DCD     EXTI3_IRQHandler           ; EXTI Line 3
    * g8 i- G0 b1 J# k2 @8 I
  35.                 DCD     EXTI4_IRQHandler           ; EXTI Line 49 c( V+ g9 s3 F3 h/ H& r
  36.                 DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 14 x% ~9 j- z, c; c+ R/ E, m6 ^8 W8 ^
  37.                 DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2& U- |* q4 X5 e6 Y3 ~, A# W% i; N
  38.                 DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3. P: M, d4 y0 c: h! N, m
  39.                 DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4) u$ I+ r' S6 t! }
  40.                 DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5* V# J% M6 W& s' R; G. g2 Y
  41.                 DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6/ s4 q4 K- _# D- A+ L" g
  42.                 DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 72 V( f4 k2 D4 b; Y7 c- F1 F) _
  43.                 DCD     ADC1_2_IRQHandler          ; ADC1 & ADC24 L! P. [1 a8 _9 g" E5 |
  44.                 DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX3 I3 ?# o, Q/ Q+ \$ `7 |; ~/ h
  45.                 DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0, c9 i$ V: t; x) G- h, J. m
  46.                 DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1  G$ c, C/ h6 R
  47.                 DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE" w, R0 @' e0 L& J1 f
  48.                 DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5& g7 X& E& z* d, X* y
  49.                 DCD     TIM1_BRK_IRQHandler        ; TIM1 Break% R* O, W( Q! o. G0 F7 b0 q
  50.                 DCD     TIM1_UP_IRQHandler         ; TIM1 Update
    6 v- j" m$ X! h6 l+ l
  51.                 DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation0 Q- k" e1 P( M2 ]& i
  52.                 DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare8 c; O" T! t, R  R
  53.                 DCD     TIM2_IRQHandler            ; TIM2
    9 Z" a5 h; o+ J0 J/ l! ?8 x
  54.                 DCD     TIM3_IRQHandler            ; TIM3
    ; ]7 j; P, Q8 ^, _
  55.                 DCD     TIM4_IRQHandler            ; TIM4; A& l( G: T9 _- @2 Y
  56.                 DCD     I2C1_EV_IRQHandler         ; I2C1 Event
    ) d+ R8 f: O9 o* ~; t1 x
  57.                 DCD     I2C1_ER_IRQHandler         ; I2C1 Error
    7 A; _" L: d# i+ k9 _: m
  58.                 DCD     I2C2_EV_IRQHandler         ; I2C2 Event8 U6 [$ `7 q; D; z
  59.                 DCD     I2C2_ER_IRQHandler         ; I2C2 Error! |$ h! f, a$ @9 v, L% c
  60.                 DCD     SPI1_IRQHandler            ; SPI1& c/ g9 q3 m( H' |
  61.                 DCD     SPI2_IRQHandler            ; SPI2. n0 w; G7 {+ B7 I; b/ [/ K5 S
  62.                 DCD     USART1_IRQHandler          ; USART1
      q# t% t  S( b4 \% I- {
  63.                 DCD     USART2_IRQHandler          ; USART22 ?6 J) k& `- K! O8 {0 ^% i& l% E
  64.                 DCD     USART3_IRQHandler          ; USART36 r* n3 D) j" v& h3 l
  65.                 DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
    # O) f, x# P( c  x* L* H
  66.                 DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
    6 n6 w5 D+ F7 E, @* M
  67.                 DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend: l  W- A% Q( R$ f' |
  68.                 DCD     TIM8_BRK_IRQHandler        ; TIM8 Break7 M' c  q4 d) N5 B8 b
  69.                 DCD     TIM8_UP_IRQHandler         ; TIM8 Update
    % K1 h) n6 |2 f+ G4 P
  70.                 DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation4 Y: V0 C  A' b& q
  71.                 DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare* Q3 L) ?5 u* P/ p1 m5 ~/ p% G
  72.                 DCD     ADC3_IRQHandler            ; ADC3. a6 F: s& V( @& a6 z% o3 D: X5 Z
  73.                 DCD     FSMC_IRQHandler            ; FSMC
    - |  I. B! i  @, t. ?& t. v) n
  74.                 DCD     SDIO_IRQHandler            ; SDIO
    " V$ [) J% [6 U$ i
  75.                 DCD     TIM5_IRQHandler            ; TIM5, Q2 z% {/ L2 q& i
  76.                 DCD     SPI3_IRQHandler            ; SPI33 L2 b, ?, V1 o; `: n/ e% i
  77.                 DCD     UART4_IRQHandler           ; UART4
      ]" s8 `3 q, G& k9 [2 V
  78.                 DCD     UART5_IRQHandler           ; UART58 R' ?& \+ X' o; E0 t' N3 k: v, f" _
  79.                 DCD     TIM6_IRQHandler            ; TIM6
    4 X7 ?0 k: u! [8 T1 @
  80.                 DCD     TIM7_IRQHandler            ; TIM7
    8 \4 ^/ f3 T, O/ x% C0 j
  81.                 DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1% O9 k; C  l, N
  82.                 DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
    ( t0 w: N/ _/ C
  83.                 DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3, h7 ^6 b- g0 G4 y; \; n: O
  84.                 DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5+ }/ g8 q$ q* S0 D* d9 c1 a+ b, \5 l
  85. __Vectors_End
复制代码
; O% H- V: T) Q* f; `( t, \9 o7 h
  这段代码就是定义异常向量表,在之前有一个“J-Flash打开hex文件”的图片跟这个表格是一一对应的。编译器根据我们定义的函数 Reset_Handler、NMI_Handler等,在连接程序阶段将这个向量表填入这些函数的地址。
  1. startup_stm32f10x_hd.s内容:
    & P2 \  `! t; ^( y, G: E
  2. ) r0 a9 }, L+ M( @9 v
  3. NMI_Handler     PROC. ?8 ~* {6 p  G" ~
  4.                 EXPORT  NMI_Handler                [WEAK]
    : g9 T- g( t& y# c2 p4 r4 u% v; P
  5.                 B       .5 K* ~7 \, ~5 A5 V4 v% `
  6.                 ENDP) g" ?% L* ~4 [8 T% A
  7. ' |8 i- M, T- q% G

  8. : y# n9 S: f3 K
  9. stm32f10x_it.c中内容:  i& B8 }) _5 u: _
  10. void NMI_Handler(void)0 _; ?" w% S4 [6 G5 r% J3 m  R
  11. {
    + m0 a  Y/ K, q/ v- s
  12. }
复制代码

, y# ?2 ]) g  }
  在启动汇编文件中已经定义了函数NMI_Handler,但是使用了“弱”,它允许我们再重新定义一个NMI_Handler函数,程序在编译的时候会将汇编文件中的弱函数“覆盖掉”--两个函数的代码在连接后都存在,只是在中断向量表中的地址填入的是我们重新定义函数的地址。
六、使用微库与不使用微库的区别
092134086673127.png

4 B1 G4 f- b/ r4 ^
  使用微库就意味着我们不想使用MDK提供的库函数,而想用自己定义的库函数,比如说printf函数。那么这一点是怎样实现的呢?我们以printf函数为例进行说明。
1、不使用微库而使用系统库
  在连接程序时,肯定会把系统中包含printf函数的库拿来调用参与连接,即代码段有系统库的参与。
  在启动过程中,不使用微库而使用系统库在初始化栈的时候,还需要初始化堆(猜测系统库需要用到堆),而使用微库则是不需要的。
  1.                  IF      :DEF:__MICROLIB8 e$ c: y5 w0 s  s
  2.                
    ; e6 R6 J" }2 m+ [
  3.                  EXPORT  __initial_sp
    + V$ E# p; p2 h% G* F4 g
  4.                  EXPORT  __heap_base
    6 `) L5 M& @1 M" \6 I
  5.                  EXPORT  __heap_limit
    ( o4 ~% X3 X5 g' k& d6 F8 ?
  6.                
    2 V0 d  M$ Z9 R4 A# m6 R+ S6 e
  7.                  ELSE$ s  X8 h8 c( T
  8.                 ) q8 k2 Y/ `0 l
  9.                  IMPORT  __use_two_region_memory
    ; q2 E& N! V6 o7 Q  |9 I
  10.                  EXPORT  __user_initial_stackheap
    6 t2 Y2 o! Q' R1 u/ ]
  11.                  - z% J9 c+ o$ j! Y
  12. __user_initial_stackheap
    0 j' z: J: {4 M/ _

  13. 3 k4 u( m) ~+ ~! Z/ [
  14.                  LDR     R0, =  Heap_Mem3 n9 L; h' o; N; w( B' K6 `0 Q) `
  15.                  LDR     R1, =(Stack_Mem + Stack_Size)
    % ^$ x: E7 O& @1 R
  16.                  LDR     R2, = (Heap_Mem +  Heap_Size)
    ) ]" B+ x* r) u& P) ?3 O7 E' B
  17.                  LDR     R3, = Stack_Mem
    . E) C( G. q& P
  18.                  BX      LR
    " q1 p  N4 j& a2 M6 \/ X$ y
  19. ; O5 X. ~+ m1 v" N! p
  20.                  ALIGN
    1 [. i. d! H: u$ ~* S& i

  21. : k' {" C% X9 }
  22.                  ENDIF
复制代码

2 e  e" _$ Q3 x0 K
  另外,在执行__main函数的过程中,不仅需要完成“使用微库”情况下的所有工作,额外的工作还需要进行库的初始化,才能使用系统库(这一部分我还没有深入探讨)。附上__main函数的内容:
  1.                   __main:; E2 z% l* _: K! v
  2. 0x08000130 F000F802  BL.W     __scatterload_rt2_thumb_only (0x08000138)  Y% y/ t- o7 {- w" \
  3. 0x08000134 F000F83C  BL.W     __rt_entry_sh (0x080001B0)
    1 a0 H* P+ M& T* u
  4.                  __scatterload_rt2_thumb_only:5 |" X  L% F7 E# Q
  5. 0x08000138 A00A      ADR      r0,{pc}+4  ; @0x08000164
    ! V4 ^9 l1 L, K6 s% E& U
  6. 0x0800013A E8900C00  LDM      r0,{r10-r11}" M# T$ K& Q; y+ _2 N, _6 ^/ ~/ b
  7. 0x0800013E 4482      ADD      r10,r10,r04 l  |: s) }9 q$ h# b% a3 i
  8. 0x08000140 4483      ADD      r11,r11,r05 S$ s. f) P5 H( j
  9. 0x08000142 F1AA0701  SUB      r7,r10,#0x017 a4 D. E' T' i
  10.                  __scatterload_null:
    , E+ n; }' ~+ }0 ^0 r& g/ i
  11. 0x08000146 45DA      CMP      r10,r11
    " d4 ^: x, W: p* P
  12. 0x08000148 D101      BNE      0x0800014E
    : F1 F. N8 n3 q, N
  13. 0x0800014A F000F831  BL.W     __rt_entry_sh (0x080001B0)8 g" l0 p1 g8 _, J5 M
  14. 0x0800014E F2AF0E09  ADR.W    lr,{pc}-0x07  ; @0x080001470 v7 c' e# W7 P7 r
  15. 0x08000152 E8BA000F  LDM      r10!,{r0-r3}
    6 Y7 i/ Y) b1 B1 V+ t! Y. N
  16. 0x08000156 F0130F01  TST      r3,#0x01
      D) K" R' n) w. f6 E, |# a
  17. 0x0800015A BF18      IT       NE
    0 j0 |9 r6 ~- U1 q3 L$ W
  18. 0x0800015C 1AFB      SUBNE    r3,r7,r3% K: p& M, C3 G: C# E
  19. 0x0800015E F0430301  ORR      r3,r3,#0x01* \( v6 y7 H! `, j" L
  20. 0x08000162 4718      BX       r38 m! t: p% L( ]% C1 u5 I
  21. 0x08000164 0298      LSLS     r0,r3,#10
    % T7 d1 V$ K& \
  22. 0x08000166 0000      MOVS     r0,r0
    6 ~9 i1 s& x0 A' F% w
  23. 0x08000168 02B8      LSLS     r0,r7,#10  M1 l2 O1 @: h
  24. 0x0800016A 0000      MOVS     r0,r07 ~. f5 L' m  G- [8 b
  25.                  __scatterload_copy:
    + Z# Q/ {/ a3 ?
  26. 0x0800016C 3A10      SUBS     r2,r2,#0x10
    2 p- ?; c2 @+ F' {5 h
  27. 0x0800016E BF24      ITT      CS
    0 H5 ?4 y* T, d) g0 a/ L
  28. 0x08000170 C878      LDMCS    r0!,{r3-r6}; ?7 h- O5 h9 H$ Z5 f( [% h: o% ~
  29. 0x08000172 C178      STMCS    r1!,{r3-r6}
    % j, }! B) v% h6 k1 r
  30. 0x08000174 D8FA      BHI      __scatterload_copy (0x0800016C)3 `% I5 m7 n6 a3 a
  31. 0x08000176 0752      LSLS     r2,r2,#29
    8 z/ q* a) q& f
  32. 0x08000178 BF24      ITT      CS
    2 W8 E: o8 x" k5 ]# J8 b
  33. 0x0800017A C830      LDMCS    r0!,{r4-r5}
    - P! H- Z$ ^8 |& H# v9 X2 R6 _
  34. 0x0800017C C130      STMCS    r1!,{r4-r5}# p1 v9 @* \) y  v8 y. t1 M3 L/ j
  35. 0x0800017E BF44      ITT      MI
    ( X# r+ G( L5 \% x- S, y" K
  36. 0x08000180 6804      LDRMI    r4,[r0,#0x00]% c5 Z5 Z- n$ a' j/ U  j
  37. 0x08000182 600C      STRMI    r4,[r1,#0x00]
      q& F0 \% b* L( K# |8 l7 D
  38. 0x08000184 4770      BX       lr
    , W7 \- M( X* z0 I1 t$ ?2 s
  39. 0x08000186 0000      MOVS     r0,r0' Z1 S9 ^% B% I3 r8 L+ \- Y6 h
  40.                  __scatterload_zeroinit:# k' |: ~: Y0 Y+ S- c- u3 r, N9 T9 y7 h
  41. 0x08000188 2300      MOVS     r3,#0x00
    - w/ `& c( u- f+ N
  42. 0x0800018A 2400      MOVS     r4,#0x00
    % ~$ i9 V% i0 |. i" d6 b
  43. 0x0800018C 2500      MOVS     r5,#0x00* |: G2 y$ T! H/ f
  44. 0x0800018E 2600      MOVS     r6,#0x002 o6 Q) ]9 v  f4 `6 i
  45. 0x08000190 3A10      SUBS     r2,r2,#0x10
    1 p! {! O$ e  d, C# `4 U7 R, f
  46. 0x08000192 BF28      IT       CS+ S8 }2 O/ P: f5 c: S
  47. 0x08000194 C178      STMCS    r1!,{r3-r6}
    4 P, o/ \, d7 i5 S1 Q' ?3 X
  48. 0x08000196 D8FB      BHI      0x080001907 S7 Y3 f" H9 ?! A9 z0 y
  49. 0x08000198 0752      LSLS     r2,r2,#29; [+ n6 y6 Y. b; O) T& V
  50. 0x0800019A BF28      IT       CS
    , E0 T( C5 D' B1 C2 R7 A# O' t
  51. 0x0800019C C130      STMCS    r1!,{r4-r5}8 ^1 I9 Y8 M+ V9 ~% Y- `5 y2 |
  52. 0x0800019E BF48      IT       MI
    4 ?, O+ Z6 H+ C; H9 X
  53. 0x080001A0 600B      STRMI    r3,[r1,#0x00]
    3 N) [% G; r6 O( r' I" k
  54. 0x080001A2 4770      BX       lr. r  Z9 U4 `! S! G
  55.                  __rt_lib_init:' h3 Q5 I  J' d2 \( ]
  56. 0x080001A4 B51F      PUSH     {r0-r4,lr}6 D+ Y9 v) T  H
  57. 0x080001A6 F3AF8000  NOP.W   
    ; K4 |, ^. |( H1 U0 y+ s
  58.                  __rt_lib_init_user_alloc_1:% n' i# x1 c7 ^  f
  59. 0x080001AA BD1F      POP      {r0-r4,pc}4 S" ?) C; v* {2 A+ U1 k) Y
  60.                  __rt_lib_shutdown:
    + A* a* r7 O( r4 D4 p, ~# P
  61. 0x080001AC B510      PUSH     {r4,lr}
    ! I% X4 h  ~1 n
  62.                  __rt_lib_shutdown_user_alloc_1:! G0 ~" y8 ?! ?5 y1 J1 r
  63. 0x080001AE BD10      POP      {r4,pc}
    $ Q1 I9 Q: ^6 H9 U# b9 j
  64.                  __rt_entry_sh:
    8 C: h/ _2 t9 d4 u0 `- d7 D% O
  65. 0x080001B0 F000F82F  BL.W     __user_setup_stackheap (0x08000212)
    7 U1 n/ l, C; L* R
  66. 0x080001B4 4611      MOV      r1,r2# ^( [: y- b+ t, `5 K
  67.                  __rt_entry_postsh_1:
    . J6 }( {& Z& @0 t. f
  68. 0x080001B6 F7FFFFF5  BL.W     __rt_lib_init (0x080001A4)
    4 r/ E, K9 Q" P
  69.                  __rt_entry_postli_1:# a9 K" ?2 U, X0 D0 P6 S1 x5 M
  70. 0x080001BA F000F919  BL.W     main (0x080003F0)
复制代码

9 [. `* h/ r' l
2、使用微库而不使用系统库
  在程序连接时,不会把包含printf函数的库连接到终极目标文件中,而使用我们定义的库。
  启动时需要完成的工作就是之前论述的步骤1、2、3、4、5,相比使用系统库,启动过程步骤更少。

# K7 y: G- _! z1 [
& }# n+ t1 P8 g0 x5 Z1 j! X" V" M
收藏 评论0 发布时间:2022-1-13 21:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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