![]() |
發布時間: 2015-1-10 20:28
正文摘要:啟動代碼的一般作用 1、堆和棧的初始化; 2、向量表定義; 3、地址重映射及中斷向量表的轉移; 4、初始化有特殊要求的斷口; 5、處理器模式; 6、進入C應用程序。 ARM復位后程序從0x00地址開始 ... |
一:啟動代碼簡介 啟動代碼是芯片復位后進入C語言的main()函數前執行的一段代碼。主要是為運行C語言程序提供基本的運行環境,初始化存儲系統等。為了能夠進行系統初始化,采用一個匯編文件作為啟動代碼是常見的做法。 二:啟動代碼的作用 1.初始化異常向量表 2.初始化存儲器系統 3.初始化堆棧 程序使用編譯器分配的空間作為堆棧,而不是按通常的做法爸堆棧分配到RAM的頂端。這樣做的好處一是不必知道RAM頂端的位置,移植更加方便,二是編譯器給出的占用RAM空間的大小就是實際占用的大小,便于控制RAM的分配。 4.初始化有特殊要求的端口、設備 5.初始化應用程序的運行環境 6.改變處理器的運行模式 7.調用主應用程序 三:startup_LPC11xx.s啟動代碼分析 [plain] view plaincopy ;Stack Configuration Stack_Size EQU 0x00000200 ; 定義statck_size標號為ox200的空間作為棧空間 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size ; 為棧分配內存空間,并初始化為0 __initial_sp ;Heap Configuration Heap_Size EQU 0x00000200 ; 堆大小定義為0x00000000字節 AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base Heap_Mem SPACE Heap_Size ; 為堆分配內存空間,并初始化為0 __heap_limit ; 代表堆地址的標號 PRESERVE8 ; 當前堆棧保持8字節對齊 THUMB ; 指示編譯器為thumb指令 ; Vector Table Mapped to Address 0 at Reset,向量表映射到復位地址0,??? ; 為所有Handler分配內存單元 AREA RESET, DATA, READONLY ; 聲明數據段RESET,放到數據段中為于0地址 ; 該數據段內存單元只讀 EXPORT __Vectors ; 聲明一個全局的標號,該標號可在其他的文件中引用 __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偽指令用于分配一片連續的字存儲單元并用指定的表達式初始化 ; External Interrupts DCD WAKEUP_IRQHandler ; 15 wakeup sources for all the DCD WAKEUP_IRQHandler ; I/O pins starting from PIO0 (0:11) DCD WAKEUP_IRQHandler ; all 40 are routed to the same ISR DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler DCD WAKEUP_IRQHandler ; PIO1 (0:11) DCD CAN_IRQHandler ; CAN DCD SSP1_IRQHandler ; SSP1 DCD I2C_IRQHandler ; I2C DCD TIMER16_0_IRQHandler ; 16-bit Timer0 DCD TIMER16_1_IRQHandler ; 16-bit Timer1 DCD TIMER32_0_IRQHandler ; 32-bit Timer0 DCD TIMER32_1_IRQHandler ; 32-bit Timer1 DCD SSP0_IRQHandler ; SSP0 DCD UART_IRQHandler ; UART DCD USB_IRQHandler ; USB IRQ DCD USB_FIQHandler ; USB FIQ DCD ADC_IRQHandler ; A/D Converter DCD WDT_IRQHandler ; Watchdog timer DCD BOD_IRQHandler ; Brown Out Detect DCD FMC_IRQHandler ; IP2111 Flash Memory Controller DCD PIOINT3_IRQHandler ; PIO INT3 DCD PIOINT2_IRQHandler ; PIO INT2 DCD PIOINT1_IRQHandler ; PIO INT1 DCD PIOINT0_IRQHandler ; PIO INT0 IF :DEF:EN_CRP ; 宏判斷是否定義NO_CRP AREA |.ARM.__at_0x02FC|, CODE, READONLY ; 自定義只讀代碼段 CRP_Key DCD 0x87654321 ; 加密等級 ENDIF AREA |.text|, CODE, READONLY ; 聲明代碼段|.text|,只讀 ; Reset Handler ; 復位入口子函數 Reset_Handler PROC ; PROC:子程序開始偽指令 EXPORT Reset_Handler [WEAK] ; __main()是編譯系統提供的一個函數 IMPORT __main ; 負責完成庫函數的初始化和初始化應用程序執行環境 LDR R0, =__main ; 使用=標示目前為偽指令,=等于@取地址,把__main的地址給R0 BX R0 ; 跳轉到編譯系統的__main(),最后自動跳轉到用戶程序的main() 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 EXPORT WAKEUP_IRQHandler [WEAK] EXPORT CAN_IRQHandler [WEAK] EXPORT SSP1_IRQHandler [WEAK] EXPORT I2C_IRQHandler [WEAK] EXPORT TIMER16_0_IRQHandler [WEAK] EXPORT TIMER16_1_IRQHandler [WEAK] EXPORT TIMER32_0_IRQHandler [WEAK] EXPORT TIMER32_1_IRQHandler [WEAK] EXPORT SSP0_IRQHandler [WEAK] EXPORT UART_IRQHandler [WEAK] EXPORT USB_IRQHandler [WEAK] EXPORT USB_FIQHandler [WEAK] EXPORT ADC_IRQHandler [WEAK] EXPORT WDT_IRQHandler [WEAK] EXPORT BOD_IRQHandler [WEAK] EXPORT FMC_IRQHandler [WEAK] EXPORT PIOINT3_IRQHandler [WEAK] EXPORT PIOINT2_IRQHandler [WEAK] EXPORT PIOINT1_IRQHandler [WEAK] EXPORT PIOINT0_IRQHandler [WEAK] WAKEUP_IRQHandler CAN_IRQHandler SSP1_IRQHandler I2C_IRQHandler TIMER16_0_IRQHandler TIMER16_1_IRQHandler TIMER32_0_IRQHandler TIMER32_1_IRQHandler SSP0_IRQHandler UART_IRQHandler USB_IRQHandler USB_FIQHandler ADC_IRQHandler WDT_IRQHandler BOD_IRQHandler FMC_IRQHandler PIOINT3_IRQHandler PIOINT2_IRQHandler PIOINT1_IRQHandler PIOINT0_IRQHandler B . ENDP ALIGN ; 添加補丁字節滿足對齊 ; User Initial Stack & Heap,用戶初始化的堆棧 IF :DEF:__MICROLIB ; 檢查是否定義了__MICROLIB,在編譯器中設置 ; 有時候使用外部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 |