ARM 啟動代碼詳解_第1頁
ARM 啟動代碼詳解_第2頁
ARM 啟動代碼詳解_第3頁
ARM 啟動代碼詳解_第4頁
ARM 啟動代碼詳解_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、半ARM 啟絆動代碼詳解藹(Vect扳ors.c襖、Init靶.s、Ta拜rget.扳c、 Ta癌rget.矮h)扳2010-背05-15敖 16:0藹3啟動代碼是芯片復(fù)位后進(jìn)入C語言的main()函數(shù)前執(zhí)行的一段代碼,主要是為運(yùn)行C語言程序提供基本運(yùn)行環(huán)境,如初始化存儲器系統(tǒng)等。ARM公司只設(shè)計(jì)內(nèi)核,不自己生產(chǎn)芯片,只是把內(nèi)核授權(quán)給其它廠商,其它廠商購買了授權(quán)且加入自己的外設(shè)后生產(chǎn)出各具特色的芯片。這樣就促進(jìn)了基于ARM處理器核的芯片多元化,但也使得每一種芯片的啟動代碼差別很大,不易編寫出統(tǒng)一的啟動代碼。ADS(針對ARM處理器核的C語言編譯器)的策略是不提供完整的啟動代碼,啟動代碼不足部分

2、或者由廠商提供,或者自己編寫。啟動代碼劃分為4個(gè)文件:Vectors.c、Init.s、Target.c、 Target.h。Vectors.c包含異常向量表、堆棧初始化及中斷服務(wù)程序與C程序的接口。Init.s包含統(tǒng)初始化代碼,并跳轉(zhuǎn)到ADS提供的初始化代碼。Target.c和 Target.h包含目標(biāo)板特殊的代碼,包括異常處理程序和目標(biāo)板初始化程序。這樣做的目的是為了盡量減少匯編代碼,同時(shí)把不需要修改的代碼獨(dú)立出來以減少錯(cuò)誤。 4.2.1 Vectors.c文件的編寫 中斷向量表Vectors LDR PC, ResetAddr LDR PC, UndefinedAddr LDR PC,

3、SWI_Addr LDR PC, PrefetchAddr LDR PC, DataAbortAddr DCD 0 xb9205f80 LDR PC, PC, #-0 xff0 LDR PC, FIQ_AddrResetAddr DCD ResetUndefinedAddr DCD UndefinedSWI_Addr DCD SoftwareInterruptPrefetchAddr DCD PrefetchAbortDataAbortAddr DCD DataAbortnouse DCD 0IRQ_Addr DCD IRQ_HandlerFIQ_Addr DCD FIQ_Handler異常是

4、由內(nèi)部或外部源產(chǎn)生的以引起處理器處理的一個(gè)事件。ARM處理器核支持7種類型的異常。異常出現(xiàn)后,CPU強(qiáng)制從異常類型對應(yīng)的固定存儲地址開始執(zhí)行程序。這個(gè)固定的地址就是異常向量。向量從上到下依次為復(fù)位、未定義指令異常、軟件中斷、預(yù)取指令中止、預(yù)取數(shù)據(jù)中止、保留的異常、IRQ和 FIQ。IRQ向量“LDR PC, PC, #-0 xff0” 使用的指令與其它向量不同。在正常情況下這條指令所在地址為0X。當(dāng)CPU執(zhí)行這條指令但還沒有跳轉(zhuǎn)時(shí),PC的值為0X,0X減去 0X00000FF0為 0XFFFFF030,這是向量中斷控制器(VIC)的特殊寄存器VICVectAddr。這個(gè)寄存器保存當(dāng)前將要服務(wù)的

5、IRQ的中斷服務(wù)程序的入口,用這一條指令就可以直接跳轉(zhuǎn)到需要的中斷服務(wù)程序中。至于在保留的異常向量“DCD 0 xb9205f80”位置填數(shù)據(jù)0 xb9205f8是為了使向量表中所有的數(shù)據(jù)32位累加和為0。 初始化CPU堆棧InitStack MOV R0, LR MSR CPSR_c, #0 xd2 ;設(shè)置中斷模式堆棧 LDR SP, StackIrq MSR CPSR_c, #0 xd1 ;設(shè)置快速中斷模式堆棧 LDR SP, StackFiq MSR CPSR_c, #0 xd7 ;設(shè)置中止模式堆棧 LDR SP, StackAbt MSR CPSR_c, #0 xdb ;設(shè)置未定義模式

