1. 程式人生 > >SylixOS 中斷系統分析

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 中斷系統分析