您的位置:首页 > 其它

SylixOS 中断系统分析

2017-06-16 00:00 120 查看
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 中断释放函数流程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息