午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

AT91初始化代碼手冊中文翻譯版

 我是山芋 2010-11-17

AT91初始化代碼手冊中文翻譯版

 

 

AT91初始化代碼手冊中文翻譯版

介紹
由于多種原因基于ARMAT91的大多數(shù)應(yīng)用代碼使用C語言編寫。然而,啟動順序需要初始化ARM處理器和嚴(yán)重依賴于寄存器結(jié)構(gòu)的關(guān)鍵設(shè)備和內(nèi)存映射處理機(jī),和存儲器重映射操作。由于這個(gè)原因,C啟動序列必須用匯編編寫。
這個(gè)應(yīng)用筆記描述了一個(gè)AT91C代碼啟動序列示例。他是使用ARM ADS1.1研發(fā)工具為AT91評估板寫的基于C啟動序列。更多的可用C啟動序列示例見AT91庫。在上電并且復(fù)位后C啟動序列激活執(zhí)行。

C啟動次序
在設(shè)計(jì)ARM嵌入式應(yīng)用設(shè)計(jì)中主要的考慮是規(guī)劃內(nèi)存圖。特別是位于地址0x0的存儲器。復(fù)位后,處理器從地址0x0處的指令處開始執(zhí)行,因此必須能夠從此處取得可執(zhí)行代碼。在嵌入式系統(tǒng)中,這需要初始化后在地址0xO處是NVM(非揮發(fā)存儲器)。
最簡單的規(guī)劃是在存儲器映射中將ROM定位在地址0。當(dāng)他首先執(zhí)行位于0x00地址的第一條指令后應(yīng)用程式能夠指向自動的實(shí)際入口。但是這也有一個(gè)缺點(diǎn),ROM位窄(8、16位)且比RAM慢,存取他需要更多的等待周期。這將減緩處理器處理通過矢量表的異常尤其是中斷。況且,假如矢量表在ROM中,他不能夠被代碼編輯。
由于RAMROM存取速度快且位寬,假如在RAM0x00處存儲器作為矢量表和中斷句柄更好。雖然在通常運(yùn)行中RAM被定位在0x0處數(shù)必需的,假如上電后RAM定位在地址0x0,再復(fù)位指令入口處沒有一個(gè)合法的可執(zhí)行指令。所以上電后ROM必須定位在0x0以確保此處有一個(gè)合法的復(fù)位矢量。從復(fù)位到正常運(yùn)行的存儲器圖變換通常通過執(zhí)行一個(gè)REMAP(重映射)來完成。
許多基于ARM的嵌入式應(yīng)用程式包含在ROM中且在復(fù)位后執(zhí)行。當(dāng)編寫嵌入式操作系統(tǒng),或沒有操作系統(tǒng)從復(fù)位后執(zhí)行的嵌入式應(yīng)用程式時(shí)有幾個(gè)因素必須考慮,包括:
*
變換ROMRAM,以改善執(zhí)行速度。
*
初始化執(zhí)行環(huán)境。例如異常向量,堆棧、I/O引腳
*
初始化應(yīng)用——例如,從ROM中到RAM中拷貝初始化值付值給初始化變量并且清除其他變量為0。
*
連接嵌入式執(zhí)行映像到存儲器中放置程式和代碼的指定區(qū)域。
對于沒有操作系統(tǒng)的嵌入式應(yīng)用,rom中的代碼必須提供一個(gè)方法以初始化他自己并且開始執(zhí)行。復(fù)位后不會自動初始化,因此應(yīng)用程式入口在他調(diào)用C代碼之前執(zhí)行一些初始化。
復(fù)位后定位在地址零的初始化代碼,必須:
*
為初始化代碼標(biāo)記入口標(biāo)記
*
配置異常向量。
*
初始化內(nèi)存系統(tǒng)
*
初始化堆棧指針寄存器
*
初始化任何臨界I/O器件
*
初始化中斷系統(tǒng)需求的任何RAM變量
*
使能中斷(假如通過初始化句柄)
*
假如需要的話改變處理器模式
*
假如需要的話改變處理器狀態(tài)
環(huán)境初始化完成后,應(yīng)用程式初始化繼續(xù)并且將進(jìn)入C代碼入口。
C
啟動文檔是上電后第一個(gè)執(zhí)行的文檔并且從復(fù)位后執(zhí)行微控制器初始化然后調(diào)用其他應(yīng)用程式的主例程。主程式將是個(gè)死循環(huán)且不應(yīng)該返回。
ARM
內(nèi)核復(fù)位后從地址零處開始執(zhí)行。對于嵌入式系統(tǒng)。這意味著系統(tǒng)復(fù)位后ROM必須在地址0。由于ROM的限制,異常處理的速度將受到影響并且異常向量不能被編輯。一個(gè)通用的策略是重映射ROMRAM中并且啟動后從ROM拷貝異常向量到RAM.

