基於Fujitsu FM3 32-bit ARM Cortex-M3 內核的MCU 開發(第二篇)

第三章 軟件設計


關於程序,單片機首先運行的就是啓動文件。本節重點介紹 .s文件中彙編的基本用法,其實所有單片機的啓動文件很類似,基本上用法一樣。

;/************************************************************************/
;/*  Startup for ARM                                                     */
;/*  Version     V1.02                                                   */
;/*  Date        2011-01-12                                              */
;/*  Target-mcu  MB9B5xx  												*/
;/*	說明:本啓動文件分析適合大多數單片機的啓動文件,大致相同,僅供參考*/
;/************************************************************************/

;說明 一

	;僞指令:EQU 
		;語法格式:名稱    EQU     表達式{,類型} 
		;EQU僞指令用於爲程序中的常量、標號等定義一個等效的字符名稱,類似於 C 語言的#define。
		;其中 EQU可以用“*”代替。 
		;名稱爲 EQU 僞指令定義的字符名稱,當表達式爲 32 位的常量時,可以指定表達式的數據
		;類型,可以有一下三種類型: 
		;CODE16、CODE32 和 DATA 
		
	;僞指令:AREA 
		;語法格式:AREA     段名{,屬性 1}{,屬性 2}…… 
		;AREA命令指示彙編程序彙編一個新的代碼段或數據段。段是獨立的、指定的、不可見的代
		;碼或數據塊,它們由鏈接程序處理。 
		;段名:可以爲段選擇任何段名。但是,以一個數字開始的名稱必須包含在豎槓號內,否則會
		;產生一個缺失段名錯誤。例如,|1_DataArea|。 
		;有些名稱是習慣性的名稱。例如:|.text|用於表示由 C 編譯程序產生的代碼段,或用於以某
		;種方式與 C 庫關聯的代碼段。 
		;屬性字段表示該代碼段(或數據段)的相關屬性,多個屬性用逗號分隔。常用的屬性如下:  
		;——CODE屬性:用於定義代碼段,默認爲 READONLY。 
		;——D AT A屬性:用於定義數據段,默認爲 READWRITE。 
		;——READONLY屬性:指定本段爲只讀,代碼段默認爲 READONLY。 
		;——READWRITE屬性:指定本段爲可讀可寫,數據段的默認屬性爲 READWRITE。 
		;——ALIGN 屬性:使用方式爲 ALIGN 表達式。在默認時,ELF(可執行連接文件)的代碼
		;段和數據段是按字對齊的,表達式的取值範圍爲 0~31,相應的對齊方式爲2 表達式次方。 
		;——NOINIT 屬性:表示數據段是未初始化的或初始化爲零。其只包含零初始化的空間保留
		;命令 SPACE或 DCB、DCD、DCDU、DCQ、DCQU、DCW 或 DCWU。可以決定在鏈接時
		;AREA是未初始化的還是零初始化的。 
		;一個彙編語言程序至少要包含一個段,當程序太長時,也可以將程序分爲多個代碼段和數據段。 

; Stack Configuration
;  Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>


;													定義棧段	不初始化
;棧名:STACK
;大小:Stack_Size
;只分配空間不做初始化,或者初始化爲0:	NOINIT
;可讀可寫:READWRITE
;按8字節對齊:ALIGN=3
;棧頂地址:__initial_sp
;

Stack_Size      EQU     0x00000200								;定義棧空間大小爲0x00000200個字節。此語行亦等價於:#define Stack_Size 0x00000200

                AREA    STACK, NOINIT, READWRITE, ALIGN=3		;僞指令AREA
Stack_Mem       SPACE   Stack_Size
__initial_sp


; Heap Configuration
;  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>


;													定義堆段	不初始化
;堆名:HEAP
;大小:Heap_Size
;只分配空間不做初始化,或者初始化爲0:	NOINIT
;可讀可寫:READWRITE
;按8字節對齊:ALIGN=3
;堆起始地址:__heap_base
;堆終止地址:__heap_limit
;
Heap_Size       EQU     0x00000000

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit


                PRESERVE8				;指示編譯器8字節對齊(keil編譯器時需加上)
                THUMB					;指示編譯器爲THUMB指令集



