本文章分析了ARM架構下SylixOS內核中斷流程,共包含三部分:數組
分析SylixOS運用數組和雙向鏈表實現中斷服務函數的註冊架構
闡述ARM硬件中斷機制ide
分析SylixOS中斷處理流程函數
SylixOS中斷註冊是經過數組和雙向鏈表實現的。spa
_K_idescTable [256]是SylixOS內核中的系統中斷向量結構索引數組,用於索引註冊的中斷服務函數,其類型如清單 21所示指針
清單 21索引
typedef struct { LW_LIST_LINE_HEADER IDESC_plineAction; /* 判斷中斷服務函數列表 */ ULONG IDESC_ulFlag; /* 中斷向量選項 */ LW_SPINLOCK_DEFINE (IDESC_slLock); /* 自旋鎖 */ } LW_CLASS_INTDESC
每進行一次中斷註冊,內核建立一箇中斷向量結構。若是有多箇中斷源共享一箇中斷號,內核將這些中斷源的各個中斷向量結構連接成雙向鏈表。中斷向量結構類型如清單 22所示:事務
清單 22內存
typedef struct { LW_LIST_LINE IACT_plineManage; /* 管理鏈表 */ INT64 IACT_iIntCnt[LW_CFG_MAX_PROCESSORS]; /* 中斷計數器 */ PINT_SVR_ROUTINE IACT_pfuncIsr; /* 中斷服務函數 */ VOIDFUNCPTR IACT_pfuncClear; /* 中斷清理函數 */ PVOID IACT_pvArg; /* 中斷服務函數參數 */ CHAR IACT_cInterName[LW_CFG_OBJECT_NAME_SIZE]; } LW_CLASS_INTACT
構建一箇中斷向量結構io
在此中斷向量結構中記錄中斷服務函數地址和中斷服務函數名等信息
將此中斷向量結構插入到此中斷號的中斷向量結構鏈表
以中斷向量號爲下標索引_K_idescTable數組,將其中的頭指針指向上一步構建的雙向鏈表
如圖 21所示,中斷註冊實質是構建中斷向量結構雙向鏈表。
圖 21中斷註冊
當中斷髮生後,ARM內核自動完成以下事務:
保存執行狀態:保存CPSR到中斷模式的SPSR中
模式切換:處理器進入中斷模式,並關閉中斷,防止中斷嵌套
保存返回地址:保存PC-4到中斷模式的LR中
跳入中斷向量表:強制設置PC爲中斷向量地址,跳轉到中斷處理程序中
當前程序的執行狀態是保存在CPSR中的,中斷髮生時,要保存當前CPSR中的執行狀態到中斷模式的SPSR中,未來中斷返回時,恢復到CPSR,恢復執行狀態。
硬件自動將中斷異常碼寫入CPSR中的模式位,CPU進入中斷模式。同時硬件自動切換處理器到ARM狀態下執行指令,而且CPU經過設置CPSR相應位來關閉中斷。
當前程序被中斷打斷,切換到中斷處理程序裏,中斷處理完後,返回當前被打斷模式繼續執行,所以必需要保存當前指令的下一條指令的地址到中斷模式下的LR中。因爲ARM異常模式不一樣以及ARM內核採用流水線技術,中斷處理程序須要從新計算正確的返回地址。
該操做是CPU硬件自動完成的,當異常發生時,CPU強制將PC的值改成一個固定內存地址,並跳到此地址處執行。
SylixOS中斷處理程序完成以下事務:
修正返回地址,LR=LR-4
保存現場寄存器
中斷處理階段1
恢復現場寄存器
返回現場,PC=LR,回到返回地址處繼續執行
中斷處理階段1完成了3件事務:
得到中斷源的中斷向量號
中斷處理階段2
中斷結束處理
得到中斷向量號通常都是經過讀取中斷控制器的某個寄存器來得到;中斷處理結束後須要通知中斷控制器中斷處理已經完成,通常都是向某個寄存器寫入任意值便可。
此階段是真正的進行中斷處理,完成如下事務:
以中斷向量號做爲索引,經過_K_idescTable數組找到此中斷向量號的中斷結構鏈表
依次遍歷以前註冊的中斷服務函數,並根據返回值判斷是否已經執行了相應中斷源的中斷服務函數。若是已經執行則退出遍歷,不然繼續遍歷直到找到相應的服務函數或者找不到退出。
經過中斷註冊構建中斷向量結構鏈表
中斷髮生時經過中斷向量號索引_K_idescTable數組找到此中斷向量號的中斷結構鏈表,而後遍歷以前註冊在其中的中斷服務函數,直到找到相應的服務函數或者找不到退出。