單 寅,夏偉杰
(南京航空航天大學電子信息工程學院,江蘇南京 210016)
VxWorks作為目前較為主流的嵌入式操作系統,被廣泛運用于航空與控制等方面,基于某型號飛機的虛擬儀表的GPU板卡,采用VxWorks作為頂層控制,其中采用中斷機制與外界通信是一個重要手段,由于硬件環境為Virtex5 FXT型號的FPGA,CPU為IBM公司Powerpc440x5處理器,理解其特有的架構,并編寫相應的中斷處理程序,對于操作系統的完整移植以及上層程序的正常運行至關重要。
FPGA內嵌的IBM PPC440處理器有兩個中斷引腳,一個關鍵異常引腳與一個外部中斷引腳。在構建嵌入式系統時共有兩種處理中斷的方式:(1)外部中斷直接引入外部中斷引腳。(2)為能處理較多的中斷,引入一個外擴的中斷處理器XINTC,中斷處理器連接PPC440外部中斷引腳,中斷控制器共可處理共32個優先級的中斷,從0號中斷開始優先級逐次降低。
中斷控制器由中斷核和總線接口組成,中斷核可與響應的邏輯接口總線配合,掛接在PLB總線上。圖1為中斷控制器(INTC)響應中斷的原理圖。通過PLB總線下INTC Interface向寄存器寫值,使能相應中斷位。連接在INTC的中斷源產生中斷信號Intr,被INTC檢測到后,因為寄存器相應中斷位被使能,就會產生Irq信號給PPC440外部中斷引腳[1]。
中斷控制器主要有幾個重要的寄存器,如圖1所示,Interrupt Status Register(ISR),Interrupt Enable Register(IER),Master Enable Register(MER)。MER是一個可讀寫寄存器,向MER寫1才能允許向外輸出Irq信號。ISR是一個32位只讀寄存器,相應位為1代表相應的中斷被使能。IER是個32位的可讀寫寄存器,向相應位寫1可以將ISR相應位置1。

圖1 中斷控制器原理框圖
中斷驅動實際上是在內存中構造一個中斷向量表,中斷控制器的數據結構如下:
typedef struct{
u16 DeviceId;/**中斷控制器對應的設備號*/
u32 BaseAddress;/**中斷控制器基地址*/
u32 AckBeforeService;/**讀取ISR寄存器的值以判斷正在觸發的中斷號*/
u32 Options;/**中斷控制器配置*/
XIntc_VectorTableEntry HandlerTable[XPAR_INTC_MAX_NUM_INTR_INPUTS];
}XIntc_Config
HandlerTable[XPAR_INTC_MAX_NUM_INTR_INPUTS]這一結構體數組即為中斷向量表,宏XPAR_INTC_MAX_NUM_INTR_INPUTS為系統中所有中斷的總數。
在Xilinx提供的BSP中,底層操縱中斷控制器的驅動函數為XIntc_Connect和XIntc_Enable,即IntConnect與 IntEnable函數具體實現是 XIntc_Connect與XIntc_Enable,void XIntc_Enable(XIntc* InstancePtr,u8 Id),InstancePtr是中斷控制器的地址,Id是想要使能的中斷號
……
Mask=XIntc_BitPosMask[Id];
CurrentIER=XIntc_In32(InstancePtr- >BaseAddress+XIN_IER_OFFSET);
XIntc_Out32(InstancePtr- >BaseAddress+XIN_IER_OFFSET,
(CurrentIER|Mask));
通過此操作,給IER寄存器相應位寫1,使能相應中斷。int XIntc_Connect(XIntc* InstancePtr,u8 Id,XInterruptHandler Handler,void*CallBackRef),Handler是用戶自己的中斷服務程序,可以是任何操作,CallbackRef是要傳遞給服務程序的參數。
……
InstancePtr- >CfgPtr- >HandlerTable[Id].Handler=Handler;
InstancePtr- >CfgPtr- >HandlerTable[Id].CallBackRef=CallBackRef;
由此根據中斷號Id將參數與程序放入中斷注冊表中。在BSP的sysInterrupt.c文件中,將這兩個函數封裝在IntConnect與IntEnable內,提高了程序的可移植性。
Powerpc440處理器是一個32位精簡指令集的CPU,與異常處理相關的寄存器有IVOR0~IVOR15,這16個寄存器用于存儲異常向量入口的偏移地址,其中IVOR4對應的是外部異常,也就是文中所關心的異常。SRR0和SRR1用于保存和恢復機器狀態。MSR是機器狀態寄存器,用于指示處理器的狀態[2]。
圖2為機器狀態寄存器(MSR)示意圖。CE為關鍵異常位,EE為外部異常位。這里主要關注的是EE,通過將EE位置1,可以使能外部中斷異常。通過查看Powerpc匯編指令集,對MSR寄存器操作的指令為mtmsr和mfmsr,其中mtmsr為讀出MSR中內容,mfmsr為向MSR寫入內容。在系統開始時初始化異常向量表,首先應將對應的異常向量裝入儲存異常向量入口的寄存器中。

