




已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
ARM 啟動代碼詳解(Vectors.c、Init.s、Target.c、 Target.h)2010-05-15 16:03啟動代碼是芯片復(fù)位后進入C語言的main()函數(shù)前執(zhí)行的一段代碼,主要是為運行C語言程序提供基本運行環(huán)境,如初始化存儲器系統(tǒng)等。ARM公司只設(shè)計內(nèi)核,不自己生產(chǎn)芯片,只是把內(nèi)核授權(quán)給其它廠商,其它廠商購買了授權(quán)且加入自己的外設(shè)后生產(chǎn)出各具特色的芯片。這樣就促進了基于ARM處理器核的芯片多元化,但也使得每一種芯片的啟動代碼差別很大,不易編寫出統(tǒng)一的啟動代碼。ADS(針對ARM處理器核的C語言編譯器)的策略是不提供完整的啟動代碼,啟動代碼不足部分或者由廠商提供,或者自己編寫。啟動代碼劃分為4個文件: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)板初始化程序。這樣做的目的是為了盡量減少匯編代碼,同時把不需要修改的代碼獨立出來以減少錯誤。 4.2.1 Vectors.c文件的編寫4.2.1.1 中斷向量表Vectors LDR PC, ResetAddr LDR PC, UndefinedAddr LDR PC, SWI_Addr LDR PC, PrefetchAddr LDR PC, DataAbortAddr DCD 0xb9205f80 LDR PC, PC, #-0xff0 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異常是由內(nèi)部或外部源產(chǎn)生的以引起處理器處理的一個事件。ARM處理器核支持7種類型的異常。異常出現(xiàn)后,CPU強制從異常類型對應(yīng)的固定存儲地址開始執(zhí)行程序。這個固定的地址就是異常向量。向量從上到下依次為復(fù)位、未定義指令異常、軟件中斷、預(yù)取指令中止、預(yù)取數(shù)據(jù)中止、保留的異常、IRQ和 FIQ。IRQ向量“LDR PC, PC, #-0xff0” 使用的指令與其它向量不同。在正常情況下這條指令所在地址為0X00000018。當(dāng)CPU執(zhí)行這條指令但還沒有跳轉(zhuǎn)時,PC的值為0X00000020,0X00000020減去 0X00000FF0為 0XFFFFF030,這是向量中斷控制器(VIC)的特殊寄存器VICVectAddr。這個寄存器保存當(dāng)前將要服務(wù)的IRQ的中斷服務(wù)程序的入口,用這一條指令就可以直接跳轉(zhuǎn)到需要的中斷服務(wù)程序中。至于在保留的異常向量“DCD 0xb9205f80”位置填數(shù)據(jù)0xb9205f8是為了使向量表中所有的數(shù)據(jù)32位累加和為0。4.2.1.2 初始化CPU堆棧InitStack MOV R0, LR MSR CPSR_c, #0xd2 ;設(shè)置中斷模式堆棧 LDR SP, StackIrq MSR CPSR_c, #0xd1 ;設(shè)置快速中斷模式堆棧 LDR SP, StackFiq MSR CPSR_c, #0xd7 ;設(shè)置中止模式堆棧 LDR SP, StackAbt MSR CPSR_c, #0xdb ;設(shè)置未定義模式堆棧 LDR SP, StackUnd MSR CPSR_c, #0xdf ;設(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)StackSys DCD (SysStackSpace + SYS_STACK_LEGTH * 4 -4 );/* 分配堆棧空間 */ 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 SYS_STACK_LEGTH * 4 ; 系統(tǒng)模式堆棧因為程序需要切換模式,而且程序退出時CPU的模式已經(jīng)不再是管理模式而是系統(tǒng)模式LR已經(jīng)不再保存返回程序地址,所以程序首先把返回地址保存到 R0中,同時使用R0返回。然后程序把處理器模式轉(zhuǎn)化為IRQ模式,并設(shè)置IRQ模式的堆棧指針。其中變量Stacklrq保存著IRQ模式的堆棧指針的初始值,Irqstackspace是分配給 IRQ模式的堆棧空間的開始地址,IRQ_STACK_LEGTH是用戶定義的常量,用于設(shè)置 IRQ模式的堆??臻g的大小。程序使用同樣的方法設(shè)置FIQ模式堆棧指針、中止模式堆棧指針、未定義堆棧指針和系統(tǒng)模式堆棧指針。程序使用編譯器分配的空間作為堆棧,而不是按照通常的做法把堆棧分配到 RAM的頂端,之所以這樣是因為這樣做不必知道RAM頂端位置,移植更加方便;編譯器給出的占用RAM空間的大小就是實際占用的大小,便于控制RAM的分配。對于 LPC2106來說,中止模式是不需要分配堆??臻g的,這是因為 LPC2106沒有外部總線,也沒有虛擬內(nèi)存機制,如果出現(xiàn)取數(shù)據(jù)中止或取指令中止肯定是程序有問題。而一般情況下也不需要模擬協(xié)處理器指令或擴充指令,未定義中止也就意味著程序有錯誤,也不需要分配堆棧空間。4.2.1.3 異常處理代碼與C語言的接口程序C/OS-中斷服務(wù)子程序流程圖如圖4-1所示:圖4-1 中斷服務(wù)子程序流程圖異常處理代碼與C語言的接口程序如下:MACRO$IRQ_Label HANDLER $IRQ_Exception EXPORT $IRQ_Label ;輸出的標(biāo)號 IMPORT $IRQ_Exception ;引用的外部標(biāo)號$IRQ_Label SUB LR, LR, #4 ;計算返回地址 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 ;調(diào)用c語言的中斷處理程序 MSR CPSR_c, #0x92 ;關(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 ;不進行任務(wù)切換 LDR PC, =OSIntCtxSw ;進行任務(wù)切換 MENDUndefined ;未定義指令 b UndefinedPrefetchAbort ;取指令中止 b PrefetchAbortDataAbort ;取數(shù)據(jù)中止 b DataAbortIRQ_Handler HANDLER IRQ_Exception ;中斷FIQ_Handler ;快速中斷 b FIQ_HandlerTimer0_Handler HANDLER Timer0 ;定時器0中斷未定義指令異常、取指令中止異常、取數(shù)據(jù)中止異常均是死循環(huán),其中原因在上一小節(jié)已經(jīng)說明。而快速中斷在本應(yīng)用中并未使用,所以也設(shè)置為死循環(huán)。LPC2106使用向量中斷控制器,各個 IRQ中斷的人口不一樣,所以使用了一個宏來簡化中斷服務(wù)程序與C語言的接口編寫。由ARM處理器核的文檔可知,處理器進入IRQ中斷服務(wù)程序時(LR4)的值為中斷返回地址,為了使任務(wù)無論在主動放棄CPU時還是中斷時堆棧結(jié)構(gòu)都一樣,在這里先把LR減4。其它的部分與C/OS-要求的基本一致。ARM處理核在進入中斷服務(wù)程序時處理器模式變?yōu)镮RQ模式,與任務(wù)的模式不同,它們的堆棧指針SP也不一樣,而寄存器應(yīng)當(dāng)保存到用戶的堆棧中,為了減少不必要的CPU時間和RAM空間的浪費,本移植僅在必要時將處理器的寄存器保存到用戶的堆棧中,其它時候還是保存到IRQ模式的堆棧中。同時,從編譯器的函數(shù)調(diào)用規(guī)范可知,C語言函數(shù)返回時,寄存器R4R11、SP不會改變,所以只需要保存CPSR、R0R3、R12和返回地址LR,在后面保存 CPSR是為了必要時將寄存器保存到用戶堆棧比較方便。在異常處理代碼與C語言的接口程序中沒有與中斷服務(wù)子程序流程圖中的判斷語句對應(yīng)的語句。判斷語句是為了避免在函數(shù)OSIntCtxsw()調(diào)整堆棧指針,這個調(diào)整量是與編譯器、編譯器選項、C/OS -配置選項都相關(guān)的變量。在這里進行這些處理相對其它處理器結(jié)構(gòu)可能增加的處理器時間很少,但對于ARM來說,由于中斷(IRQ)有獨立的堆棧,在這里這樣做就需要把所有寄存器從中斷的堆棧拷貝到任務(wù)的堆棧,需要花費比較多的額外時間。而變量OSIntNesting為0時,并不一定會進行任務(wù)切換,所以本移植沒有與之對應(yīng)的程序,而在函數(shù)OSIntCtxsw()中做這一項工作。這樣,僅在需要時才處理這些事物,程序效率得以提高。在中斷調(diào)用后,如果需要任務(wù)切換,則變量OSTCBHighRdy和變量OSTCBCur的值不同;如果不需要任務(wù)切換這兩個變量則相同。本移植通過判斷這兩個變量來決定是進行任務(wù)切換,還是不進行任務(wù)切換。通過比較,如果需要任務(wù)切換則執(zhí)行“LDR PC, =OSIntCtxSw”跳轉(zhuǎn)到OSIntCtxSw處進行任務(wù)切換;如果不需要任務(wù)切換則執(zhí)行“LDMEQFD SP!, R0-R3, R12, PC”中斷返回。這里需要對“MSR CPSR_c, #0x92”說明下,這條指令的作用是關(guān)IRQ中斷。因為中斷(IRQ)模式的LR寄存器在處理器響應(yīng)中斷時用于保存中斷返回地址,所以在處理器響應(yīng)中斷時中斷(IRQ)模式的LR寄存器不能保存有效數(shù)據(jù)。而BL指令要用LR寄存器保存BL下一條指令的位置,所以在中斷(IRQ)模式時,在BL指令之前必須關(guān)中斷,在保存LR后才能開中斷。4.2.2 Target.c文件的編寫為了使系統(tǒng)基本能夠工作,必須在進人 main()函數(shù)前對系統(tǒng)進行一些基本的初始化工作,這些工作由函數(shù)TargetResetInit()完成。void TargetResetInit(void) uint32 i; uint32 *cp1; uint32 *cp2; extern void Vectors(void) ; /* 拷貝向量表,保證在flash和ram中程序均可正確運行 */ cp1 = (uint32 *)Vectors; cp2 = (uint32 *)0x40000000; for (i = 0; i 2 * 8; i+) *cp2+ = *cp1+; MEMMAP = 0x2;PINSEL0 = (PINSEL0 & 0xFFFF0000) | UART0_PCB_PINSEL_CFG | 0x50;PLLCON = 1; /* 設(shè)置系統(tǒng)各部分時鐘 */ VPBDIV = 0; PLLCFG =0x23; PLLFEED = 0xaa; PLLFEED = 0x55; while(PLLSTAT & (1 10) = = 0) ; PLLCON = 3; PLLFEED = 0xaa; PLLFEED = 0x55; MAMCR = 2; /* 設(shè)置存儲器加速模塊 */#if Fcclk 20000000 MAMTIM = 1;#else#if Fcclk 40000000 MAMTIM = 2;#else MAMTIM = 3;#endif#endif首先向量表拷貝到RAM底部,加上這部分是為了代碼無論從Flash基地址開始編譯還是從RAM基地址開始編譯程序均運行正確。而把RAM底部映射到向量表“MEMMAP = 0x2”也是為了同一個目的。至于復(fù)制16個字而不是8個字,是因為后8個字存儲跳轉(zhuǎn)的地址是通過 PC指針間接尋址的,它們與對應(yīng)指令(在向量表中)相對位置是不能變化的。因為在進入多任務(wù)環(huán)境前使用了一些外設(shè),部分外設(shè)使用了芯片的引腳,而 LPC2106的所有引腳都是多功能的,所以需要設(shè)置引腳功能。同時串口也進行了設(shè)置。時鐘是芯片各部分正常工作的基礎(chǔ),雖然時鐘可以在任何時候設(shè)置,但為了避免混亂,最好在進入 main()函數(shù)前設(shè)置。程序首先使能PLL但不連接PLL,然后設(shè)置外設(shè)時鐘(VPB時鐘pclk)與系統(tǒng)時鐘(cclk)的分頻比。接著設(shè)置PLL的乘因子和除因子。設(shè)置完成后,使用“PLLFEED = 0xaa; PLLFEED = 0x55;”的訪問序列把數(shù)據(jù)正確寫人硬件,并等待PLL跟蹤完成。最后,使能PLL,并使PLL聯(lián)上系統(tǒng)。本應(yīng)用外接的晶振頻率(Fosc)為11.0592MHz,倍增器的值M=4,所以處理器時鐘(Fcclk)為44.2368 MHz。為了使電流控制振蕩器頻率(Fcco)滿足156-320MHz,所以分頻器的值P=2,使
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公寓按揭貸款管理辦法
- 青椒計劃項目實施效果評估與個人貢獻總結(jié)報告
- 豎爐氫冶金工藝在低碳環(huán)保鋼鐵生產(chǎn)中的應(yīng)用探索
- 標(biāo)桿企業(yè)指標(biāo)管理辦法
- 理財教育大眾化傳播模式與內(nèi)容創(chuàng)新研究
- 全基因組關(guān)聯(lián)分析在小麥抗旱性狀研究中的應(yīng)用
- 《公共圖書館法》分析:結(jié)構(gòu)特點、生成邏輯與優(yōu)化策略
- 廚房高檔原料管理辦法
- 橋梁安全等級劃分標(biāo)準(zhǔn)
- 發(fā)票管理辦法追訴時限
- 保安培訓(xùn)課程表(完整版)咨詢培訓(xùn)
- 《飛機電子顯示器顯示符號》
- 贏利:未來10年的經(jīng)營能力
- 光伏支架風(fēng)荷載分析
- 頭等大事:脫發(fā)青年自救指南
- 馬拉色菌相關(guān)疾病診療指南(2022年版)
- 哈雷之約:基于指數(shù)成分股調(diào)整的選股策略
- 湖北省隨州市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會明細及行政區(qū)劃代碼
- 磁流體密封課件
- T∕CCIA 001-2022 面向網(wǎng)絡(luò)安全保險的風(fēng)險評估指引
- 高處作業(yè)審批表
評論
0/150
提交評論