STM32啟動程式碼學習
目錄
文章目錄
摘要
本節主要記錄位元組學習STM32啟動程式碼的過程,通過對啟動程式碼的分析,可以更清晰的瞭解STM32的CPU是如何執行的;歡迎批評指標!!!
第一部分:彙編指令學習
1.偽指令
1).EQU
EQU偽指令:用來為一個數字常量、或一個和核心暫存器相關的數值或一個和程式計數器相關的數值定義的一個符號名稱。類似於C語言中的#define 。
格式: name EQU expr{ , type}
格式: 名稱 EQU 表示式(,型別)
例如:
Stack_Size EQU 0X00000400 //定義1k位元組的棧空間
Heap_Size EQU 0x00000200 //定義512位元組的堆空間
2).AREA
AREA偽指令:用於定義一個程式碼段或資料段。其中,段名若以數字開頭,則該段名需用“|”括起來,如:|1_test| 。
格式: AREA 段名 屬性1 ,屬性2 ,…… 屬性欄位表示該程式碼段(或資料段)的相關屬性,多個屬性用逗號分隔。常用的屬性如下: — CODE 屬性:用於定義程式碼段,預設為READONLY 。 — DATA 屬性:用於定義資料段,預設為READWRITE 。 — READONLY 屬性:指定本段為只讀,程式碼段預設為READONLY 。 — READWRITE 屬性:指定本段為可讀可寫,資料段的預設屬性為READWRITE 。 — ALIGN 屬性:使用方式為ALIGN表示式。在預設時,ELF(可執行連線檔案)的程式碼段和資料段是按字對齊的,表示式的取值範圍為0~31,相應的對齊方式為2表示式次方。 — COMMON 屬性:該屬性定義一個通用的段,不包含任何的使用者程式碼和資料。各原始檔中同名的COMMON段共享同一段儲存單元。
例如1:
AREA HEAP, NOINIT, READWRITE, ALIGN=3
其中:
HEAP: 定義一個堆段,名字 HEAP
NOINIT: 只分配空間不初始化零
READWRITE:可以讀寫
ALIGN=3 : 8位元組對齊
例如2:
AREA STACK, NOINIT, READWRITE, ALIGN=3
定義一個棧段,名字是STACK,不初始化為0,可以讀寫,8位元組對齊
例如3:
AREA RESET, DATA, READONLY
定義一個數據段,名字是RESET,只可讀;這裡面的DATA屬性表示RESET是一個數據段
例如4:
AREA |.text|, CODE, READONLY
定義一個程式碼段,名字是 |.text|,只可讀;這裡面的CODE屬性表示|.text|是一個程式碼段
3). SPACE
SPACE偽指令:用於分配一片連續的儲存單元並初始化為0,其中表達式為要分配的位元組數
格式:標號 SPACE 表示式
例如1:
Stack_Mem SPACE Stack_Size
分配連續Stack_Size 位元組的儲存單元,儲存單元的名字是Stack_Mem,這裡是在記憶體中連續分配1k位元組的棧空間
例如2:
Heap_Mem SPACE Heap_Size
分配連續Heap_Size 位元組的儲存單元,儲存單元的名字是Heap_Mem,這裡是在記憶體中連續分配512位元組的堆空間
4). DCD(或DCDU)
DCD偽指令:用於分配一片連續的字儲存單元,並用偽指令中指定的表示式初始化。其中,表示式可以為程式標號或數字表達式。 DCD 也可用 “ & ” 代替。用 DCD 分配的字儲存單元是字對齊的,而用 DCDU 分配的字儲存單元並不嚴格字對齊。
格式:標號 DCD (或 DCDU ) 表示式
**例如1:**下面是摘自STM32f4啟動程式碼的例子
其中:_Vectors是一個標號,該處的實體地址值即為 _Vetors 標號所表示的值,該地址中儲存__initial_sp所表示的地址值。使用DCD定義了一個記憶體陣列,陣列首地址放置的是棧指標地址,然後是復位中斷服務入口地址。這個表的作用的作用定義一個存放地址的陣列表。
例如2:
SwiFunction
DCD TASK_SW
DCD ENTER_CRITICAL
DCD EXIT_CRITICAL
DCD ISRBegin
DCD ChangeToSYSMode
DCD ChangeToUSRMode
5). ENTRY
ENTRY偽指令用於指定彙編程式的入口點。
6).PROC/ENDP
過程就是子程式。一個程式可以被其他程式所呼叫(CALL),過程的最後一投指令一般反匯指令(RET),需要注意PROC和ENDP必須成對出現。
格式:
<過程名> PROC [型別]
...
...
ENDP
例如1:復位中斷服務函式
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
例如2:硬體中斷服務函式
HardFault_Handler PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
7).END
END偽指令:用於指示組合語言程式段結束,因此一個源程式中僅有一個END,且一般放在程式最後。若END放在程式中間,則END後面的語句將不再被彙編。
8).LDR、STR
LDR指令:將儲存器地址所指地址處連續的4個位元組(1個字)的資料傳送到目的暫存器中
STR指令:將暫存器內容存入記憶體空間中
格式:
LDR{條件} 目的暫存器 <儲存器地址>
STR{條件} 源暫存器, <儲存器地址>
例如1:
LDR R0,[R1] ;將儲存器地址為R1的字資料讀入暫存器R0
LDR R0,[R1,R2] ;將儲存器地址為R1+R2的字資料讀入暫存器R0
LDR R0,[R1,#8] ;將儲存器地址為R1+8的字資料讀入暫存器R0
LDR R0,[R1],R2 ;將儲存器地址為R1的字資料讀入暫存器R0,然後R1=R1+8
LDR R0,[R1],#8 ;將儲存器地址為R1的字資料讀入暫存器R0,並將R1+8的值存入
LDR R0,=DATA ;將立即數DATA 載入到暫存器R0
STR R0,[R1],#8 ;將R0中的字資料寫入以R1為地址的儲存器中,並將新地址R1+8
STR R1, [R0] ;將R1暫存器的值,傳送到地址值為R0的(儲存器)記憶體中
例如2:
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
2. 彙編指令
1). IMPORT
表示這是一個外部變數的標號,不是在本程式定義的,表明要呼叫的函式為外部檔案定義
2).EXPORT
表示本程式裡面用到的變數提供給其他模組呼叫的。
3).PRESERVE8
PRESERVE8指令指定當前檔案需保持堆疊八位元組對齊方式。其通過設定PRES8編譯屬性通知聯結器。
格式:
PRESERVE8 {bool}
PRESERVE8 ;保持程式碼堆疊八位元組對齊。
PRESERVE8 {FALSE} ;不保持程式碼堆疊八位元組對齊。
4).Thumb
Thumb是ARM體系結構中一種16位的指令集。Thumb指令集可以看作是ARM指令壓縮形式的子集,它是為減小程式碼量而提出,具有16bit的程式碼密度。Thumb指令體系並不完整,只支援通用功能,必要時仍需要使用ARM指令,如進入異常時。其指令的格式與使用方式與ARM指令集類似,而且使用並不頻繁,Thumb指令集作一般瞭解。
5).跳轉指令B,BL,BX,BLX
B Label ;跳轉到Label處對應的地址
BL Label ;跳轉到Label對應的地址,並且把跳轉前的下條指令地址儲存到LR
BX reg ;跳轉到由暫存器reg給出的地址
BLX reg ;跳轉到由暫存器reg給出的地址,並根據REG的LSB切換處理器;狀態還要把轉移前的下條指令地址儲存到LR.
其中BX 和BLX 都會啟動中斷返回序列。即從SP中依次將值返回至xPSR, PC, LR, R12以及R3-R0—-其中從堆疊SP中返回PC值實現了程式跳轉。 對於B和BL 則是多用於函式跳轉,其中BL儲存了下條指令地址到LR.
6).IF——ELSE——ENDIF
格式:
IF 判斷式
執行1
ELSE
執行2
ENDIF
7).weak
一般來說,這個關鍵字使用在IMPORT和EXPORT這兩個宣告段,weak 宣告其他的同名標號優先於該標號被引用。
IMPORT StackTop [WEAK]
AREA |.text|, CODE, READONLY
;Vector list
ARM_Vectors
DCD StackTop
IMORT: 如果我們有一個名為ARM_Vectors的量表,向量表的第一個數值指向一個StackTop函式的地址。因為我們可能定義了該函式,也可能沒有,為了程式碼的簡便,我們可以使用WEAK關鍵字。
當我們定義了StackTop函式後,那麼ARM_Vectors裡第一個向量值就是StackTop函式的地址。如果沒有定義StackTop,那麼編譯器不會報錯,而這時候第一個向量值就直接賦予0。
EXPORT: EXPORT的函式帶有WEAK標誌的話,並且別的原始碼沒有定義同名函式,那麼連線時就是該函式;否則,就是另外的一個同名函式(類似類的繼承)
第二部分:STM32啟動流程學習
1.基礎知識儲備
每一款晶片的啟動檔案都值得去研究,因為它是程式跑的最初一段程式碼。通過了解啟動檔案,我們可以體會到處理器的架構、指令集、中斷向 量安排等內容,是非常值得研究的。
STM32作為一款高階Cortex-M3系列微控制器,有必要了解它的啟動檔案。打好基礎,為以後優化程式,寫出高質量的程式碼最準備。
相對於ARM上一代的主流ARM7/ARM9核心架構,新一代Cortex核心架構的啟動方式有了比較大的變化。ARM7/ARM9核心的控制器在復位後,CPU會從儲存空間的絕對地址0x000000取出第一條指令執行復位中斷服務程式的方式啟動,即固定了復位後的起始地址為0x000000(PC = 0x000000)同時中斷向量表的位置並不是固定的。而Cortex-M3核心則正好相反,有3種情況:
1、 通過boot引腳設定可以將中斷向量表定位於SRAM區,即起始地址為0x2000000,同時復位後PC指標位於0x2000000處;
2、 通過boot引腳設定可以將中斷向量表定位於FLASH區,即起始地址為0x8000000,同時復位後PC指標位於0x8000000處;
3、 通過boot引腳設定可以將中斷向量表定位於內建Bootloader區,本文不對這種情況做論述;
**
而Cortex-M3核心規定,起始地址必須存放堆頂指標,而第二個地址則必須存放復位中斷入口向量地址,這樣在Cortex-M3核心復位後,會自動從起始地址的下一個32位空間取出復位中斷入口向量,跳轉執行復位中斷服務程式。對比ARM7/ARM9核心,Cortex-M3核心則是固定了中斷向量表的位置而起始地址是可變化的。
STM整個啟動過程是指從上電開始,一直到執行到main函式之間的這段過程,步驟為:
①上電後硬體設定SP、PC
②設定系統時鐘
③軟體設定SP
④載入.data、.bss,並初始化棧區
⑤跳轉到C檔案的main函式
啟動過程涉及的檔案不僅包含startup_stm32f40x_hd.s,還涉及到了MDK自帶的連線庫檔案entry.o、entry2.o、entry5.o、entry7.o等(從生成的map檔案可以看出來)。
2.反彙編工具
STM32啟動程式碼startup_stm32f40_41xxx.s,這裡以天穹飛控程式碼的啟動進行反彙編分析。使用的反彙編工具是IDAIDA下載地址,對應的密碼是a2mm,怎麼使用的這裡就不做講述,可以自行查資料。介面下圖所示。
**步驟:
直接點選OK,然後Go,繼續File選擇open,選擇BlueSky.axf(這裡可以隨意開啟電腦上的一個.exe檔案,主要學會使用這個軟體)**開啟之後主要出現IDA View-A,Hex View-1 ,Structures ,Enums,Imports,Exports這些視窗
整體介面顯示:
(1)IDA View-A
這個就是啟動程式碼如何執行到main()函式的流程圖
也可以參考這個部落格:如何到main()函式
(2)Hex View-1
**(3)Structures **
(4)Enums
(5)Exports
第三部分:STM32啟動程式碼分析
Stack_Size EQU 0x00000400 ;EQU偽指令,作用是左邊的符號名代表右邊的表示式</span>
AREA STACK, NOINIT, READWRITE, ALIGN=3 ;定義棧段:名稱為STACK,未初始化,可讀寫,ELF 的棧段按2^3=8對齊
Stack_Mem SPACE Stack_Size ;分配一片連續的儲存區域並初始化為 0,棧空間:0x400個位元組
__initial_sp ;棧空間頂地址
; <h> Heap Configuration ;堆定義
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000200
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base ;堆空間起始地址
Heap_Mem SPACE Heap_Size ;堆空間:0x200個位元組
__heap_limit ;堆空間結束地址
PRESERVE8 ;PRESERVE8 指令指定當前檔案保持堆疊八位元組對齊
THUMB ;告訴彙編器下面是32位的Thumb指令,如果需要彙編器將插入位以保證對齊
; Vector Table Mapped to Address 0 at Reset ;中斷向量表定義
;實際上是在CODE區(假設STM32從FLASH啟動,則此中斷向量表起始地址即為0x8000000)
AREA RESET, DATA, READONLY ;定義一塊資料段<DATA>,只可讀<READONLY,預設READWRITE>,段名字是RESET
EXPORT __Vectors ;EXPORT:在程式中宣告一個全域性的標號__Vectors,該標號可在其他的檔案中引用
EXPORT __Vectors_End ;在程式中宣告一個全域性的標號__Vectors_End
EXPORT __Vectors_Size ;在程式中宣告一個全域性的標號__Vectors_Size
;DCD(DCDU)用於分配一片連續的字儲存單元並用指定的資料初始化。
__Vectors DCD __initial_sp ; Top of Stack ;該處實體地址值儲存__initial_sp所表示的地址值,即為 __Vetors 標號所表示的值
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts ;以下為外部中斷向量表
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
DCD ADC1_2_IRQHandler ; ADC1 & ADC2
DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD TIM1_BRK_IRQHandler ; TIM1 Break
DCD TIM1_UP_IRQHandler ; TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD TIM4_IRQHandler ; TIM4
DCD I2C1_EV_IRQHandler ; I2C1 Event
DCD I2C1_ER_IRQHandler ; I2C1 Error
DCD I2C2_EV_IRQHandler ; I2C2 Event
DCD I2C2_ER_IRQHandler ; I2C2 Error
DCD SPI1_IRQHandler ; SPI1
DCD SPI2_IRQHandler ; SPI2
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD USART3_IRQHandler ; USART3
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
DCD RTCAlarm_IRQHandler ; RTC Alarm through EXTI Line
DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
DCD TIM8_BRK_IRQHandler ; TIM8 Break
DCD TIM8_UP_IRQHandler ; TIM8 Update
DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation
DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
DCD ADC3_IRQHandler ; ADC3
DCD FSMC_IRQHandler ; FSMC
DCD SDIO_IRQHandler ; SDIO
DCD TIM5_IRQHandler ; TIM5
DCD SPI3_IRQHandler ; SPI3
DCD UART4_IRQHandler ; UART4
DCD UART5_IRQHandler ; UART5
DCD TIM6_IRQHandler ; TIM6
DCD TIM7_IRQHandler ; TIM7
DCD DMA2_Channel1_IRQHandler ; DMA2 Channel1
DCD DMA2_Channel2_IRQHandler ; DMA2 Channel2
DCD DMA2_Channel3_IRQHandler ; DMA2 Channel3
DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End ;Vectors結束
__Vectors_Size EQU __Vectors_End - __Vectors ;得到向量表的大小,304個位元組也就是0x130個位元組
AREA |.text|, CODE, READONLY ;定義一個程式碼段,可讀,段名字是.text
;|.text| 用於表示由 C 編譯程式產生的程式碼段,或用於以某種方式與 C 庫關聯的程式碼段
; Reset handler ;利用PROC、ENDP這一對偽指令標記程式開始、結束,把程式段分為若干個過程,使程式的結構加清晰
Reset_Handler PROC
EXPORT Reset_Handler [WEAK];WEAK宣告其他的同名標號優先於該標號被引用,就是說如果外面聲明瞭的話,呼叫外面的對應函式
IMPORT __main ;IMPORT:偽指令用於通知編譯器要使用的標號在其他的原始檔中定義
IMPORT SystemInit
LDR R0, =SystemInit ;系統初始化
BLX R0 ;帶連結的跳轉,切換指令集,跳到SystemInit
LDR R0, =__main ;__main為執行時庫提供的函式;完成堆疊,堆的初始化等工作,會呼叫下面定義的__user_initial_stackheap
BX R0 ;切換指令集,main函式不返回跳到__main,進入C的世界
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK];不可遮蔽中斷處理函式
B .
ENDP
HardFault_Handler\ ;\意為換行
PROC
EXPORT HardFault_Handler [WEAK];硬體錯誤處理函式
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
Default_Handler PROC
;輸出異常向量表標號,方便外部實現異常的具體功能,[WEAK]是弱定義的意思,如果外部定義了,優先執行外部定義,否則下面的函式定義
EXPORT WWDG_IRQHandler [WEAK]
EXPORT PVD_IRQHandler [WEAK]
EXPORT TAMPER_IRQHandler [WEAK]
EXPORT RTC_IRQHandler [WEAK]
EXPORT FLASH_IRQHandler [WEAK]
EXPORT RCC_IRQHandler [WEAK]
EXPORT EXTI0_IRQHandler [WEAK]
EXPORT EXTI1_IRQHandler [WEAK]
EXPORT EXTI2_IRQHandler [WEAK]
EXPORT EXTI3_IRQHandler [WEAK]
EXPORT EXTI4_IRQHandler [WEAK]
EXPORT DMA1_Channel1_IRQHandler [WEAK]
EXPORT DMA1_Channel2_IRQHandler [WEAK]
EXPORT DMA1_Channel3_IRQHandler [WEAK]
EXPORT DMA1_Channel4_IRQHandler [WEAK]
EXPORT DMA1_Channel5_IRQHandler [WEAK]
EXPORT DMA1_Channel6_IRQHandler [WEAK]
EXPORT DMA1_Channel7_IRQHandler [WEAK]
EXPORT ADC1_2_IRQHandler [WEAK]
EXPORT USB_HP_CAN1_TX_IRQHandler [WEAK]
EXPORT USB_LP_CAN1_RX0_IRQHandler [WEAK]
EXPORT CAN1_RX1_IRQHandler [WEAK]
EXPORT CAN1_SCE_IRQHandler [WEAK]
EXPORT EXTI9_5_IRQHandler [WEAK]
EXPORT TIM1_BRK_IRQHandler [WEAK]
EXPORT TIM1_UP_IRQHandler [WEAK]
EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
EXPORT TIM1_CC_IRQHandler [WEAK]
EXPORT TIM2_IRQHandler [WEAK]
EXPORT TIM3_IRQHandler [WEAK]
EXPORT TIM4_IRQHandler [WEAK]
EXPORT I2C1_EV_IRQHandler [WEAK]
EXPORT I2C1_ER_IRQHandler [WEAK]
EXPORT I2C2_EV_IRQHandler [WEAK]
EXPORT I2C2_ER_IRQHandler [WEAK]
EXPORT SPI1_IRQHandler [WEAK]
EXPORT SPI2_IRQHandler [WEAK]
EXPORT USART1_IRQHandler [WEAK]
EXPORT USART2_IRQHandler [WEAK]
EXPORT USART3_IRQHandler [WEAK]
EXPORT EXTI15_10_IRQHandler [WEAK]
EXPORT RTCAlarm_IRQHandler [WEAK]
EXPORT USBWakeUp_IRQHandler [WEAK]
EXPORT TIM8_BRK_IRQHandler [WEAK]
EXPORT TIM8_UP_IRQHandler [WEAK]
EXPORT TIM8_TRG_COM_IRQHandler [WEAK]
EXPORT TIM8_CC_IRQHandler [WEAK]
EXPORT ADC3_IRQHandler [WEAK]
EXPORT FSMC_IRQHandler [WEAK]
EXPORT SDIO_IRQHandler [WEAK]
EXPORT TIM5_IRQHandler [WEAK]
EXPORT SPI3_IRQHandler [WEAK]
EXPORT UART4_IRQHandler [WEAK]
EXPORT UART5_IRQHandler [WEAK]
EXPORT TIM6_IRQHandler [WEAK]
EXPORT TIM7_IRQHandler [WEAK]
EXPORT DMA2_Channel1_IRQHandler [WEAK]
EXPORT DMA2_Channel2_IRQHandler [WEAK]
EXPORT DMA2_Channel3_IRQHandler [WEAK]
EXPORT DMA2_Channel4_5_IRQHandler [WEAK]
;如下只是定義一些空函式
WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
DMA1_Channel1_IRQHandler
DMA1_Channel2_IRQHandler
DMA1_Channel3_IRQHandler
DMA1_Channel4_IRQHandler
DMA1_Channel5_IRQHandler
DMA1_Channel6_IRQHandler
DMA1_Channel7_IRQHandler
ADC1_2_IRQHandler
USB_HP_CAN1_TX_IRQHandler
USB_LP_CAN1_RX0_IRQHandler
CAN1_RX1_IRQHandler
CAN1_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
USART1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler
EXTI15_10_IRQHandler
RTCAlarm_IRQHandler
USBWakeUp_IRQHandler
TIM8_BRK_IRQHandler
TIM8_UP_IRQHandler
TIM8_TRG_COM_IRQHandler
TIM8_CC_IRQHandler
ADC3_IRQHandler
FSMC_IRQHandler
SDIO_IRQHandler
TIM5_IRQHandler
SPI3_IRQHandler
UART4_IRQHandler
UART5_IRQHandler
TIM6_IRQHandler
TIM7_IRQHandler
DMA2_Channel1_IRQHandler
DMA2_Channel2_IRQHandler
DMA2_Channel3_IRQHandler
DMA2_Channel4_5_IRQHandler
B .
ENDP
ALIGN ;預設是字對齊方式
;*******************************************************************************
; User Stack and Heap initialization 使用者堆疊初始化
;*******************************************************************************
IF :DEF:__MICROLIB ;判斷是否使用DEF:__MICROLIB(micro lib),如果勾選了micro lib
EXPORT __initial_sp ;將棧頂地址、堆起始地址、堆結束地址賦予全域性屬性,使外部程式可用
EXPORT __heap_base
EXPORT __heap_limit
ELSE ;如果沒有勾選micro lib
IMPORT __use_two_region_memory ;兩區堆疊空間,堆和棧有各自的空間地址
EXPORT __user_initial_stackheap
__user_initial_stackheap ;標號__user_initial_stackheap,表示使用者堆疊初始化程式入口
;此處是初始化兩區的堆疊空間,堆是從由低到高的增長,棧是由高向低生長的,兩個是互相獨立的資料段,並不能交叉使用。
LDR R0, = Heap_Mem ;儲存堆起始地址
LDR R1, =(Stack_Mem + Stack_Size) ;儲存棧結束地址
LDR R2, = (Heap_Mem + Heap_Size) ;儲存堆結束地址
LDR R3, = Stack_Mem ;儲存棧起始地址
BX LR
ALIGN
ENDIF
END ;END命令指示彙編器,已到達一個原始檔的末尾
;******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE*****