6、堆棧 LDR SP, StackUnd MSR CPSR_c, #0 xdf ;設(shè)置系統(tǒng)模式堆棧 LDR SP, StackSys MOV PC, R0StackIrq DCD (IrqStackSpace + IRQ_STACK_LEGTH * 4 - 4)StackFiq DCD (FiqStackSpace + FIQ_STACK_LEGTH * 4 - 4)StackAbt DCD (AbtStackSpace + ABT_STACK_LEGTH * 4 - 4)StackUnd DCD (UndtStackSpace + UND_STACK_LEGTH * 4 - 4)StackSy

7、s DCD (SysStackSpace + SYS_STACK_LEGTH * 4 -4 );/* 分配堆??臻g */ AREA MyStacks, DATA, NOINITIrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;中斷模式堆棧FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;快速中斷模式堆棧AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;中止義模式堆棧UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;未定義模式堆棧SysStackSpace SPACE

8、 SYS_STACK_LEGTH * 4 ; 系統(tǒng)模式堆棧因?yàn)槌绦蛐枰袚Q模式,而且程序退出時(shí)CPU的模式已經(jīng)不再是管理模式而是系統(tǒng)模式LR已經(jīng)不再保存返回程序地址,所以程序首先把返回地址保存到 R0中,同時(shí)使用R0返回。然后程序把處理器模式轉(zhuǎn)化為IRQ模式,并設(shè)置IRQ模式的堆棧指針。其中變量Stacklrq保存著IRQ模式的堆棧指針的初始值,Irqstackspace是分配給 IRQ模式的堆??臻g的開始地址,IRQ_STACK_LEGTH是用戶定義的常量,用于設(shè)置 IRQ模式的堆棧空間的大小。程序使用同樣的方法設(shè)置FIQ模式堆棧指針、中止模式堆棧指針、未定義堆棧指針和系統(tǒng)模式堆棧指針。程序

9、使用編譯器分配的空間作為堆棧,而不是按照通常的做法把堆棧分配到 RAM的頂端,之所以這樣是因?yàn)檫@樣做不必知道RAM頂端位置,移植更加方便;編譯器給出的占用RAM空間的大小就是實(shí)際占用的大小,便于控制RAM的分配。對于 LPC2106來說,中止模式是不需要分配堆??臻g的,這是因?yàn)?LPC2106沒有外部總線,也沒有虛擬內(nèi)存機(jī)制,如果出現(xiàn)取數(shù)據(jù)中止或取指令中止肯定是程序有問題。而一般情況下也不需要模擬協(xié)處理器指令或擴(kuò)充指令,未定義中止也就意味著程序有錯(cuò)誤,也不需要分配堆??臻g。 異常處理代碼與C語言的接口程序C/OS-中斷服務(wù)子程序流程圖如圖4-1所示:圖4-1 中斷服務(wù)子程序流程圖異常處理代碼與

10、C語言的接口程序如下:MACRO$IRQ_Label HANDLER $IRQ_Exception EXPORT $IRQ_Label ;輸出的標(biāo)號 IMPORT $IRQ_Exception ;引用的外部標(biāo)號$IRQ_Label SUB LR, LR, #4 ;計(jì)算返回地址 STMFD SP!, R0-R3, R12, LR ;保存任務(wù)環(huán)境 MRS R3, SPSR ;保存狀態(tài) STMFD SP!, R3 LDR R2, =OSIntNesting ;OSIntNesting+ LDRB R1, R2 ADD R1, R1, #1 STRB R1, R2 BL $IRQ_Exception

11、;調(diào)用c語言的中斷處理程序 MSR CPSR_c, #0 x92 ;關(guān)中斷 BL OSIntExit LDR R0, =OSTCBHighRdy LDR R0, R0 LDR R1, =OSTCBCur LDR R1, R1 CMP R0, R1 LDMFD SP!, R3 MSR SPSR_cxsf, R3 LDMEQFD SP!, R0-R3, R12, PC ;不進(jìn)行任務(wù)切換 LDR PC, =OSIntCtxSw ;進(jìn)行任務(wù)切換 MENDUndefined ;未定義指令 b UndefinedPrefetchAbort ;取指令中止 b PrefetchAbortDataAbort ;

