SylixOS 中斷系統分析
SylixOS中斷系統分析
中斷向量表
在SylixOS中,系統默認存在一張大小為256(可以手動配置)的中斷向量表,用於管理SylixOS中的每一個中斷向量。該向量表存在於k_globalvar.h文件中,其定義格式如程序清單1-1所示。
程序清單1-1 系統中斷向量表定義
/********************************************************************************************************* 系統中斷向量表 *********************************************************************************************************/ __KERNEL_EXT LW_CLASS_INTDESC _K_idescTable[LW_CFG_MAX_INTER_SRC]; __KERNEL_EXT LW_SPINLOCK_DEFINE (_K_slVectorTable);
_K_idescTable是大小為256的數組,數組元素為256個中斷向量,_K_slVectorTable是一個自旋鎖,用於對中斷向量表的互斥訪問。
_K_idescTable的類型為LW_CLASS_INTDESC,該類型是SylixOS的中斷向量表結構,定義如程序清單1-2所示。
程序清單1-2 中斷向量表結構定義
typedef struct { LW_LIST_LINE_HEADER IDESC_plineAction; /* 判斷中斷服務函數列表 */ ULONG IDESC_ulFlag; /* 中斷向量選項 */ LW_SPINLOCK_DEFINE (IDESC_slLock); /* 自旋鎖 */ } LW_CLASS_INTDESC; typedef LW_CLASS_INTDESC *PLW_CLASS_INTDESC;
LW_CLASS_INTDESC類型的原型分析如下:
IDESC_plineAction是用於管理中斷服務函數的鏈表,通常情況下,一個中斷號對應一個中斷服務函數,那麽該鏈表內只有一個成員;但有些特殊情況,一個中斷號可以對應多個中斷服務函數,則該鏈表有多個成員。
IDESC_ulFlag 中斷向量選項。
IDESC_slLock 中斷向量自旋鎖
中斷向量的選項如表1-1所示。
表1-1 中斷向量類型
宏名 | 含義 |
LW_IRQ_FLAG_QUEUE | 支持單向量,多服務 |
LW_IRQ_FLAG_PREEMPTIVE | 允許中斷搶占 |
LW_IRQ_FLAG_SAMPLE_RAND | 可用作系統隨機數種子 |
LW_IRQ_FLAG_GJB7714 | 支持GJB7714國軍標體系 |
1.2中斷描述符
在SylixOS中,每一個中斷服務函數對應一個中斷描述符結構,並將該中斷描述符結構加入到中斷向量表對應的表項中,如果一個中斷向量對應多個中斷服務函數,則這些中斷服務函數對應的中斷描述符就組成了一個鏈表,並由中斷向量表對應的表項來進行管理。中斷描述符結構如程序清單1-3所示。
程序清單1-3 中斷描述符結構體定義
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; /* 中斷描述符 */ typedef LW_CLASS_INTACT *PLW_CLASS_INTACT;
中斷描述符類型的原型分析:
IACT_plineManage 管理鏈表,用於將中斷描述符加入到中斷向量表表項
IACT_iIntCnt 中斷計數器,每一次中斷該數值加1
IACT_pfuncIsr 中斷服務函數
IACT_pfuncClear 中斷清理函數
IACT_pvArg 中斷服務函數參數
IACT_cInterName 中斷服務函數名字
1.3SylixOS中斷服務函數流程
1.3.1總中斷服務函數
以ARM體系為例,當ARM內核檢測到中斷時,會自動將PC指向中斷異常入口處去執行中斷異常函數,SylixoS的中斷異常函數定義為archIntEntry,它是由匯編語言編寫,可以用ctrl+h來全局查找該函數進行詳細分析。這就是SylixOS的總中斷服務函數,也就是說,無論是哪一個中斷向量產生中斷,都會先進入archIntEntry函數。實際上,在執行工程師自己定義的中斷服務函數之前,需要進行一些準備工作,比如上下文的保存,中斷嵌套的判斷等;執行完工程師自己定義的中斷服務函數後,還需要進行上下文的恢復等操作;這些都是由archIntEntry函數來完成,archIntEntry函數就相當於一層外殼,它對底層工程師隱藏了整個中斷響應復雜的細節。
那麽,archIntEntry函數,來查找中斷服務函數。是如何找到工程師自己定義的中斷服務函數呢?通過分析archIntEntry函數的源代碼可知, archIntEntry函數通過調用bspIntHandle函數,bspIntHandle函數調用archIntHandle函數,來查找中斷服務函數。
1.3.2查找中斷服務函數
archIntHandle函數定義如程序清單1-4所示。
程序清單1-4 archIntHandle函數定義
LW_WEAK VOID archIntHandle (ULONG ulVector, BOOL bPreemptive)
archIntHandle函數原型分析:
參數ulVector是中斷向量號
參數bPreemptive表示是否允許中斷搶占,這裏只是根據是否允許搶占來判斷是否打開中斷,中斷嵌套上下文的保存是在archIntEntry函數中處理的。
archIntHandle函數的大體流程如圖1-1所示。
圖1-1 中斷服務函數流程
1.3.3中斷服務函數返回值
archIntHandle函數在遍歷中斷服務函數鏈表時,會根據中斷服務函數的返回值判斷是否需要結束遍歷,它的返回值有三種選項,如表1-2所示。
表1-2 中斷服務函數返回值選項
宏名 | 含義 |
LW_IRQ_NONE | 不是本中斷服務函數產生的中斷,繼續遍歷 |
LW_IRQ_HANDLED | 是本中斷服務函數產生的中斷,結束遍歷 |
LW_IRQ_HANDLED_DISV | 中斷處理結束,並屏蔽本次中斷 |
可參考SylixOS GIT上的文檔《TN0032_SylixOS共用中斷號機制》,來對中斷服務函數返回值做更詳細的了解。
2.SylixOS中斷的連接與釋放
在SylixOS中,中斷的連接與釋放的函數分別是API_InterVectorConnect函數和API_InetrVectorDisable函數,下面介紹SylixOS中斷的連接和釋放過程。
2.1SylixOS中斷連接函數簡介
API_InterVectorConnect函數定義如程序清單2-1所示。
程序清單2-1 中斷連接函數
LW_API ULONG API_InterVectorConnect(ULONG ulVector, PINT_SVR_ROUTINE pfuncIsr, PVOID pvArg, CPCHAR pcName); /* 設置指定向量的服務程序 */
函數API_InterVectorConnect原型分析:
函數返回為連接成功或失敗
參數ulVector是中斷向量號
參數pfuncIsr是中斷服務函數
參數pvArg是中斷服務函數參數
參數pcName是中斷服務名稱
API_InterVectorConnect函數的功能是將中斷向量號與中斷服務函數進行連接。
API_InterVectorConnect函數的大體流程如圖2-所示。
圖2- 1 中斷服務連接函數流程
SylixOS中斷釋放函數簡介
API_InterVectorDisable函數的定義如程序清單2-2所示。
程序清單2-2 中斷釋放函數
LW_API ULONG API_InterVectorDisconnect(ULONG ulVector, PINT_SVR_ROUTINE pfuncIsr, PVOID pvArg); /* 刪除指定向量的服務程序 */
API_InterVectorDisable函數原型分析:
函數返回值是釋放成功或失敗
參數ulVector是中斷向量號
參數pfuncIsr是中斷服務函數
參數pvArg是中斷服務函數的參數
API_InterVectorDisable函數僅僅只是釋放與參數pfuncIsr和參數pvArg相對應的中斷服務函數,當一個向量對應多個函數時,它並不會釋放該向量的所有中斷服務函數。
如果要想一次性釋放所有中斷服務函數,SylixOS提供了另外的接口,API_InterVectorDisconnectEx函數,它的定義如程序清單2-3所示。
程序清單2-3 中斷釋放擴展函數
LW_API ULONG API_InterVectorDisconnectEx(ULONG ulVector, PINT_SVR_ROUTINE pfuncIsr, PVOID pvArg, ULONG ulOption); /* 刪除指定向量的服務程序 */
API_InterVectorDisconnectEx函數原型分析:
該函數的前三個參數與API_InterVectorDisable函數參數相同,實際上API_InterVectorDisable就是調用了該函數。
參數ulOption是刪除選項
刪除選項的選項如表2- 1所示。
表2- 1 中斷釋放函數的刪除選項
宏名 | 含義 |
LW_IRQ_DISCONN_DEFAULT | 解除匹配函數和函數參數的中斷服務連接 |
LW_IRQ_DISCONN_ALL | 解除所有中斷服務連接 |
LW_IRQ_DISCONN_IGNORE_ARG | 解除匹配函數的中斷服務連接(忽略函數參數) |
API_InterVectorDisconnectEx函數的大體流程如圖2-2所示。
圖2-2 中斷釋放函數流程
SylixOS 中斷系統分析