版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、uC/OS-II官網(wǎng)給出來的ARM7-ARM9移植手冊(AN-104),分析了在ARM中移植的問題,想想從來沒有認真的學(xué)習(xí)過ARM的匯編,趁著這個機會復(fù)習(xí)復(fù)習(xí)吧。其實底層的東西才是創(chuàng)造力的心臟。其中的移植代碼中存在的很多問題比如中斷的關(guān)閉和開啟,任務(wù)級別的情景切換,中斷到任務(wù)的情景切換都是我們在平時移植中講到,我也不在此強調(diào)了。在官網(wǎng)中提供的移植過程中存在異常處理機制,這個本不是在移植過程中考慮的,但是文檔中確實提供了一個比較好的處理方式。我在此對這一段時間的學(xué)習(xí)做一個總結(jié)。首先需要了解ARM的異常處理機制,異常是每一種處理器都必須考慮的問題之一,關(guān)鍵在于如何讓處理,返回地址在什么位置都是需要
2、考慮的,ARM中支持7種異常,其中包括復(fù)位、未定義指令異常、軟中斷異常、預(yù)取指令中止、數(shù)據(jù)中止、IRQ、IFQ。每一種異常運行在特定的處理器模式下。我在此逐一的分析。一般異常發(fā)生后,CPU都會進行一系列的操作,這些操作有一部分是CPU自動完成,有一部分是需要我們程序員完成。首先說明CPU會自動完成的部分,用ARM結(jié)構(gòu)手冊中的代碼描述如下:R14_<exception_mode> = return link
3、 /這個可以參看寄存器的說明,兩個作用SPSR_< exception_mode > = CPSRCPSR4:0 = exception mode numberCPSR5 = 0 /AEM指令I(lǐng)f <exception_mode>=Reset or Fiq then &
4、#160; /只有在復(fù)位和FIQ模式下才會關(guān)閉FIQ中斷CPSR6 = 1 CPSR7 = 1 /任何異常模式下都會關(guān)閉IRQ中斷PC = exception vector address從上面的代碼中我們可以發(fā)現(xiàn)CPU自
5、動處理的過程包括如下:1、 拷貝CPSR到SPSR_<mode>2、 設(shè)置適當?shù)腃PSR位: 改變處理器狀態(tài)進入ARM狀態(tài);改變處理器模式進入相應(yīng)的異常模式;設(shè)置中斷禁止位禁止相應(yīng)中斷。3、 更新LR_<mode>,這個寄存器中保存的是異常返回時的鏈接地址4、 設(shè)置PC到相應(yīng)的異常向量以上的操作都是CPU自動完成,異常的向量表如下:返回地址問題異常的返回地址也是需要我們注意的地方,不同的異常模式返回地址也是存在差異的,這主要是因為各種異常產(chǎn)生的機理存在差別所導(dǎo)致的。這樣我們
6、的需要在異常進入處理函數(shù)之前或者在返回時調(diào)整返回地址,一般采用進入異常處理函數(shù)前進行手動調(diào)整。下面每一種異常R14保存的值都給了出來,其中也包含了CPU自動處理的部分,根據(jù)保存的R14就可以知道怎樣實現(xiàn)地址的返回。復(fù)位異常:可以看出該模式下的先對來說返回地址也比較簡單,不需要做太多的描述。未定義的指令異常:返回的方式也比較簡單: MOVS PC, R14軟中斷異常:返回的方式也比較簡單: MOVS &
7、#160;PC, R14預(yù)取指令中止異常:返回需要做下面的調(diào)整:SUBS PC, R14, #4數(shù)據(jù)中止返回地址需要做下面的調(diào)整:如果需要重新訪問數(shù)據(jù)則:SUBS PC, R14, #8如果不需要重新訪問數(shù)據(jù)則:SUBS PC, R14, #4IRQ中斷的處理過程:返回地址需要做下面的調(diào)整: SUBS PC
8、,R14,#4IFQ中斷:返回地址需要做下面的調(diào)整: SUBS PC, R14 ,#4從上面的代碼可以知道,對于每一種異常,保存的返回地址都是不一樣的,一般都需要我們手動的跳轉(zhuǎn),當然調(diào)整的時機也需要我們選擇,是在進入處理前跳轉(zhuǎn)還是返回時調(diào)整都是需要我們程序員控制的。在ARM Developer Suite Developer Guide中對ARM處理器的異常處理操作提供能更加詳細的解釋,每一種異常下的處理方式如下文描述:異常返回時另一個非常重要的問題是返回地址的確定,在前面曾提到進入異常時處
9、理器會有一個保存LR 的動作,但是該保存值并不一定是正確的返回地址,下面以一個簡單的指令執(zhí)行流水狀態(tài)圖來對此加以說明。我們知道在ARM 架構(gòu)里,PC值指向當前執(zhí)行指令的地址加8處,也就是說, 當執(zhí)行指令A(yù)(地址0x8000)時,PC 等于指令C 的地址(0x8008)。假如指令A(yù) 是“BL”指令,則當執(zhí)行該指令時,會把PC(=0x8008)保存到LR 寄存器里面,但是接下去處理器會馬上對LR 進行一個自動的調(diào)整動作:LR=LR-0x4。這樣,最終保存在 LR 里面的是 B 指
10、令的地址,所以當從 BL 返回時,LR里面正好是正確的返回地址。同樣的調(diào)整機制在所有LR自動保存操作中都存在,比如進入中斷響應(yīng)時,處理器所做的LR 保存中,也進行了一次自動調(diào)整,并且調(diào)整動作都是LR=LR-0x4。下面,我們對不同類型的異常的返回地址依次進行說明:假設(shè)在指令A(yù) 處(地址0x8000)發(fā)生了異常,進入異常響應(yīng)后,LR 上經(jīng)過調(diào)整保存的地址值應(yīng)該是B 的地址0x8004。1、 如果發(fā)生的是軟件中斷,即A 是“SWI”指令異常是由指令本身引起的,從 SWI 中斷返回后下一條執(zhí)行指令就是
11、B,正好是LR 寄存器保存的地址, 所以只要直接把LR 恢復(fù)給PC。MOVS pc, lr2、 發(fā)生的是Undefined instruction異常異常是由指令本身引起的,從異常返回后下一條執(zhí)行指令就是B,正好是LR 寄存器保存的地址, 所以只要直接把LR 恢復(fù)給PC。MOVS pc, lr3、 發(fā)生的是IRQ或FIQ中斷因為指令不可能被中斷打斷,所以A指令執(zhí)行完以后才能響應(yīng)中斷,此時PC已更新,指向指令D的地址(地址0x800C),LR 上經(jīng)過調(diào)整保存的地址值是C 的地址0x8008。中斷返
12、回后應(yīng)該執(zhí)行B指令,所以返回操作是:SUBS pc, lr, #44、 發(fā)生的是Prefetch Abort異常該異常并不是處理器試圖從一個非法地址取指令時觸發(fā),取出的指令只是被標記為非法,按正常處理流程放在流水線上,在執(zhí)行階段觸發(fā)Prefetch Abort異常,此時LR 上經(jīng)過調(diào)整保存的地址值是B 的地址0x8004。異常返回應(yīng)該返回到A指令,嘗試重新取指令,所以返回操作是:SUBS pc, lr, #45、 發(fā)生的是“Data Abort”CPU訪問存儲器時觸發(fā)該異常,此時PC指向指令D的地址(地址0x800C),LR 上經(jīng)過調(diào)整保存的地
13、址值是C 的地址0x8008。異常返回后,應(yīng)回到指令A(yù),嘗試重新操作存儲器,所以返回操作是:SUBS pc, lr, #8以上就是ARM異常的CPU操作部分,接下來就是程序員應(yīng)該完成的操作。1. 由于CPU會自動跳轉(zhuǎn)到對應(yīng)的異常向量中,因此只需要在在各個異常向量中存放對應(yīng)的操作,最簡單的都是存放一個B指令跳轉(zhuǎn)到對應(yīng)的異常處理函數(shù)的操作即可。但由于B指令的跳轉(zhuǎn)返回只有+-32M,而異常處理函數(shù)的地址可能會超過+-32M,因此可以采用另一種方式實現(xiàn)方式:在異常向量中保存一條指令LDR
14、 PC addr,其中的addr中就保存了異常處理函數(shù)的地址,當然addr的相對地址要小于+-32M。這樣也就解決了跳轉(zhuǎn)范圍的問題。2. 接下來就是異常處理函數(shù)對應(yīng)的操作,可以在進入異常處理之前就進行返回地址的調(diào)整,這樣后面就不用進行處理啦,當然也可以在返回過程中再調(diào)整。一般都是在這個過程中進行調(diào)整。進行壓棧操作,保存對應(yīng)的環(huán)境變量。調(diào)用實際的處理過程等。3. 出棧,恢復(fù)CPU的狀態(tài)和
15、寄存器的值。由于第一步中已經(jīng)調(diào)整好返回地址,這一步不需要再次調(diào)整。當然如果之前沒有調(diào)整,這里則需要進行相應(yīng)的調(diào)整。在uC/OS-II的官網(wǎng)移植中采用通用異常處理函數(shù)的方式實現(xiàn)異常的處理,下面我們來分析其中的部分代碼:首先是處理器部分的移植,包括異常向量、異常的ID號,存儲異常處理函數(shù)地址的地址等:/*ARM的異常ID號,支持7種類型的異常,每一種異常都存在一個ID號*/#define OS_CPU_ARM_EXCEPT_RESET 0x00#define O
16、S_CPU_ARM_EXCEPT_UNDEF_INSTR 0x01#define OS_CPU_ARM_EXCEPT_SWI 0x02#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT 0x03#define OS_CPU_ARM_EXCEPT_DATA_ABORT 0x04#define OS_CPU_
17、ARM_EXCEPT_ADDR_ABORT 0x05#define OS_CPU_ARM_EXCEPT_IRQ 0x06#define OS_CPU_ARM_EXCEPT_FIQ
18、; 0x07#define OS_CPU_ARM_EXCEPT_NBR 0x08/*異常向量地址*/#define OS_CPU_ARM_EXCEPT_RESET_VECT_ADDR (OS
19、_CPU_ARM_EXCEPT_RESET * 0x04 + 0x00) /0x00#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INS
20、TR * 0x04 + 0x00) /0x04#define OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR (OS_CPU_ARM_EXCEPT_SWI
21、60; * 0x04 + 0x00) /0x08#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x00) &
22、#160; /0x0c#define OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x00)
23、0; /0x10/*這個異常是ARM中不支持的異常*/#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x00)
24、 /0x14#define OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR
25、; (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x00) /0x18#define
26、; OS_CPU_ARM_EXCEPT_FIQ_VECT_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x00)
27、0; /0x1c/*存儲異常處理函數(shù)地址的地址*/* ARM exception handlers addresses */#define OS_CPU_ARM_EXCEPT_RESET_HANDLER_ADDR
28、; (OS_CPU_ARM_EXCEPT_RESET * 0x04 + 0x20)
29、60; /0x20#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INSTR * 0x04 + 0x20) /0x24#define OS_CPU_ARM_EXCEPT_SWI_HAN
30、DLER_ADDR (OS_CPU_ARM_EXCEPT_SWI * 0x04 + 0x20) /0x28#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_
31、HANDLER_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x20) /0x2c#define OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x20)
32、 /0x30#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x20) /0x34#define
33、 OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x20) /0
34、x38#define OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x20)
35、0; /0x3c/*存儲在異常向量中的內(nèi)容,實質(zhì)上是LDR PC,PC,#0x18的機器碼*/#define OS_CPU_ARM_INSTR_JUMP_TO_SELF 0xEAFFFFFE/* ARM "Jump To Exception Handler" asm instruction */#define O
36、S_CPU_ARM_INSTR_JUMP_TO_HANDLER 0xE59FF018異常的初始化函數(shù),首先,完成了在異常向量中存儲指令的操作,采用機器碼的形式就能避免直接訪問寄存器什么的,其次,完成在固定的地址處存放對應(yīng)異常處理函數(shù)的地址。其中采用了賦值的形式也是需要注意的,采用的強制類型轉(zhuǎn)換和指針相結(jié)合的形式。保證了是修改地址處的內(nèi)容。而不是修改地址。/*初始化異常中斷向量*/void OS_CPU_InitExceptVect (void)
37、 /* OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR是對應(yīng)中斷向量表的地址
38、160; OS_CPU_ARM_INSTR_JUMP_TO_HANDLER是保存了對應(yīng)的OS_CPU_ARM_INSTR_JUMP_TO_HANDLER(實質(zhì)上是一個指令) 實質(zhì)上就是在異常向量中存放了:LDR PC PC, #0x18,也就是讓PC指向?qū)?yīng)的異常處理地址中的內(nèi)容,
39、; 也就是實現(xiàn)到實際處理函數(shù)的跳轉(zhuǎn)。 異常處理地址中存儲了實際的異常處理函數(shù)的地址
40、60; 其他的異常也有相同的操作,OS_CPU_ARM_INSTR_JUMP_TO_HANDLER是一個指令的機器碼形式 */ (*(IN
41、T32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; (*(INT32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR) = (INT32U)OS_CPU_ARM
42、_ExceptUndefInstrHndlr; (*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; (
43、*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptSwiHndlr; (*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR) =
44、 OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; (*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptPrefetchAbortHndlr; (*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR)
45、60; = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; (*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptDataAbortHndlr; (*(INT32U *)OS_CPU_ARM_
46、EXCEPT_ADDR_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; (*(INT32U *)OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptA
47、ddrAbortHndlr; (*(INT32U *)OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; (*(INT32U
48、*)OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptIrqHndlr; /*在異常向量中存儲對應(yīng)的操作,實質(zhì)上就是將PC值調(diào)轉(zhuǎn)*/ (*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_VECT_ADD
49、R) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER; (*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR) &
50、#160; = (INT32U)OS_CPU_ARM_ExceptFiqHndlr; 異常類型Mode異常向量內(nèi)容IRQ異常IRQ0x00000018LDR PC,PC,#0x18或者0xE59FF018IFQ異常IFQ0x0000001CLDR PC,PC,#0x180xE59FF018 0x00000038Address of OS_CPU_ARM_ExceptIrqHndlr() 0x0000003CAddress of OS_CPU_ARM_ExceptFiqHndlr()有必要的討論一下,為什么在
51、向量中存儲的是指令: LDR PC,PC,#0x18,我們從上面的地址可以知道,IRQ異常處理函數(shù)地址被存儲到了0x00000038中,異常向量與該地址之間的差值是0x20,那么為什么在其中存儲的值只是0x18呢?這還要討論ARM的流水線結(jié)構(gòu),當前執(zhí)行的命令相比PC指向的地址差0x08。也就是當前執(zhí)行的指令的地址是PC-0x08.當PC指向異常向量以后(取值),還需要等待一個時鐘(譯碼)之后才會被執(zhí)行(真正意義上的執(zhí)行操作),而這時PC值已經(jīng)被更新了。指向了Vector+0x8的位置,因此我們可以知道,當執(zhí)行向量中的代碼時,這時PC=Vector+0x8,而這時相對于固定的0x20-0x08=
52、0x18,這也就是為什么是LDR PC,PC,#0x18,而不是LDR PC,PC,#0x20.采用上面的例子說明IRQ的向量為0x00000018,而設(shè)定好的固定地址用來存儲對應(yīng)異常處理函數(shù)地址的地址是0x00000038,當CPU執(zhí)行完P(guān)C = 0x00000018以后,還需要譯碼、才能被執(zhí)行,這時候PC值已經(jīng)更新為PC = 0x00000018 + 0x08;這時候固定地址距離PC的相對位置位0x00000038 PC = 0x18,而該地址中保存了IRQ中斷的通用處理函數(shù)OS_CPU_ARM_ExceptIrqHndlr()的地址,LDR PC,PC,#0x18這條指令是指將PC+0x18地址處的內(nèi)容加載到PC中,實質(zhì)上也就完成跳轉(zhuǎn)到異常處理函數(shù)的操作。這樣處理的好處是因為LDR的加載范圍是一個固定值+-32M,我們不能保證異常處理程序的地址剛好在+-32M左右,采用這種LDR PC, ADDR(固定地址)的形式就能實現(xiàn)大范圍的跳轉(zhuǎn)操作。 我們僅僅以FIQ中斷處理的形式進行討論,其他的異常有一定的相似性,只是在返回地址上存在差別。這段代碼主要是完成寄存器
溫馨提示
- 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)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度生態(tài)旅游場承包經(jīng)營合作協(xié)議范本4篇
- 2025年度大棚農(nóng)業(yè)保險合作協(xié)議3篇
- 二手房交易標準協(xié)議樣本(2024個人版)版
- 2025年度叉車租賃與租賃物租賃期限調(diào)整合同4篇
- 2025年昌月離婚協(xié)議書婚姻解除及財產(chǎn)清算范本4篇
- 2025年度航空航天材料質(zhì)量保證協(xié)議4篇
- 2024年重慶地區(qū)標準離婚合同模板一
- 2024私募股權(quán)投資居間協(xié)議
- 專項舞臺效果策劃與實施協(xié)議版A版
- 2024年食堂運營合作協(xié)議標準文本版
- 考級代理合同范文大全
- 2024解析:第三章物態(tài)變化-講核心(原卷版)
- DB32T 1590-2010 鋼管塑料大棚(單體)通 用技術(shù)要求
- 安全行車知識培訓(xùn)
- 2024年安徽省高校分類對口招生考試數(shù)學(xué)試卷真題
- 第12講 語態(tài)一般現(xiàn)在時、一般過去時、一般將來時(原卷版)
- 2024年采購員年終總結(jié)
- 2024年新疆區(qū)公務(wù)員錄用考試《行測》試題及答案解析
- 肺動脈高壓的護理查房課件
- 2025屆北京巿通州區(qū)英語高三上期末綜合測試試題含解析
- 公婆贈予兒媳婦的房產(chǎn)協(xié)議書(2篇)
評論
0/150
提交評論