打開(kāi)Freedom KL25的例程包,任意找一個(gè)code example,,以lower_power_dma_uart_demo為例,分析一下啟動(dòng)匯編文件的代碼,。
代碼主要分三部分:堆棧等的配置,、向量表、初始啟動(dòng)跳轉(zhuǎn),。
1. 堆棧配置
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x00000800
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp EQU 0x20002ff8
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
注:AREA關(guān)鍵字的作用是告訴匯編器,,該section是獨(dú)立的一段,應(yīng)該重新開(kāi)始解析,。AREA后面的一系列表示該段的屬性,。
SPACE關(guān)鍵字告訴其后的一段memory存儲(chǔ)空間,不被初始化為某些特定值,,與FILL相對(duì),。
EQU可以理解為等于。
2. 向量表
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD DMA0_IRQHandler ; DMA channel 0 transfer complete interrupt
DCD DMA1_IRQHandler ; DMA channel 1 transfer complete interrupt
DCD DMA2_IRQHandler ; DMA channel 2 transfer complete interrupt
DCD DMA3_IRQHandler ; DMA channel 3 transfer complete interrupt
DCD Reserved20_IRQHandler ; Reserved interrupt 20
DCD FTFA_IRQHandler ; FTFA interrupt
DCD LVD_LVW_IRQHandler ; Low Voltage Detect, Low Voltage Warning
DCD LLW_IRQHandler ; Low Leakage Wakeup
DCD I2C0_IRQHandler ; I2C0 interrupt
DCD I2C1_IRQHandler ; I2C0 interrupt 25
DCD SPI0_IRQHandler ; SPI0 interrupt
DCD SPI1_IRQHandler ; SPI1 interrupt
DCD UART0_IRQHandler ; UART0 status/error interrupt
DCD UART1_IRQHandler ; UART1 status/error interrupt
DCD UART2_IRQHandler ; UART2 status/error interrupt
DCD ADC0_IRQHandler ; ADC0 interrupt
DCD CMP0_IRQHandler ; CMP0 interrupt
DCD TPM0_IRQHandler ; TPM0 fault, overflow and channels interrupt
DCD TPM1_IRQHandler ; TPM1 fault, overflow and channels interrupt
DCD TPM2_IRQHandler ; TPM2 fault, overflow and channels interrupt
DCD RTC_IRQHandler ; RTC interrupt
DCD RTC_Seconds_IRQHandler ; RTC seconds interrupt
DCD PIT_IRQHandler ; PIT timer interrupt
DCD Reserved39_IRQHandler ; Reserved interrupt 39
DCD USB0_IRQHandler ; USB0 interrupt
DCD DAC0_IRQHandler ; DAC interrupt
DCD TSI0_IRQHandler ; TSI0 interrupt
DCD MCG_IRQHandler ; MCG interrupt
DCD LPTimer_IRQHandler ; LPTimer interrupt
DCD Reserved45_IRQHandler ; Reserved interrupt 45
DCD PORTA_IRQHandler ; Port A interrupt
DCD PORTD_IRQHandler ; Port D interrupt
向量表很長(zhǎng),,此處只截取一部分,,這些向量表中的向量的默認(rèn)名字就在這里指定了。開(kāi)發(fā)人員只需將中斷向量函數(shù)的具體功能實(shí)現(xiàn)即可,。當(dāng)然,,有一些默認(rèn)的dummy 異常handler已經(jīng)有了,都是死循環(huán):
; 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
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
B .
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B .
ENDP
3. 啟動(dòng)代碼
啟動(dòng)代碼就放在Reset復(fù)位向量里面,,因?yàn)镽eset向量是MCU啟動(dòng)時(shí)候第一個(gè)進(jìn)入到PC寄存器并開(kāi)始執(zhí)行的地方,。
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
啟動(dòng)代碼首先將SystemInit的地址load到R0寄存器中,然后使用BLX跳轉(zhuǎn)指令跳到SystemInit函數(shù)開(kāi)始處去執(zhí)行,,執(zhí)行完畢以后再執(zhí)行main函數(shù)的執(zhí)行,。
接下去需要找SystemInit的代碼查看。