;說明:二
		;	僞指令:EXPORT 
			;	語法格式:EXPORT     標號{[WEAK]} 
			;	EXPORT 僞指令用於在程序中聲明一個全局的標號,該標號可在其他的文件中引用。
			;	EXPORT 可用 GLOBAL 代替。標號在程序中區分大小寫,[WEAK]選項聲明其他的同名標
			;	號優先於該標號被引用。 

		;	僞指令:DCD 
			;	語法格式:DCD(或 DCDU)    表達式 
			;	DCD(或 DCDU)僞指令用於分配一片連續的字存儲單元並用僞指令中指定的表達式初始
			;	化。其中,表達式可以爲程序標號或數字表達式。DCD 也可用“&”代替。 
			;	用 DCD 分配的字存儲單元是字對齊的,而用 DCDU分配的字存儲單元並不嚴格字對齊

; Vector Table Mapped to Address 0 at Reset

;														定義復位段 (中斷向量表),並初始化

;段名:RESET
;大小:__Vectors_Size
;數據段:DATA
;只讀:READONLY
;按字節對齊:默認ALIGN
;向量表起始地址:__Vectors
;向量表終止地址:__Vectors_End


                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     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

                DCD     CSV_Handler               ; 0: Clock Super Visor
                DCD     SWDT_Handler              ; 1: Software Watchdog Timer
                DCD     LVD_Handler               ; 2: Low Voltage Detector
                DCD     MFT_WG_IRQHandler         ; 3: Wave Form Generator / DTIF
                DCD     INT0_7_Handler            ; 4: External Interrupt Request ch.0 to ch.7
                DCD     INT8_15_Handler           ; 5: External Interrupt Request ch.8 to ch.15
                DCD     DT_Handler                ; 6: Dual Timer / Quad Decoder
                DCD     MFS0RX_IRQHandler         ; 7: MultiFunction Serial ch.0
                DCD     MFS0TX_IRQHandler         ; 8: MultiFunction Serial ch.0
                DCD     MFS1RX_IRQHandler         ; 9: MultiFunction Serial ch.1
                DCD     MFS1TX_IRQHandler         ; 10: MultiFunction Serial ch.1
                DCD     MFS2RX_IRQHandler         ; 11: MultiFunction Serial ch.2
                DCD     MFS2TX_IRQHandler         ; 12: MultiFunction Serial ch.2
                DCD     MFS3RX_IRQHandler         ; 13: MultiFunction Serial ch.3
                DCD     MFS3TX_IRQHandler         ; 14: MultiFunction Serial ch.3
                DCD     MFS4RX_IRQHandler         ; 15: MultiFunction Serial ch.4
                DCD     MFS4TX_IRQHandler         ; 16: MultiFunction Serial ch.4
                DCD     MFS5RX_IRQHandler         ; 17: MultiFunction Serial ch.5
                DCD     MFS5TX_IRQHandler         ; 18: MultiFunction Serial ch.5
                DCD     MFS6RX_IRQHandler         ; 19: MultiFunction Serial ch.6
                DCD     MFS6TX_IRQHandler         ; 20: MultiFunction Serial ch.6
                DCD     MFS7RX_IRQHandler         ; 21: MultiFunction Serial ch.7
                DCD     MFS7TX_IRQHandler         ; 22: MultiFunction Serial ch.7
                DCD     PPG_Handler               ; 23: PPG
                DCD     TIM_IRQHandler            ; 24: OSC / PLL / Watch Counter
                DCD     ADC0_IRQHandler           ; 25: ADC0
                DCD     ADC1_IRQHandler           ; 26: ADC1
                DCD     ADC2_IRQHandler           ; 27: ADC2
                DCD     MFT_FRT_IRQHandler        ; 28: Free-run Timer
                DCD     MFT_IPC_IRQHandler        ; 29: Input Capture
                DCD     MFT_OPC_IRQHandler        ; 30: Output Compare
                DCD     BT_IRQHandler             ; 31: Base Timer ch.0 to ch.7
                DCD     CAN0_IRQHandler           ; 32: CAN ch.0
                DCD     CAN1_IRQHandler           ; 33: CAN ch.1
                DCD     USBF_Handler              ; 34: USB Function
                DCD     USB_Handler               ; 35: USB Function / USB HOST
                DCD     DummyHandler              ; 36: Reserved
                DCD     DummyHandler              ; 37: Reserved
                DCD     DMAC0_Handler             ; 38: DMAC ch.0
                DCD     DMAC1_Handler             ; 39: DMAC ch.1
                DCD     DMAC2_Handler             ; 40: DMAC ch.2
                DCD     DMAC3_Handler             ; 41: DMAC ch.3
                DCD     DMAC4_Handler             ; 42: DMAC ch.4
                DCD     DMAC5_Handler             ; 43: DMAC ch.5
                DCD     DMAC6_Handler             ; 44: DMAC ch.6
                DCD     DMAC7_Handler             ; 45: DMAC ch.7
                DCD     DummyHandler              ; 46: Reserved
                DCD     DummyHandler              ; 47: Reserved
