arm啓動過程詳解

1、綜述

    目前大多基於ARM芯片的系統都是一個比較複雜的片上系統,多數硬件模塊都是可配置的,可以通過軟件來設置其需要的工作狀態。因此在運行用戶的應用程序之前,需要由專門的一段代碼來完成對系統的初始化。這一段代碼就稱爲啓動程序。

    由於這類代碼直接面對處理器內核和硬件控制器進行編程,一般都是用彙編語言。在ARM系統上電覆位後,需要設置中斷向量表、初始化各模式堆棧、設置系統時鐘頻率等,需要用ARM的彙編語言編寫啓動代碼,由啓動代碼完成系統初始化以及跳轉到用戶C程序。在ARM設計開發中,啓動代碼的編寫是一個極重要的過程。然而啓動代碼隨具體的目標系統和開發系統有所區別,但通常包含以下部分:

    ·向量表定義
    ·地址重映射及中斷向量表的轉移
    ·堆棧初始化
    ·設置系統時鐘頻率
    ·中斷寄存器的初始化
    ·進入C應用程序

下面就結合PHILIPS的LPC2119的啓動代碼來分析與說明ARM7處理器的啓動代碼的編寫。

1.1向量表定義

 
 

        ARM芯片上電或復位後,系統進入管理模式、ARM狀態、PC(R15寄存器)指向0x00000000地址處。中斷向量表爲每一箇中斷設置1個字的存儲空間,存放一條跳轉指令,通過這條指令使PC指針指向相應的中斷服務程序入口,繼而執行相應的中斷處理程序。LPC2119的中斷向量表和其它基於ARM核的芯片中斷向量表較類似,只要注意LPC2119要使向量表所有數據32位累加和爲零(0x00000000-0x0000001C的8個字的機器碼累加), 才能使用戶的程序脫機運行。LPC2119的中斷向量表如圖1所示。

1.2 地址重映射及中斷向量表的轉移

        ARM7處理器在復位後從地址0讀取第一條指令並執行,因此係統上電後地址0必須是非易失的ROM/FLASH,這樣才能保證處理器有正確可用的指令。爲了加快對中斷的處理以及實現在不同操作系統模式下對中斷的處理,這就需要重新映射中斷向量表、Bootblock和SRAM空間的一小部分。ARM具有非常靈活的存儲器地址分配特性。ARM處理器的地址重映射機制有兩種情況:
  ①由專門的寄存器完成重映射(Remap),只需對相應的Remap寄存器相應位設置即可。
  ②沒有專門的Remap控制寄存器需要重新改寫用於控制存儲器起始地址的塊(Bank)寄存器來實現Remap。在LPC2119上的重映射,可以通過存儲器映射控制器來實現。實現REMAP操作的程序實現如下:

MOV R8,#0x40000000;            /設置新向量表起始地址/
LDR R9,=Interrupt_Vector_Table;             /讀原向量表源地址/
LDMIA R9!,(R0-R7);               /複製中斷向量表及中斷處理程序的入口地址到RAM中(64字節)/
STMIA R8!,(R0-R7)
LDMIA R9!,(R0-R7)
STMIA R8!,(R0-R7)
LDR R8,=MEMMAP ;           /REMMAP操作/
MOV R9,#0x02
STR R9, [R8]

1.3 堆棧初始化

        啓動代碼中各模式堆棧空間的設置是爲中斷處理和程序跳轉時服務的。當系統響應中斷或程序跳轉時,需要將當前處理器的狀態和部分重要參數保存在一段存儲空間中,所以對每個模式都要進行堆棧初始化工作,給每個模式的SP定義一個堆棧基地址和堆棧的容量。堆棧的初始化有兩種方法:第一種方法是結合ADS開發套件中的分散加載文件來定義堆棧。第二種方法是最簡單也是最常用的一種就是直接進入對應的處理器模式,爲SP寄存器指定相應的值。下面給出了用第二種方法初始化管理模式和中斷模式堆棧的程序:

MSR CPSR_c, #0xD3 ;           /切換到管理模式,並初始化管理模式的堆棧/
LDR SP, Stack_Svc
MSR CPSR_c, #0xD2 ;            /切換到IRQ模式,並初始化IRQ模式的堆棧/
LDR SP, Stack_Irq


1.4 系統部分時鐘初始化

        時鐘是芯片各部分正常工作的基礎,應該在進入main()函數前設置。部分ARM7片子內部集成有PLL(鎖相環)電路,用戶可以用低頻率的晶振通過PLL電路獲得一個較高頻率的時鐘。LPC2119內部的PLL電路接受的輸入時鐘頻率範圍爲10~25MHz,輸入頻率通過一個電流控制振盪器(CCO)倍增到範圍10~60MHz。同時爲了使高速的ARM處理器與低速的外設正常通訊和降低功耗(降低外設運行速度使功耗降低),LPC2119又集成了一個額外的分頻器。PLL的激活是由PLLCON寄存器控制。PLL倍頻器和分頻器的值由PLLCFG寄存器控制。對PLLCON或PLLCFG寄存器的更改必須遵循嚴格的順序,否則所作更改是無法生效的(在連續的VPB週期內向PLLFEED寄存器寫入0xAA、0x55,在此期間中斷必須是被禁止的。)

1.5 中斷初始化

         ARM7的向量中斷控制器(Vectored Interrupt Controller)可以將中斷編程爲3類:FIQ、向量IRQ、非向量IRQ。FIQ中斷請求的優先級最高,其次是IRQ中斷請求,非向量IRQ的優先級最低。VIC具有32箇中斷請求輸入,但在LPC2219中只佔用了17箇中斷輸入。對於這17箇中斷源的IRQ/FIQ選擇,由VICIntSelect寄存器控制,當對應位設置位1時,則此中斷爲FIQ中斷,否則爲IRQ中斷。若再將IRQ中斷設置到向量控制寄存器(VICVectCntIn)中,則此中斷爲向量IRQ中斷,否則爲非向量IRQ中斷。FIQ中斷是專門用來處理那些需要及時響應的特殊事件,儘可能地只給FIQ分配一箇中斷源。

1.6 進入C應用程序

        至此,系統各部分的初始化基本完成,可以直接從啓動代碼轉入到應用程序的main()函數入口。從啓動代碼轉入到應用程序的實例代碼如下:

IMPORT main
LDR R0,=main
BX R0

2、總結

        一個優秀的啓動代碼將給應用程序的開發提供一個良好的開發平臺。本文中較詳細的討論了啓動代碼的編寫及難點。其中在堆棧初始化過程中要特別的注意兩點:
  ①要儘量給堆棧分配快速和高帶寬的存儲器。
  ②儘量避免過早將處理器切換到用戶模式,一般在系統初始化的最後階段才切換到用戶模式(用戶模式沒有權限通過修改CPSR來進行模式切換)。

        嵌入式系統的迅猛發展,使啓動代碼的編寫成爲嵌入式系統開發人員應該具備的能力。本文有助於正在從事嵌入式ARM開發的讀者理解啓動代碼的內涵與編寫出適合自己的啓動代碼。

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