天天看點

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)。

表1 中斷相關概念對照表

irqnumber

inumber

ivector

32

0x100

1

33

0x108

2

34

0x110

15

47

0x178

④ 用intconnect挂中斷後,還必須用sysintenablepic使能中斷,sysintenablepic的函數原型在i8259pic.c中定義,實際上就是針對某個irq,置8259中斷屏蔽寄存器中的相應位為允許。sysintenablepic中的基本操作是利用端口讀寫函數sysinbyte,sysoutbyte讀寫8259的中斷屏蔽寄存器。sysinbyte,sysoutbyte的函數原型在sysalib.s中定義。

⑤ 關鍵代碼段可用關中斷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架構的嵌入式計算機為軟硬體平台,較深入地闡述了在實時系統中設計中斷應用時需要考慮的一些問題。由于篇幅所限,一些在其他資料中被廣泛提及的設計要點(如中斷服務程式不能調用可能會引起調用阻塞的函數)在此不作介紹。