專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

Cortex-M3 .s文啟動(dòng)文件分析

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年08月16日   【字體:

1. 基本概念(CMSIS): Cortex Micro-controller Software Interface Standard,微控制器軟件接口標(biāo)準(zhǔn)。

2. CMSIS標(biāo)準(zhǔn)的文件結(jié)構(gòu):
a) core_cm.c (stdint.h)
b) system_.c (core_cm, system_)
c) startup_.s
其中core_cm.c以及core_cm中為內(nèi)核設(shè)訪問(wèn)層,其中定義了定義了內(nèi)核中得外設(shè)幾丁質(zhì)以及一些內(nèi)核的訪問(wèn)及控制函數(shù)。
startup_.s文件是系統(tǒng)的啟動(dòng)文件,其包括堆和棧的初始化配置、中斷向量表的配置以及將程序引導(dǎo)到main()函數(shù)等功能。
system_和system_.c文件則是由ARM公司提供模版,各芯片制造商根據(jù)自己芯片的特點(diǎn)來(lái)編寫(xiě)的。
3. 注解startup_.s文件
此文件主要完成三項(xiàng)工作:堆棧以及堆的初始化、定位中斷向量表、調(diào)用Reset Handler
a) 堆棧以及堆的初始化
; Stack Configuration
;   Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
Stack_Size         EQU      0x00000200
                      AREA     STACK, NOINIT, READWRITE, ALIGN=3  
//指明8字節(jié)對(duì)齊(ALIGN=3)

Stack_Mem SPACE    Stack_Size
__initial_sp       //此標(biāo)號(hào)有一層隱含的意思那就是在M3中堆棧是滿遞減堆棧,
//因?yàn)樗付硕褩V羔樜挥诙褩5母叩刂罚ㄔ?/Stack_Mem之后)
 
 
; Heap Configuration
;    Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;
 
Heap_Size        EQU      0x00000000
                AREA     HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE Heap_Size
__heap_limit
以上堆和棧的具體地址可以在工程編譯后產(chǎn)生的*.map文件中看到。
b) 定位中斷向量表
PRESERVE8   //PRESERVE8指定了以下的代碼位8字節(jié)對(duì)齊
THUMB //THUMB指定了接下來(lái)的代碼為T(mén)HUMB指令集
; Vector Table Mapped to Address 0 at Reset
                AREA    RESET, DATA, READONLY   //此語(yǔ)句聲明RESET數(shù)據(jù)段
                EXPORT  __Vectors
//導(dǎo)出向量表標(biāo)號(hào),EXPORT作用類似于C語(yǔ)言中的extern
__Vectors       
                DCD     __initial_sp                       ; Top of Stack
                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     WDT_IRQHandler             ; 16: Watchdog Timer
                DCD     TIMER0_IRQHandler          ; 17: Timer0
                DCD     TIMER1_IRQHandler          ; 18: Timer1
                DCD     TIMER2_IRQHandler          ; 19: Timer2
                DCD     TIMER3_IRQHandler          ; 20: Timer3
                DCD     UART0_IRQHandler           ; 21: UART0
 (……省略)
c) 調(diào)用Reset Handler
; 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ǎo)程序進(jìn)入__main(此__main是C_Library中的函數(shù),非main())
 
d) 堆棧以及堆的初始化行為
; User Initial Stack & Heap
                IF       :DEF:__MICROLIB
                EXPORT  __initial_sp
                EXPORT  __heap_base
                EXPORT  __heap_limit
                ELSE
                IMPORT  __use_two_region_memory
                EXPORT  __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
e) ARM m3 C是怎么調(diào)用startup.s文件的?
startup.s大部分內(nèi)容不是被C調(diào)用的,而是在C程序之前運(yùn)行的。m3上電之后會(huì)先從0地址處讀取MSP,然后從0x4地址處讀取復(fù)位向量,接著跳轉(zhuǎn)到復(fù)位異常服務(wù)程序Reset_Handler(這些是m3內(nèi)核自動(dòng)做的,不需要編程)。如果你用MDK的話,在工程設(shè)置Debug下的run to main()上的勾去掉,然后進(jìn)入調(diào)試,你會(huì)發(fā)現(xiàn)你運(yùn)行的第一句就是Reset_Handler的第一句。
Reset_Handler就是在startup.s中定義的,它一般會(huì)對(duì)系統(tǒng)初始化,然后進(jìn)入main函數(shù)。
向量表也是在startup.s中定義的,至于為什么程序編譯之后向量表一定在0地址處,是因?yàn)橄蛄勘淼那懊鏁?huì)有類似AREA    RESET, CODE, READONLY的聲明。在MDK生成的分散加載文件中,RESET被設(shè)置在flash的0地址處,這樣就規(guī)定了向量表的地址。
關(guān)閉窗口