C啟動示例
AT91軟件庫中本筆記和其他筆記包含一個(gè)普通的啟動文檔。這個(gè)事例基于AT91研發(fā)板、使用ARM ADS 1.1研發(fā)工具在外接閃存中調(diào)試。這個(gè)文檔必須被編輯以適應(yīng)用戶的需要。
每個(gè)AT91評估板描述在AT91庫的\software\targets子目錄中。每個(gè)這些子目錄中包含下列文檔:
*<target>.h
文檔,用C描述的線路板組件
*<target>.inc
文檔,用匯編描述的線路板組件
*
一個(gè)或多個(gè)cstartup.s,使用ARM SDT、ARM ADSGREEN HILL MULTI 200的標(biāo)準(zhǔn)引導(dǎo)示例。
AT91
庫提供C啟動文檔解釋如何引導(dǎo)AT91零件并且如何分支到MAIN主函數(shù)。啟動代碼提供一個(gè)如何考慮零件的特別性引導(dǎo)AT91零件以達(dá)到板子指定特性和調(diào)試級別需求的實(shí)例。
初始化代碼的區(qū)域定義和入口指針
ARM匯編語言源文檔中,開始片斷必須通過AREA偽指令標(biāo)記。這個(gè)偽指令片斷并且配置他的屬性。屬性被放置在名字之后,通過逗號分割。以上代碼示例定義一個(gè)名為RESET的只讀代碼段。
一個(gè)可執(zhí)行映像必須有一個(gè)入口指針。被放置在ROM中的可執(zhí)行映像通常在0x0放置一個(gè)入口指針。在初始化代碼中使用匯編偽指令定義一個(gè)入口指針。
;----------------------------------------------------------------------------------
;-
區(qū)域定義
;----------------------------------------------------------------------------------
AREA              reset,CODE,READONLY
;---------------------------------------------------------------------------------
;
定義入口指針
;--------------------------------------------------------------------------------
ENTRY

配置異常向量
異常向量被配置為一個(gè)連續(xù)的指向到最近的標(biāo)號或連接到子程式分支的地址空間。在程式的正常執(zhí)行流程中,程式計(jì)數(shù)器增加使能處理器操作過內(nèi)部或外部源產(chǎn)生的事件。在通常運(yùn)行中異常發(fā)生后使處理器轉(zhuǎn)移執(zhí)行。這樣的事件的例子是:
*
外部產(chǎn)生中斷
*
處理器企圖執(zhí)行一個(gè)不明確的指令
當(dāng)這樣一個(gè)中斷發(fā)生時(shí),保護(hù)以前的處理器狀態(tài)是必須的,以便當(dāng)適當(dāng)?shù)漠惓3淌酵瓿珊髨?zhí)行中的程式能夠繼續(xù)執(zhí)行。
初始化代碼必須配置所需的異常向量(見表一)。假如ROM定位在地址0,向量包含指向每個(gè)異常的操作硬指令序列。在重映射前,這些向量被映射在地址0。為確保一個(gè)合法的跳轉(zhuǎn)他們必須是個(gè)關(guān)聯(lián)地址模式。重映射后,這些向量被應(yīng)設(shè)在地址0x01000000,并且僅能夠由NRST中斷或內(nèi)部中斷改變回去。
處理器的異常句柄通過向量表控制。向量表是個(gè)32字節(jié)(byte)的保留區(qū)域,通常在內(nèi)寸圖的底部。每個(gè)向量分配一個(gè)字的(word)空間,并且當(dāng)前的保留字示于表一。因?yàn)榇颂幱凶銐虻目臻g包含句柄的全部代碼,每個(gè)例外向量的入口包含一個(gè)分支指令或調(diào)入PC指令以便繼續(xù)執(zhí)行適當(dāng)?shù)奶幚怼?/span>


