VxWorks中的中斷應用設計要點
硬件中斷處理是實時係統設計中的關鍵性問題,設計人員有必要對其作深入研究,以更好地滿足開發工作需要。文中以VxWorks操作係統為軟件平台,討論了在實時係統中進行中斷應用設計時要注意的一些問題。由於軟硬件的相關性,選用廣泛應用的X86架構的嵌入式汁算機為硬件平台,對PenriumCPU和計算機主板對硬件中斷的管理機製也做了詳細介紹 所得出的研究結論在具體的開發項目中均得以驗證,可供相關技術人員參考。硬件中斷處理是實時係統設計中最重要、最關鍵的問題。文中綜合軟硬件,從工程應用的角度對此問題加以討論。文中所述內容針對的軟件平台是VxWorks實時操作係統,硬件平台選用廣泛使用的X86架構的嵌入式計算機,全文按照CPU、主板、操作係統自下而上的順序展開。
1 Pentium CPU的中斷類型
有兩類事件可引起Pentium掛起當前的指令流,即中斷和異常。中斷是由外部事件引發的,在程序執行的任何時刻都可能出現;異常也稱異常中斷,是由內部事件引發的。中斷和異常各有兩類觸發源:
(1)中斷。
可屏蔽中斷:CPU的INTR引腳收到有效信號,如果Pentium標誌寄存器IF位為1,則允許中斷,否則信號在CPU內被屏蔽。
非屏蔽中斷:CPU的NMI引腳收到有效信號而引發的中斷,這類中斷不能被阻止。
(2)異常。
執行異常:CPU試圖執行一條指令的過程中出現錯誤、故障等不正常條件而引發的異常中斷。
執行軟件中斷指令:Pentium指令係統中包括一些如INTO,INT n這類軟件中斷指令,執行時產生異常中斷。
詳細分類的話,Pentium可以識別256種中斷和異常。每種中斷給予一個編號,即0~255,稱為中斷向量號(interrupt vector number)。其中NMI、異常以及係統保留占用中斷向量號0~31,而32~255為用戶中斷向量號,可供INTR和自定義軟件中斷(如匯編中的INT指令)使用。
2 Pentium CPU的中斷響應過程
中斷處理子程序的入口地址信息存於內存中的一個表內,實模式為中斷向量表IVT,保護模式為中斷描述符表IDT。中斷發生時,CPU首先通過某種方式獲得中斷向量號,再以中斷向量號檢索此表,即可獲取中斷服務子程序入口地址,詳述如下:
(1)實模式使用中斷向量表。
中斷向量表IVR的基地址由IDTR(中斷描述符寄存器)指定,大小為1kB。中斷響應時的查表過程與8086/8088一致,在此不再贅述。
(2)保護模式使用中斷描述符表。
中斷描述符表(IDT)的基地址也由IDTR指定,大小為2kB。中斷描述符表每一表項對應一個中斷向量號,但表項稱為中斷門描述符或陷阱門描述符。這些門描述符為8字節長,對應256個中斷向量號。以中斷向量號乘以8作為訪問IDT的偏移,讀取相應的中斷門/陷阱門描述符表項。門描述符給出中斷服務子程序人口地址(段:偏移),其中32位偏移量裝入EIP,16位的段值被裝入CS寄存器。但此段值是選擇符,CPU會自動查GDT或LDT取得代碼段描述符並送到相應的描述符寄存器中。
3 X86架構的計算機對外部中斷的管理
在嵌入式應用中,人們感興趣的主要是指由硬件信號觸發的非屏蔽中斷與可屏蔽中斷。在單CPU的X86計算機中,采用兩片8259級聯來管理16個可屏蔽外部中斷,由於主8259的IRQ2用於級聯,所以實際可用的IRQ隻有15個,其中又有一些被係統占用,這種邏輯如今已被集成在主板芯片組的南橋中,如圖1所示。由於傳統的PIC提供的中斷資源較少,現代PC開始采用APIC(高級可編程中斷控製器)管理外部中斷,它的一個顯著優點是能夠擴充係統可用的IRQ資源。文中問題的討論基於傳統的PIC結構。
圖1 外部中斷管理邏輯
4 在VxWorks中設計中斷應用
Vxworks運行在保護模式下。在Vxworks中,可以采用intConnect關聯中斷服務程序至某個中斷向量。然而intConnect並不是直接將用戶設計的ISR與中斷門描述符相關聯,而是對它加了一層封裝,然後將封裝代碼的內存首地址與中斷門描述符相關聯,中斷響應過程如圖2所示。采用intConnect為ISA總線設備關聯中斷服務程序IRQ—ISR至IRQ10的程序片斷如下:
- #define IRQNum 10 /*1*/
- ……
- /* 2,3 */
- if(intConneet((VOIDFUNCPTR)INUM_TO_IVEC(IRQNum+0x20),IRQ_ISR,0)==OK)
- {
- if(sysIntEnablePIC(IRQNum)==OK) /*4*/
- {
- print{("Succeeded.\n");
- }
- }
- void IRQ_ISR()
- {
- int intLockKey;
- intLockKey=intLock();/*5*/
- ……(critical section)
- intUnlock(intLocKey);
- }
圖2 中斷響應過程
程序要點詳述:
① X86架構的計算機中,一些中斷資源已經固定地分配給某些外部設備,如係統時鍾固定使用IRQ0,所以在選擇中斷號時首先應參考硬件手冊,避免與已用的中斷資源衝突。選定中斷號後,需要在BIOS中加以設置。避免BIOS在初始化時,把此中斷號作為可用資源分配給PCI設備,造成中斷衝突。以上是在開發ISA設備時要注意的,若開發PCI設備,一般不做上述考慮,因為BIOS可為PCI設備動態分配中斷資源,且多個PCI設備可共享一個中斷號,隻需從PCI配置頭中讀取分配到的中斷號使用即可。
② VxWorks中使用intConnect掛接中斷服務程序,但對於PCI設備,一般采用pciIntConnect掛接中斷,它與intConnect的主要不同在於intConnect使用的中斷向量是獨占的,而pciIntConnect則可使多個外部中斷共享一個中斷向量。它在內部使用一個鏈表管理多個ISR,發生中斷時,鏈接在一個鏈表上的各個ISR被依次調用,pciIntConnect要求每個ISR被調用時,應該首先查詢是否為自己的設備產生的中斷,不是則應立即返回,以繼續調用其它ISR。
③ 在VxWorks中要注意區分以下4個與中斷相關的概念:IRQNumber,INumber,IVector,ILevel。
- IRQNumber:外部中斷信號由兩片8259級聯構成的PIC的那個輸入管腳引入,主8259的8條中斷輸入線對應IRQ0~IRQ7,從8259對應IRQ8~IRQ15。
- INumber:Pentium CPU 的中斷向量號。INumber=IRQNumber+INT_NUM_IRQ0,INT_NUM_IRQ0,即IRQ0對應的中斷向量號,BSP的config.h中定義其為0x20(十進製的32),即Pentium CPU 中斷向量號用戶定義區的起始編號。
- IVector:中斷向量,是指某中斷的中斷描述符在中斷描述符表中的偏移量。INumber與IVector間的關係可簡單描述為:IVector=INumber*8。可以用ivi86.h中定義的兩個宏(INUM_TO_IVEC,IVEC_TO_INUM)實施轉換。
- ILevel:中斷優先級。由於主從8259都被初始化為固定優先級,優先級逐漸遞減,且兩片8259存在級聯關係,所以優先級關係為IRQ0 > IRQ1> IRQ2[IRQ8>IRQ9>…>IRQ15]>IRQ3>…>IRQ6>IRQ7。
表1列出了IRQ0~IRQ15對應的中斷向量號(INumber)與中斷向量(IVector)。
IRQNumber | INumber | IVector |
0 | 32 | 0x100 |
1 | 33 | 0x108 |
2 | 34 | 0x110 |
… | … | … |
15 | 47 | 0x178 |
⑤ 關鍵代碼段可用關中斷intLock和開中斷intUnlock加以保護。語句對intLock與intUnlock在不同的CPU體係架構中實現原理不同。在X86架構中,它們是通過操作EFLAGS中的IF位實現的。反匯編後可觀察它們的匯編形式代碼。
intLock的反匯編代碼:
_intLock: PUSHF /*將EFLAGS壓棧*/
_intLock: POP EAX
+0x002: AND EAX,0x200 /*隻保存感興趣的位IF*/
+0x007: CLI /*清IF位*/
+0x008: RET /*EAX作為返回值,即lock-out key */
intUnlock的反匯編代碼:
_intUnlock: MOV EAX,[ESP+4] /*將lock-out key作為參數傳給EAX */
+0x004: AND EAX,0x200 /*判封鎖中斷前IF位的狀態如何*/
+0x009: JE intUnlock0 /*若封鎖中斷前也是關中斷狀態,則不做操作*/
+0x011: STI /*若封鎖中斷前是開中斷狀態,則置IF位*/
intUnlock0: RET /*返回*/
注意不要在中斷閉鎖期間調用Vxworks係統函數,否則有可能意外打開中斷閉鎖,違反臨界代碼的設計意圖。intLock可以在ISR或通常的任務中使用,當在任務中使用時,關中斷並不會禁止任務調度,所以,若一個任務關中斷後,又發生了任務調度,則新任務的上下文將被恢複,而EFLAGS是任務上下文的一部分,所以IF位可能會發生變化,中斷屏蔽可能會被解除。為了在關中斷的同時禁止任務調度,可采用如下形式:
if(taskLock()==OK)
{
intLockKey= intLock();
…(critical section)
intUnlock(intLockKey);
taskUnlock();
}
以上介紹了設計中斷應用時在軟件方麵要注意的一些問題,再簡單說一下硬件中斷信號的提供。VxWorks中8259被初始化為上升沿觸發,值得注意的是,外部中斷信號 須保持為高電平直至第一個INTA信號的下降沿到來,否則會造成假中斷,觸發IRQ7的中斷服務程序,常用的硬件中斷信號形式是利用一個負脈衝的後沿(上升沿)。IRQ7是並口使用的中斷號,在調試過程中,可以在VxWorks中裁減掉並口模塊,在IRQ7上掛一個測試用的中斷服務程序,以觀察記錄假中斷。
5 結束語
文中結合工程實踐,以VXWorks與X86架構的嵌入式計算機為軟硬件平台,較深入地闡述了在實時係統中設計中斷應用時需要考慮的一些問題。由於篇幅所限,一些在其他資料中被廣泛提及的設計要點(如中斷服務程序不能調用可能會引起調用阻塞的函數)在此不作介紹。
最後更新:2017-04-03 12:56:27