12、取數(shù)據(jù)中止 b DataAbortIRQ_Handler HANDLER IRQ_Exception ;中斷FIQ_Handler ;快速中斷 b FIQ_HandlerTimer0_Handler HANDLER Timer0 ;定時(shí)器0中斷未定義指令異常、取指令中止異常、取數(shù)據(jù)中止異常均是死循環(huán),其中原因在上一小節(jié)已經(jīng)說明。而快速中斷在本應(yīng)用中并未使用,所以也設(shè)置為死循環(huán)。LPC2106使用向量中斷控制器,各個(gè) IRQ中斷的人口不一樣,所以使用了一個(gè)宏來簡化中斷服務(wù)程序與C語言的接口編寫。由ARM處理器核的文檔可知,處理器進(jìn)入IRQ中斷服務(wù)程序時(shí)(LR4)的值為中斷返回地址,為了使任務(wù)無論

13、在主動放棄CPU時(shí)還是中斷時(shí)堆棧結(jié)構(gòu)都一樣,在這里先把LR減4。其它的部分與C/OS-要求的基本一致。ARM處理核在進(jìn)入中斷服務(wù)程序時(shí)處理器模式變?yōu)镮RQ模式,與任務(wù)的模式不同,它們的堆棧指針SP也不一樣,而寄存器應(yīng)當(dāng)保存到用戶的堆棧中,為了減少不必要的CPU時(shí)間和RAM空間的浪費(fèi),本移植僅在必要時(shí)將處理器的寄存器保存到用戶的堆棧中,其它時(shí)候還是保存到IRQ模式的堆棧中。同時(shí),從編譯器的函數(shù)調(diào)用規(guī)范可知,C語言函數(shù)返回時(shí),寄存器R4R11、SP不會改變,所以只需要保存CPSR、R0R3、R12和返回地址LR,在后面保存 CPSR是為了必要時(shí)將寄存器保存到用戶堆棧比較方便。在異常處理代碼與C語言

14、的接口程序中沒有與中斷服務(wù)子程序流程圖中的判斷語句對應(yīng)的語句。判斷語句是為了避免在函數(shù)OSIntCtxsw()調(diào)整堆棧指針,這個(gè)調(diào)整量是與編譯器、編譯器選項(xiàng)、C/OS -配置選項(xiàng)都相關(guān)的變量。在這里進(jìn)行這些處理相對其它處理器結(jié)構(gòu)可能增加的處理器時(shí)間很少,但對于ARM來說,由于中斷(IRQ)有獨(dú)立的堆棧,在這里這樣做就需要把所有寄存器從中斷的堆??截惖饺蝿?wù)的堆棧,需要花費(fèi)比較多的額外時(shí)間。而變量OSIntNesting為0時(shí),并不一定會進(jìn)行任務(wù)切換,所以本移植沒有與之對應(yīng)的程序,而在函數(shù)OSIntCtxsw()中做這一項(xiàng)工作。這樣,僅在需要時(shí)才處理這些事物,程序效率得以提高。在中斷調(diào)用后,如果需

15、要任務(wù)切換,則變量OSTCBHighRdy和變量OSTCBCur的值不同;如果不需要任務(wù)切換這兩個(gè)變量則相同。本移植通過判斷這兩個(gè)變量來決定是進(jìn)行任務(wù)切換,還是不進(jìn)行任務(wù)切換。通過比較,如果需要任務(wù)切換則執(zhí)行“LDR PC, =OSIntCtxSw”跳轉(zhuǎn)到OSIntCtxSw處進(jìn)行任務(wù)切換;如果不需要任務(wù)切換則執(zhí)行“LDMEQFD SP!, R0-R3, R12, PC”中斷返回。這里需要對“MSR CPSR_c, #0 x92”說明下,這條指令的作用是關(guān)IRQ中斷。因?yàn)橹袛啵↖RQ)模式的LR寄存器在處理器響應(yīng)中斷時(shí)用于保存中斷返回地址,所以在處理器響應(yīng)中斷時(shí)中斷(IRQ)模式的LR寄存器不