表一。異常向量


;------------------------------------------------------------------------------
;-
異常向量(重映射前)
;-------------------------------------------------------------------------------
B   itReset   ;reset
undefvec
B   defvec  ; Undefined Instruction
swivec
B   ivec  ; Software Interrupt
pabtvec
B   btvec   ;Prefetch Abort
dabtvec
B   btvec   ;Data Abort
rsvdvec
B   rsvdvec   ; reserved
irqvec
B   irqvec   ; reserved
fiqvec
B   fiqvec   ; reserved

 圖一。異常向量圖
外部總線接口初始化平臺
EBI
平臺被用來配置內(nèi)存控制器。EBI依賴于器件、時(shí)鐘和外部內(nèi)存存取時(shí)間。這些植被定義在相應(yīng)目標(biāo)器件的“INCLUDE   FILE”,例如對于AT91EB55評估板的eb55.inc文檔。
;--------------------------------------------------------------------------
;-EBI
初始化數(shù)據(jù)
;--------------------------------------------------------------------------
InitTableEBI
DCD   EBI_CSR_0
DCD   EBI_CSR_1
DCD   EBI_CSR_2
DCD   EBI_CSR_3
DCD   EBI_CSR_4
DCD   EBI_CSR_5
DCD   EBI_CSR_6
DCD   EBI_CSR_7
DCD   0x00000001 ; REMAP
命令
DCD   0x00000006 ; 6   
存儲器區(qū)域
PtEBIBase
DCDEBI_BASE ; EBI Base Address
,標(biāo)準(zhǔn)讀

復(fù)位處理
位于地址零的代碼從這開始執(zhí)行。應(yīng)該注意的是,他被連接到0x100  0000
;------------------------------------------------------------
;-
重映射前復(fù)位處理
;------------------------------------------------------------
InitReset

    加速引導(dǎo)過程
復(fù)位后,擴(kuò)展總線界面沒有配置為片選0和片選0-8的等待狀態(tài)分離。在重映射命令前,片選0配置能夠通過編程具備精確引導(dǎo)內(nèi)存特性的EBI_CSR0來編輯。,重映射后底部地址變得有效,但等待狀態(tài)的新數(shù)目能夠被立即改變。假如希望引導(dǎo)更快的話這是所希望的。
;---------------------------------------------------------------------------
;-
加速引導(dǎo)過程
;-------------------------------------------------------------------------
;-
調(diào)入EBI系統(tǒng)的底部地址和CSR0的初始值
ldr  r0, ptEBIBase
ldr  r1, InitTableEBI   ;
相對值
;- 
通過禁止片選0的等待狀態(tài)加速代碼執(zhí)行
str  r1, [r0]

低級初始化
當(dāng)臨界狀態(tài)時(shí)應(yīng)該考慮外圍設(shè)備在使能終端前必須被初始化。假如這些外圍設(shè)備在此處沒有被初始化,當(dāng)中斷使能時(shí)可能引起虛假的中斷。
;-------------------------------------------------------------------------------
;-   
低級初始化
;-------------------------------------------------------------------------------
bl —low_level_init

    例如:在AT91EB55評估板上,啟動PLL(鎖相環(huán))。
   