__Vectors_End

__Vectors_Size 	EQU 	__Vectors_End - __Vectors

;說明 三
		;過程定義僞指令:PROC、ENDP 
			;語法格式:<過程名>  PROC  [類型] 
			;          …… 
			;          RET 
			;       <過程名>  ENDP   
			;過程就是子程序。一個過程可以被其它程序所調用(用 CALL指令),過程的最後一條指令一般是返回指令(RET)。
		;僞指令:IMPORT 
			;語法格式:IMPORT    標號  {[WEAK]} 
			;IMPORT 僞指令用於通知編譯器要使用的標號在其他源文件中定義,但是在當前源文件中引
			;用,而且無論當前源文件是否引用該標號,該標號均會被加入到當前源文件的標號表中。 
			;標號在程序中區分大小寫,[WEAK]選項表示當所有的源文件都沒有定義這樣的一個標號時,
			;編譯器也不給出錯誤信息,在多數情況下將該標號置爲 0,若該標號爲 B 或 BL 指令引用,
			;則將 B或 BL指令置爲 NOP 操作。 
		;僞指令:LDR 
			;語法格式:LDR{執行條件,如 EQ、NE等}    register,=expr/label_expr  
			;大範圍的地址讀取僞指令 LDR 用於加載 32 位的立即數或一個地址值到指定寄存器,在彙編
			;編譯源程序時,LDR 僞指令被編譯器替換成一條合適的指令。若加載的常數未超出 MOV
			;或MVN的範圍,則使用MOV或MVN指令代替 LDR僞指令,否則彙編器將常量放入字池,
			;並使用一條程序相對偏移的 LDR 指令從文字池讀出常量。 
		;Thumb跳轉指令:B、BL、BX 
			;語法格式:  B{執行條件,如 EQ、NE等}      labe l 
			;帶鏈接    BL{執行條件,如 EQ、NE等}      labe l 
			;帶狀態切換  BX{執行條件,如 EQ、NE等}      labe l 
			


;																	定義代碼段(異常處理函數) ,並初始化 
;段名:.text 
;代碼段:CODE 
;只讀:READONLY   
;按字節對齊:默認 ALIGN 
;代碼段起始地址:Reset_Handler 

                AREA    |.text|, CODE, READONLY


; Reset Handler

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main
                LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
                BX      R0
                ENDP
					
;說明 四				
		;內置變量:    {PC}  或“.”    當前指令地址 
		;彙編語句格式規範: 
		;ARM 彙編中,所有標號必須在一行的頂格書寫,其後面不要添加“:”,而所有指令均不能頂格書寫。 
		;ARM 彙編器對標識符大小寫敏感,書寫標號及指令時字母大小寫要一致,在 ARM 彙編程
		;序中,一個 ARM 指令、僞指令、寄存器名可以全部爲大寫字母,也可以全部爲小寫字母,但不要大小寫混合使用。 
		;註釋使用“;”,註釋內容由“;”開始到此行結束,註釋可以在一行的頂格書寫。 
		;源程序中允許有空行,適當地插入空行可以提高源程序代碼的可讀性。如果單行太長,可以使用字符“\”將其分行,“\”後不能有任何字符,包括空格和製表符等。
		;對於變量的設置,常量的定義,其標識符必須在一行的頂格書寫。 