16、能保存有效數(shù)據(jù)。而BL指令要用LR寄存器保存BL下一條指令的位置,所以在中斷(IRQ)模式時(shí),在BL指令之前必須關(guān)中斷,在保存LR后才能開中斷。4.2.2 Target.c文件的編寫為了使系統(tǒng)基本能夠工作,必須在進(jìn)人 main()函數(shù)前對系統(tǒng)進(jìn)行一些基本的初始化工作,這些工作由函數(shù)TargetResetInit()完成。void TargetResetInit(void) uint32 i; uint32 *cp1; uint32 *cp2; extern void Vectors(void) ; /* 拷貝向量表,保證在flash和ram中程序均可正確運(yùn)行 */ cp1 = (uint32

17、*)Vectors; cp2 = (uint32 *)0 x; for (i = 0; i 2 * 8; i+) *cp2+ = *cp1+; MEMMAP = 0 x2;PINSEL0 = (PINSEL0 & 0 xFFFF0000) | UART0_PCB_PINSEL_CFG | 0 x50;PLLCON = 1; /* 設(shè)置系統(tǒng)各部分時(shí)鐘 */ VPBDIV = 0; PLLCFG =0 x23; PLLFEED = 0 xaa; PLLFEED = 0 x55; while(PLLSTAT & (1 10) = = 0) ; PLLCON = 3; PLLFEED = 0 xaa;

18、 PLLFEED = 0 x55; MAMCR = 2; /* 設(shè)置存儲器加速模塊 */#if Fcclk MAMTIM = 1;#else#if Fcclk MAMTIM = 2;#else MAMTIM = 3;#endif#endif首先向量表拷貝到RAM底部,加上這部分是為了代碼無論從Flash基地址開始編譯還是從RAM基地址開始編譯程序均運(yùn)行正確。而把RAM底部映射到向量表“MEMMAP = 0 x2”也是為了同一個(gè)目的。至于復(fù)制16個(gè)字而不是8個(gè)字,是因?yàn)楹?個(gè)字存儲跳轉(zhuǎn)的地址是通過 PC指針間接尋址的,它們與對應(yīng)指令(在向量表中)相對位置是不能變化的。因?yàn)樵谶M(jìn)入多任務(wù)環(huán)境前使用了

19、一些外設(shè),部分外設(shè)使用了芯片的引腳,而 LPC2106的所有引腳都是多功能的,所以需要設(shè)置引腳功能。同時(shí)串口也進(jìn)行了設(shè)置。時(shí)鐘是芯片各部分正常工作的基礎(chǔ),雖然時(shí)鐘可以在任何時(shí)候設(shè)置,但為了避免混亂,最好在進(jìn)入 main()函數(shù)前設(shè)置。程序首先使能PLL但不連接PLL,然后設(shè)置外設(shè)時(shí)鐘(VPB時(shí)鐘pclk)與系統(tǒng)時(shí)鐘(cclk)的分頻比。接著設(shè)置PLL的乘因子和除因子。設(shè)置完成后,使用“PLLFEED = 0 xaa; PLLFEED = 0 x55;”的訪問序列把數(shù)據(jù)正確寫人硬件,并等待PLL跟蹤完成。最后,使能PLL,并使PLL聯(lián)上系統(tǒng)。本應(yīng)用外接的晶振頻率(Fosc)為11.0592MHz

20、,倍增器的值M=4,所以處理器時(shí)鐘(Fcclk)為44.2368 MHz。為了使電流控制振蕩器頻率(Fcco)滿足156-320MHz,所以分頻器的值P=2,使得Fcco= Fcclk2P=176.9472 MHz。取VPB分頻器的分頻值為1/4,所以外設(shè)時(shí)鐘(Fpclk)= Fcclk/4=11.0592 MHz,則記數(shù)周期為0.09042s,定時(shí)0.2ms,則記數(shù)值為2212個(gè),這些時(shí)鐘的定義都在config.h文件中。用戶程序最終是要在Flash中運(yùn)行的,而系統(tǒng)復(fù)位時(shí)Flash是以最低速度運(yùn)行,這對發(fā)揮芯片的性能極其不利。雖然存儲器加速模塊可以在任何時(shí)候設(shè)置,但為了避免混亂,最好在進(jìn)入 main()函數(shù)前設(shè)置。首先使存儲器加速模塊全速工作,然后根據(jù)系統(tǒng)主時(shí)鐘利用條件編譯將Flash的訪問時(shí)鐘設(shè)置到合適的值。4.2.3 Init.s文件的編寫由于LPC2106微控制器的存儲系統(tǒng)比較簡單,所以系統(tǒng)初始化代碼也比較簡單,代碼如下:Reset BL InitS

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論