引言 硬件中斷處理在實時操作系統設計中起著十分重要的作用,它是外部事件通知操作系統的最常用手段。中斷的正常運行是操作系統穩定工作的先決條件。VxWorks作為一款優秀的實時嵌入式系統,通常采用中斷的方式來滿足系統實時性要求。因此,熟悉其中斷的處理過程對于VxWorks操作系統的開發至關重要。本文通過基于S3C44B0X處理器VxWorks嵌入式操作系統的BSP移植,詳細分析了VxWorks操作系統基于ARM處理器的中斷處理方法。 1 ARM異常中斷處理 ARM體系結構支持復位(Reset)等7種異常中斷類型,各異常中斷的向量地址及中斷的處理優先級如表1所示。當異常中斷發牛時,硬件邏輯根據異常類型給程序計數器(PC)強制賦值,使程序從表1給出的相應的矢量地址開始執行異常處理程序。在異常中斷向量表中指定了各異常中斷與其處理程序的對應關系,一般來說,矢量地址處將包含一條指向相應程序的轉移指令,從而可跳轉到相應的中斷服務程序。異常中斷向量表存放在存儲器的0地址處,大小為32字節,每個異常中斷占4字節大小,保留了4字節空間。 表1 各異常中斷的向量地址以及中斷處理優先 S3C44BOX的中斷控制器町以接收來自26個中斷源的30個中斷請求,其中有4個外部中斷(EINT/4/5/6/7)是邏輯或的關系,它們共用一條中斷請求線。當片內外圍中斷和片外中斷模式設定為IRQ時,如有多重中斷發生,中斷控制器經過優先級判斷選擇其中一個中斷,通過IRQ向ARM7TDMI內核發出IRQ中斷請求。另外.在中斷服務程序中需特別注意:必須加入對L_ISPC或F_ISPC寄存器相應的中斷位寫1操作,來清除只讀中斷掛起寄存器INTPEND的掛起位,以使中斷正常運行。 2 VxWorks中斷處理機制 VxWorks中斷處理主要包括:保存被中斷任務的上下文,調用中斷服務程序(ISR),中斷返回恢復被中斷任務的上下文,其具體流程如圖1所示。對被中斷任務現場信息的保存,在S3C44B0處理器體系結構中,VxWorks采用集中式的保存方式,即在內存中專門設置一個中斷保存堆棧.所有中斷的現場信息都統一保存在此堆棧中。堆棧的定位和大小初始化依據指定參數在系統啟動時進行配置。對于堆棧的大小,必須足夠大,以滿足最壞情況下中斷嵌套的深度。 圖1 VxWorks中斷處理執行流程 2.1 異常向量表的生成及實現 當異常發生時,程序計數器(PC)會被強制為相應異常處理程序的入口地址.然后進行中斷源的識別,根據中斷號在中斷向量表中找到相應中斷服務程序(ISR)的入口地址。VxWorks將異常向量表定位在RAM中,基地址為VEC_BASE_ADRS,在configA11.h中定義.一般為RAM存儲器的起始地址。在系統啟動初始化時,由intVecBaseSet()函數設置向量表的基地址。向量表地址設定后,需要初始化指定異常的缺省處理函數。VxWorks在映像的代碼段建立了一張中斷缺省函數表,函數excVecInit()根據這張表來設置向量表的各異常中斷向量值。需初始化的向量表范圍由LOW_VEC和HIGH_VEC確定,在excArchLib.h中定義。由于不同的處理器異常處理機制不同,有時需根據具體的異常處理來建立自己的異常向量表,具體建立實現過程在下面討論。 2.2 中斷服務程序的連接 VxWorks為中斷提供接口函數intConnect(),它將中斷服務程序(ISR)和中斷向量相關聯。在操作系統內核啟動后,VxWorks建立與中斷號相對應的中斷向量表,中斷向量表中的每個中斷向量包含中斷服務程序(ISR)的入口地址。當中斷事件發生時.VxWorks內核將調用與其中斷向量對應的中斷服務程序。intConnect()原型如下: STATUS intConnect ( VOIDFUNCPTR * vector, /* 要關聯的中斷向量 */ VOIDFUNCPTR routine, /*中斷發生時調用的函數 */ int parameter /*傳遞給lsR函數的參數*/ ) 但實際上,中斷出現時并不是直接調用指定的中斷處理函數。而是,intConnect()函數將創建一小段代碼,這段代碼用以保存必要寄存器、設置堆棧入口、之后調用中斷處理函數。相反,當從該函數返回時,這段代碼先恢復寄存器和堆棧,然后退出中斷。 3 VxWorks基于S3C44B0X的中斷處理 3.1 基于S3C44B0X處理器的VxWorks異常向量表的生成S3C44BOX處理器不支持內存重定向操作,也就是每個片選的地址范圍是定死的,不能根據需要自己指定。啟動flash存儲器一直位于0地址,異常人口不能在運行時寫入,故必須硬編碼將異常入口填寫在啟動flash的0地址處。romInit.s是系統上電時的初始人口程序.從flash的0地址開始運行。故在其開始出定義異常入口程序實現如下: _ARM_FUNCTION(romInit) _romInit: B cold /* 上電復位后執行的第1條指令,也可看作是復位向量 */ ⋯ /* 未定義指令、軟件中斷等異常入口 */ B . B _romIRQ /* IRQ中斷異常入口 */ B . 在地址Ox00000014處S3C44B0X處理器未使用,保留。另外VxWorks不支持快速中斷.地址Ox0000001c保留。 由于VxWorks建立的異常向量表定位在RAM中.那么當中斷發生時如何把兩者連接起來.從而由VxWorks實現中斷管理呢?本BsP根據VxWorks缺省異常向量表,建立自定義的向量表,實現從ROM到RAM異常的連接,總體程序如下: /* _romIRQ 及其它函數定義 */ _romIRQ; sub sp,sp,#4 stmfd sq1 , (r0) ldr r0,L$_promIRQ ldr r0,[r0] /* 裝載IRQ異常地址到R0 */ str r0,[sp,#4] ldmfd sp!,{r0,pc} /* 跳轉到異常服務程序 */ /* _romIRQ指向RAM中的位置 */ L$_promIRQ: .long S3C_EXC_BASE + 20 /* #define S3C_EXC_BASE 0x0c000100 */ /* 在真正RAM空間建立異常向量表,和VxWorks建立的向量表相同,只是位置不同 */ void s3cExcVecSet(void) { UINT32 i: ... i=(UINT32)intEnt; *((UINT32 *)(S3C_EXC_BASE + Ox14))=i; } 對以上代碼分析:當中斷發生時.程序跳轉到_romIRQ處,然后執行出棧操作,把L$_promIRQ地址(0x0c000114=(s3c_EXC_BASE + 20))的內容賦給程序計數器(PC);而上述vxwofks在RAM空間建立異常向量表時,把異常中斷服務程序(intEnt)的地址放在地址0x0c00Oll4(s3C_EXC_BASE + 0x14)中,即PC=(UINT32) intEnt實現從ROM到RAM中斷的連接。 3.2 中斷驅動中的回調函數 VxWorks中intArchLib庫所包含的中斷系統函數與具體的處理器體系結構相關.其默認體系結構中不包含ARM處理器,所以此庫中的函數都要依賴于具體BsP提供的例程來完成其功能。VxWorks采用Hook的方法來實現,針對本處理器的BSP,在sngkcIntrCtl.c文件中,定義了四個鉤子函數: sysIntLvlVecChkRtn = sngks32cIntLvlVecChk;/* 中斷源檢測,返回中斷號 */ sysIntLvlEnableRtn = sngks32cIntLvlEnable; /* 使能相應中斷 */, svslntLvlDisableRtn = sngks32cIntLvlDisable; /* 禁止相應中斷 */, svsIntLvlvecAckRtn = sngks32cIntLvLAck; /* 清除中斷標志位 */, 用來完成中斷驅動。當外部中斷發生時,程序進入intEnt函數,運行sysIntLvlVecChkRm鉤子函數讀中斷服務掛起寄存器(I_ISPR)來檢測中斷源,并返回中斷號,通過在intConnect函數中建立的中斷向量與中斷服務函數的連接,從而調用相應的中斷服務程序。在中斷返回時.執行sysIntLvlvecAckRtn鉤子函數通過寫IRQ中斷掛起清零寄存器(I_ISPC),來清除剛處理完的中斷掛起位。完整的VxWorks基于S3C44BOX處理器的中斷響應流圖如圖2所示: 圖2 VxWorks基于S3C44B0X處理器的中斷響應流圖 4 實例分析 外部中斷EINT4/5/6/7共用一個中斷請求線,當其中一個中斷發生時,中斷掛起寄存器(INTPND)的EINT4/5/6/7位置1.具體是其中哪個發生中斷可通過讀外部中斷掛起寄存器(EXTINTPND)來判斷。 中斷服務程序連接 intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(21), (VOIDFUNCPTR)isr4567,0) 外部中斷使能 intEnable(21); /* 觸發鉤子函數 */ svsIntLvlEnableRtn; /* 清中斷屏蔽寄存器(INTMSK)的EINT4/5/6/7位使能中斷? */ 中斷服務程序: void isr4567(void) { int j; intDisable(21); /* 關中斷 */ S3C44B0X_INT_REG_READ (S3C44BOX_EXTINTPND,j);/*讀外部中斷掛起寄存器 */ switch (j) /* 判斷外部中斷4/5/6/7具體為哪個 */ { case 1: /* EINT4觸發 */ semGive(semInt4); /* 釋放二值信號量,同步EINT服務程序 */ break: ⋯ /* EINT5,EINT6,EINT7觸發程序 */ } ⋯ /* 清外部中斷掛起位,使能外部中斷 */ } 在中斷服務程序設計中對處理代碼有諸多限制,如處理代碼應盡量短,不能調用可能引起阻塞的任務等。針對這種限制,可以采用中斷服務程序分步處理法,具體是將原來的中斷服務程序分為新的中斷服務程序和中斷服務任務兩部分:新的中斷服務程序僅僅執行最基本的中斷處理,例如禁止中斷、判斷中斷類型等;而絕大多數的中斷處理任務,特別是有可能造成阻塞的任務,都放在中斷服務任務中執行。新的中斷服務程序和中斷服務任務采用二進制信號量進行同步(如上述程序設計所示),但中斷服務任務在創建時必須滿足在所有創建的任務中具有較高的優先級,以使中斷發生時外部事件得到優先處理,否則中斷響應就失去其意義。 5 結束語 隨著計算機技術和控制技術快速發展,VxWorks實時嵌入式操作系統被廣泛應用于各種設備和實時控制系統中,而硬件中斷處理在實時操作系統設計中起著十分重要的作用。針對嵌入式系統的硬件設計和軟件規劃,本文闡述了VxWorks的中斷處理機制,分析了VxWorks的中斷處理過程,提出了基于S3C44B0X處理器的中斷處理實現方法.提高了系統的實時性并滿足塒外部突發事件的及時處理.對從事實時系統的開發具有一定的參考和借鑒作用。 本文作者創新點:首次深刻分析了VxWorks基于S3C44B0X處理器的中斷處理過程。并以實際外部中斷處理為例,提出了在中斷服務程序設計中采取的分步處理。 作者:錢華明,牛付震 來源:《微計算機信息》(嵌入式與SOC)2009年第5-2期 |