; 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

                EXPORT  CSV_Handler	              [WEAK]
                EXPORT  SWDT_Handler              [WEAK]
                EXPORT  LVD_Handler               [WEAK]
                EXPORT  MFT_WG_IRQHandler         [WEAK]
                EXPORT  INT0_7_Handler            [WEAK]
                EXPORT  INT8_15_Handler           [WEAK]
                EXPORT  DT_Handler                [WEAK]
                EXPORT  MFS0RX_IRQHandler         [WEAK]
                EXPORT  MFS0TX_IRQHandler         [WEAK]
                EXPORT  MFS1RX_IRQHandler         [WEAK]
                EXPORT  MFS1TX_IRQHandler         [WEAK]
                EXPORT  MFS2RX_IRQHandler         [WEAK]
                EXPORT  MFS2TX_IRQHandler         [WEAK]
                EXPORT  MFS3RX_IRQHandler         [WEAK]
                EXPORT  MFS3TX_IRQHandler         [WEAK]
                EXPORT  MFS4RX_IRQHandler         [WEAK]
                EXPORT  MFS4TX_IRQHandler         [WEAK]
                EXPORT  MFS5RX_IRQHandler         [WEAK]
                EXPORT  MFS5TX_IRQHandler         [WEAK]
                EXPORT  MFS6RX_IRQHandler         [WEAK]
                EXPORT  MFS6TX_IRQHandler         [WEAK]
                EXPORT  MFS7RX_IRQHandler         [WEAK]
                EXPORT  MFS7TX_IRQHandler         [WEAK]
                EXPORT  PPG_Handler               [WEAK]
                EXPORT  TIM_IRQHandler            [WEAK]
                EXPORT  ADC0_IRQHandler           [WEAK]
                EXPORT  ADC1_IRQHandler           [WEAK]
                EXPORT  ADC2_IRQHandler           [WEAK]
                EXPORT  MFT_FRT_IRQHandler        [WEAK]
                EXPORT  MFT_IPC_IRQHandler        [WEAK]
                EXPORT  MFT_OPC_IRQHandler        [WEAK]
                EXPORT  BT_IRQHandler             [WEAK]
                EXPORT  CAN0_IRQHandler           [WEAK]
                EXPORT  CAN1_IRQHandler           [WEAK]
                EXPORT  USBF_Handler              [WEAK]
                EXPORT  USB_Handler               [WEAK]
                EXPORT  DMAC0_Handler             [WEAK]
                EXPORT  DMAC1_Handler             [WEAK]
                EXPORT  DMAC2_Handler             [WEAK]
                EXPORT  DMAC3_Handler             [WEAK]
                EXPORT  DMAC4_Handler             [WEAK]
                EXPORT  DMAC5_Handler             [WEAK]
                EXPORT  DMAC6_Handler             [WEAK]
                EXPORT  DMAC7_Handler             [WEAK]
                EXPORT  DummyHandler              [WEAK]

                     ;下面的全部異常處理函數標號都對應同一個地址,這個地址也是 Default_Handler 的地址
CSV_Handler
SWDT_Handler
LVD_Handler
MFT_WG_IRQHandler
INT0_7_Handler
INT8_15_Handler
DT_Handler
MFS0RX_IRQHandler
MFS0TX_IRQHandler
MFS1RX_IRQHandler
MFS1TX_IRQHandler
MFS2RX_IRQHandler
MFS2TX_IRQHandler
MFS3RX_IRQHandler
MFS3TX_IRQHandler
MFS4RX_IRQHandler
MFS4TX_IRQHandler
MFS5RX_IRQHandler
MFS5TX_IRQHandler
MFS6RX_IRQHandler
MFS6TX_IRQHandler
MFS7RX_IRQHandler
MFS7TX_IRQHandler
PPG_Handler
TIM_IRQHandler
ADC0_IRQHandler
ADC1_IRQHandler
ADC2_IRQHandler
MFT_FRT_IRQHandler
MFT_IPC_IRQHandler
MFT_OPC_IRQHandler
BT_IRQHandler
CAN0_IRQHandler
CAN1_IRQHandler
USBF_Handler
USB_Handler
DMAC0_Handler
DMAC1_Handler
DMAC2_Handler
DMAC3_Handler
DMAC4_Handler
DMAC5_Handler
DMAC6_Handler
DMAC7_Handler
DummyHandler

                B       .

                ENDP





;由於前面只是定義了堆棧段並沒有初始化,這裏對堆棧段進行初始化。就像定義了:int a;  初始化 a = 1;也可以像代碼段一樣定義的同時就初始化:int b = 2; 
;下面代碼中有個__MICROLIB,對應後面 MDK 截圖的 Use MicroLIB,如果選了勾選了 Use MicroLIB,IF 就爲真,否則爲假。 
                ALIGN


; 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

                ALIGN

                ENDIF


                END


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章