圖2 機器狀態寄存器
異常只能發生在處理器的內核中,在總線的中斷處理中沒有異常這個概念。異常是指處理器有意或無意的停止正常的運行,如意外重啟、軟件中斷等。而在PPC440中,所有的外部中斷被當做一個特殊的異常來進行處理。當發生異常/中斷時,系統自動跳轉到異常向量表(Interrupt-handler Table)中。異常向量表將異常/中斷與其異常向量相關聯,異常/中斷通過異常向量表找到自己的向量。通過異常向量在中斷控制器中找到對應的處理程序,這樣就與前面所說的總線中斷控制器對應。通過excIntConnect函數將外部中斷與異常處理程序掛接,excIntConnect((VOIDFUNCPTR*)_EXC_OFF_INTR,(VOIDFUNCPTR)ExternalISR),_EXC_OFF_INTR這個宏定義在VxWorks6.5安裝目錄下Powerpc處理器對應的excPpcLib.h文件中,代表外部異常向量;ExternalISR為異常處理程序,此處理程序主要負責對中斷控制器進行發出中斷后的操作,具體操作為利用IO函數XIo_Out32和XIo_In32讀寫各個中斷寄存器,中斷優先級從高到低檢測哪個中斷是被激活的,通過向IAR寄存器相應位寫1可以清除中斷請求。
如圖3所示,程序首先進入異常向量表中注冊的Xintc_DeviceInterruptHandler,該服務程序是系統層的注冊,然后進入HandlerTable,用戶自己的服務程序通過BSP中的中斷控制器驅動程序注冊在這個HandlerTable中。這樣就可以完成一次中斷的流程。

圖3 中斷處理流程框圖
由于VxWorks下中斷服務程序不能調用可能引起阻塞的函數,所以處理方法是拆分中斷服務程序,分為兩部分:一部分專門做判斷中斷類型,禁止中斷等,稱為中斷服務程序;第二部分將多數需要處理的操作,尤其是可能引起任務阻塞的操作放在此執行,稱為中斷服務任務。兩部分間采用VxWorks特有的信號量機制通信。由于獲取信號量會造成任務阻塞,中斷服務程序中不能獲取信號量,但可以釋放信號量,從而解除等待在該信號量上的一個任務[3]。
在調試實時系統過程中,中斷程序的性能是一個重要的指標,所以在調試過程中,需要使用時間戳功能。時間戳與sysclk不同,sysclkRate可以看做內核調度的頻率,一般默認較低,在本系統中為60,即每秒有60個TICK,如果修改的過高會導致CPU系統占用率過高。而時間戳與CPU的主頻相關,與RTOS調度無關。sysTimestamp是通過讀取計時器當前計數值來實現高精度定時的。時間戳顯示的是一秒內的時間狀態,溢出后就會從0開始重新計數,所以首先要確保任務運行在1 s內可以完成,否則一旦時間戳溢出,得出的數據就無意義了[4]。調試時可以使用打印兩次時間戳的方式查看任務所用時間,即兩次數據之差乘以頻率即為任務所用時間。
嵌入式操作系統VxWorks現被廣泛應用于各類實際工程中,其中中斷處理的性能直接影響整個系統的性能。由于ML507開發板FPGA和PPC440雙核的特殊性,理解基于該板卡的中斷處理流程是一個難點。通過研究驅動程序的內容,對深入了解硬件與FPGA邏輯的工作原理有幫助。
[1] Xilinx,Inc.DS516[M].USA:Xilinx,Inc,2009.
[2] International Business Machines Corporation.PPC440x5 CPU CORE User's Manual[M].USA:International Business Machines Corporation,2003.
[3] 王韜,楊士中,譚曉衡.基于MPC860和VxWorks的嵌入式中斷處理設計[J].電訊技術,2005(1):45-50.
[4] 陳育智,溫彥軍,陳琪.VxWorks程序開發實踐[M].北京:人民郵電出版社,2004.