在復(fù)位時(shí),AT91M55800微控制器使用低速時(shí)鐘(32.786KHZ〕啟動以減小系統(tǒng)啟動時(shí)的電源需求并 且主振蕩器是禁止的。PLL能夠通過配置高級電源管理控制來運(yùn)行主振蕩器來啟動以加速啟動過程。
_low_level_init
函數(shù)在相應(yīng)的評估板的AT91軟件庫中在匯編文檔中定義。
高級中斷控制器配置
復(fù)位后,高級中斷控制器(AIC)沒有配置。C啟動文檔通過配置缺省中斷向量來初始化AIC。缺省中斷操作函數(shù)定義在AT91函數(shù)庫中。這些函數(shù)能夠在應(yīng)用代碼中被重新定義。中斷缺省操作的初始化見圖2

;---------------------------------------------------------------------------
;-
高級終端控制器配置
;---------------------------------------------------------------------------
;-
配置缺省向量
;---------------------------------------------------------------------------
;-
調(diào)入AIC基礎(chǔ)地址和缺省操作地址
add   r0, pc,#-(8+.-AicData)  ; @
這里是讀取相對值
ldmia  r0, {r1-r4}
;-
配置偽造向量
str   r4, [r1, #AIC_SPU]  ; r4 =
偽操作
;-
配置缺省中斷操作向量
str   r2, [r1, #AIC_SVR] ; SVR[0] for FIQ
add   r1, r1, #AIC_SVR
mov   r0, #31    ;
計(jì)數(shù)器
LoopAic1
str   r3, [r1, r0, LSL #2]  ; SVRs for IRQs
subs  r0, r0, #1    ; do not save FIQ
bhi   LoopAic1
b   EndInitAic
;---------------------------------------------------------------------------
;-
缺省中斷操作
;---------------------------------------------------------------------------
AicData
DCD  AIC_BASE  ; AIC Base Address
IMPORT  at91_default_fiq_handler
IMPORT  at91_default_irq_handler
IMPORT  at91_spurious_handler
PtDefaultHandler
DCD  at91_default_fiq_handler
DCD  at91_default_irq_handler
DCD  at91_spurious_handler
EndInitAic
2,中斷的缺省操作初始化
                                                          
高級中斷控制器

拷貝異常向量到內(nèi)部RAM

異常向量必須拷貝到內(nèi)部RAM中。為確保在重映射操作中內(nèi)核執(zhí)行合法向量,在重映射前執(zhí)行這個(gè)操作是重要的。這里僅僅有五個(gè)偏移作為引導(dǎo)使用。見表3。
;------------------------------------------------------------
;--- 
在重映射前在內(nèi)部RAM中配置異常向量
;------------------------------------------------------------
b  SetupRamVectors
VectorTable
ldr  pc, [pc, #&18] ; SoftReset
軟件復(fù)位
ldr  pc, [pc, #&18]  ; UndefHandler
未定義操作
ldr  pc, [pc, #&18]  ; SWIHandler
ldr  pc, [pc, #&18]  ; PrefetchAbortHandler
ldr  pc, [pc, #&18]  ; DataAbortHandler
nop    ; Reserved
ldr  pc, [pc,#-0xF20]  ; IRQ : read the AIC
AIC
ldr  pc, [pc,#-0xF20]  ; FIQ : read the AIC
;-
僅僅有五個(gè)偏移量作為向量使用
DCD  SoftReset
DCD  UndefHandler
DCD  SWIHandler
DCD  PrefetchAbortHandler
DCD  DataAbortHandler
;-
運(yùn)行在絕對地址的向量執(zhí)行函數(shù)
SoftReset
b SoftReset
UndefHandler
b  UndefHandler
SWIHandler
b  SWIHandler
PrefetchAbortHandler
b  PrefetchAbortHandler
DataAbortHandler
b  DataAbortHandler
SetupRamVectors
mov  r8, #RAM_BASE_BOOT  ; @
RAM 0x300000的硬件向量
add  r9, pc,#-(8+.-VectorTable)  ; @
從哪兒度相對值
ldmia  r9!, {r0-r7}  ;
8向量
stmia  r8!, {r0-r7}   ;
存儲他們到RAM
ldmia  r9!, {r0-r4}   ;
5絕對操作地址
stmia  r8!, {r0-r4}   ; 
存儲他們到RAM

3,在RAM中拷貝異常向量
存儲器控制初始化和重映射命令

復(fù)位后AT91系列的RAM映射在地址0x0030 0000。連接到片選0的存儲器映射在地址0。當(dāng)重映射命令執(zhí)行時(shí),擴(kuò)展存儲器映射在片選寄存器0定義的地址。內(nèi)部ram定義在地址0以允許在0x00x20之間的異常向量能夠由軟件編輯。

;---------------------------------------------------------------------------
;-
內(nèi)存控制器初始化
;---------------------------------------------------------------------------
;-
拷貝內(nèi)存控制器的映像
sub  r10, pc,#(8+.-InitTableEBI)   ;
得到芯片地址
;
選擇寄存器映像
ldr  r12, PtInitRemap    ;
得到真實(shí)的跳轉(zhuǎn)地址
; (
重映射后)
;- Copy Chip Select Register Image to Memory Controller and command remap
;-拷貝片選寄存器映像到內(nèi)存控制器和重映射命令
ldmia  r10!, {r0-r9,r11}    ;
調(diào)入完整映像和
; EBI
基礎(chǔ)地址
stmia  r11!, {r0-r9}    ;
存儲完整映像包括
;
重映射命令
;- J
跳轉(zhuǎn)到rom新地址
mov  pc, r12     ; jump and break the pipeline
PtInitRemap
DCD  InitRemap    ; address where to jump after REMAP
;---------------------------------------------------------------------------
;- From here, the code is executed from its link address, ie. 0x100 0000.
;-
從此處,代碼開始從他的連接地址開始執(zhí)行,例如,0x100 0000
;---------------------------------------------------------------------------
InitRemap

ARM處理器流水線確保"mov pc,r12"指令在重映射指令執(zhí)行前得到讀取。重映射后,下一條指令被從RAM中讀取并且"mov pc,r12"指令執(zhí)行完成跳轉(zhuǎn)到ROMr12(0x100011C)以前的裝載地址因此如圖4所示同時(shí)打斷流水線。重映射后的存儲器圖描述見圖5
4,重映射命令期間arm內(nèi)核流水線
                                     
重映射前                                                      重映射后                mov PC,r12

流水線

存儲器


5,重映射后內(nèi)存圖

初始化堆棧寄存器

快速中斷、中斷、異常終止未定義和。管理堆棧定位在內(nèi)部存儲器的頂部以加速操作速度。用戶(應(yīng)用程式,C)堆棧定位在擴(kuò)展存儲器頂部。
初始化代碼初始化堆棧指針寄存器。依賴于中斷和異常需要,下面一些或任何堆棧指針需要初始化:
*
管理堆棧必須經(jīng)常初始化
*
假如使用IRQ中斷的話則IRQ中斷堆棧必須初始化。必須在中斷使能前完成初始化。
*
假如使用FIQ中斷的話則FIQ中斷堆棧必須初始化。必須在中斷使能前完成初始化。
*
數(shù)據(jù)和預(yù)取操作的Abort-stack必須初始化。
*
未定義指令操作的未定義指令堆棧必須初始化。
通常,Abort-state和未定義指令在簡單嵌入式系統(tǒng)中不使用。然而,初始化他們用于調(diào)試目的是更優(yōu)越的。
當(dāng)改變到用戶模式執(zhí)行應(yīng)用程式時(shí)用戶堆棧指針能夠被配置。
;------------------------------------------------------------------------
;-
堆棧大小定義
;---------------------------------------------------------------------------
IRQ_STACK_SIZE  EQU  (3*8*4)   ; 3 words
FIQ_STACK_SIZE  EQU  (3*4)   ; 3 words
ABT_STACK_SIZE  EQU  (1*4)   ; 1 word
UND_STACK_SIZE  EQU  (1*4)   ; 1 word
假定使用IRQ_ENTRY/IRQ_EXIT宏指令,當(dāng)使用向量時(shí)中斷堆棧需要3個(gè)字*優(yōu)先級8*4字節(jié)。中斷堆棧依賴于中斷操作調(diào)整。快速中斷需要3個(gè)字*4字節(jié),沒有優(yōu)先級。其他堆棧定義為使用缺省的每個(gè)一個(gè)字。用戶堆棧沒有定義并且由外接RAM的自由空間所限。

;---------------------------------------------------------------------------
;-
堆棧頂部定義
;---------------------------------------------------------------------------
TOP_EXCEPTION_STACK EQU RAM_LIMIT   ; Defined in part
TOP_APPLICATION_STACK EQU EXT_SRAM_LIMIT ; Defined in Target
;---------------------------------------------------------------------------
;-
配置每種模式的堆棧
;---------------------------------------------------------------------------
ldr   r0, =TOP_EXCEPTION_STACK
;-
配置快速中斷模式和配置FIQ模式堆棧
msr   CPSR_c, #ARM_MODE_FIQ:OR:I_BIT:OR:F_BIT
mov   r13, r0       ;
初始化FIQ
sub   r0, r0, #FIQ_STACK_SIZE
;-
配置中斷模式和配置FIQ模式堆棧
msr   CPSR_c, #ARM_MODE_IRQ:OR:I_BIT:OR:F_BIT
mov   r13, r0       ; Init stack IRQ
sub   r0, r0, #IRQ_STACK_SIZE
;-
配置異常終止模式和配置異常終止模式堆棧
msr   CPSR_c, #ARM_MODE_ABORT:OR:I_BIT:OR:F_BIT
mov   r13, r0       ; Init stack Abort
sub   r0, r0, #ABT_STACK_SIZE
;-
配置未定義指令模式和配置未定義指令模式堆棧
msr   CPSR_c, #ARM_MODE_UNDEF:OR:I_BIT:OR:F_BIT
mov  r13, r0       ; Init stack Undef
sub   r0, r0, #UND_STACK_SIZE
;-
配置管理模式和管理模式堆棧
msr   CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT
mov  r13, r0       ; Init stack Sup

改變處理器模式和使能中斷

假如需要的話初始化代碼現(xiàn)在能夠通過清除CPSR的中斷禁止位來使能中斷。這是最早期的安全使能中斷的操作。在此時(shí)處理器一直處于管理模式。假如應(yīng)用程式運(yùn)行在用戶模式,改變到用戶模式并且初始化用戶模式堆棧。
;---------------------------------------------------------------------------
;-
配置應(yīng)用程式運(yùn)行模式和使能中斷
;---------------------------------------------------------------------------
msr   CPSR_c, #ARM_MODE_USER   ;
配置用戶模式
ldr   r13, =TOP_APPLICATION_STACK   ;
初始化用戶堆棧

初始化軟件變量并且指向主函數(shù)

下一個(gè)任務(wù)是初始化數(shù)據(jù)存儲器進(jìn)入一個(gè)循環(huán)寫零到指定位置用來存儲數(shù)據(jù)。這好形式多余的,但這樣做有兩個(gè)原因:
1.
C語言中,任何未初始化的變量假定包含0作為初始化值。
2.
這能夠使程式行為再現(xiàn),即使不是任何變量明顯初始化。
   ——
初始化變量的初始化值列表(C語言方法)拷貝到RAM中變量所在的位置。
   ——
連接器放置初始化值到RAM中相應(yīng)的變量中。
任何初始化變量的初始化值必須從ROM中拷貝到RAM中。任何其他變量必須初始化為0。
當(dāng)編譯器編譯調(diào)用MAIN()的函數(shù)時(shí),他產(chǎn)生一個(gè)_MAIN的模型強(qiáng)制連接器從ANSIC函數(shù)庫中包含基礎(chǔ)的C運(yùn)行系統(tǒng)。初始化代碼庫調(diào)用_main執(zhí)行拷貝和初始化。main()函數(shù)應(yīng)當(dāng)是個(gè)封閉的循環(huán)并且沒有返回值。

;---------------------------------------------------------------------------
;-
交互方式轉(zhuǎn)移到C代碼主函數(shù)
;---------------------------------------------------------------------------
IMPORT   __main
ldr    r0, =__main
bx    r0
end

 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多