SylixOS中断实现相对简单,主要借助arch接口,bsp接口,cpu对象,调度接口等实现。还通过数组和链表管理中断对象。

基于arch接口实现类

全局中断开关接口的简单封装。

#define  KN_INT_DISABLE()            archIntDisable()
#define KN_INT_ENABLE(intLevel)     archIntEnable(intLevel)
#define KN_INT_ENABLE_FORCE()       archIntEnableForce()
/*********************************************************************************************************
** 函数名称: API_InterLock
** 功能描述: 系统关闭中断
** 输 入  : piregInterLevel   保存中断控制字
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块: API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterLock (INTREG  *piregInterLevel)
{#if LW_CFG_ARG_CHK_EN > 0if (!piregInterLevel) {_ErrorHandle(ERROR_INTER_LEVEL_NULL);return  (ERROR_INTER_LEVEL_NULL);}
#endif*piregInterLevel = KN_INT_DISABLE();return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: API_InterUnlock
** 功能描述: 系统打开中断
** 输 入  : iregInterLevel    需要恢复的中断控制字
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块: API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterUnlock (INTREG  iregInterLevel)
{KN_INT_ENABLE(iregInterLevel);return  (ERROR_NONE);
}

基于bsp接口实现类

由bsp实现具体中断控制器下各中断的开关,优先级设置,CPU绑核等操作。对应的API_InterVectorxxx接口则是增加参数检查,自旋锁保护后调用bsp接口。

VOID    bspIntVectorEnable(ULONG  ulVector);
VOID    bspIntVectorDisable(ULONG  ulVector);
BOOL    bspIntVectorIsEnable(ULONG  ulVector);#define __ARCH_INT_VECTOR_ENABLE    bspIntVectorEnable
#define __ARCH_INT_VECTOR_DISABLE   bspIntVectorDisable
#define __ARCH_INT_VECTOR_ISENABLE  bspIntVectorIsEnable#if LW_CFG_INTER_PRIO > 0
ULONG   bspIntVectorSetPriority(ULONG  ulVector, UINT  uiPrio);
ULONG   bspIntVectorGetPriority(ULONG  ulVector, UINT *puiPrio);#define __ARCH_INT_VECTOR_SETPRIO   bspIntVectorSetPriority
#define __ARCH_INT_VECTOR_GETPRIO   bspIntVectorGetPriority
#endif                                                                  /*  LW_CFG_INTER_PRIO > 0       */#if LW_CFG_INTER_TARGET > 0
ULONG   bspIntVectorSetTarget(ULONG  ulVector, size_t  stSize, const PLW_CLASS_CPUSET  pcpuset);
ULONG   bspIntVectorGetTarget(ULONG  ulVector, size_t  stSize, PLW_CLASS_CPUSET  pcpuset);#define __ARCH_INT_VECTOR_SETTARGET bspIntVectorSetTarget
#define __ARCH_INT_VECTOR_GETTARGET bspIntVectorGetTarget
#endif                                                                  /*  LW_CFG_INTER_TARGET > 0     */
API 功能
API_InterVectorEnable 使能指定向量中断
API_InterVectorDisable 禁能指定向量中断
API_InterVectorDisableEx 禁能指定向量中断
API_InterVectorIsEnable 获得指定中断状态
API_InterVectorSetPriority 设置中断优先级
API_InterVectorGetPriority 获取中断优先级
API_InterSetTarget 设置中断目标 CPU
API_InterGetTarget 获取中断目标 CPU

基于CPU对象实现类

CPU有记录中断嵌套计数值和中断堆栈基地址,基于这俩变量可实现下列接口。

    PLW_STACK                CPU_pstkInterBase;                         /*  中断堆栈基址                */ULONG                    CPU_ulInterNesting;                        /*  中断嵌套计数器              */ULONG                    CPU_ulInterNestingMax;                     /*  中断嵌套最大值              */
API 功能
API_InterContext 是否在中断中
API_InterGetNesting 获得中断嵌套层数
API_InterGetNestingById 获得指定 CPU 中断嵌套层数,和最大中断嵌套层数
API_InterStackBaseGet 获得当前中断堆栈首地址
API_InterStackCheck 中断堆栈检查

中断每进入一次CPU_ulInterNesting加一,每退出一次减一,这样就能记录当前中断嵌套层数,如果为0,说明不在中断服务中。

基于工作队列类

中断延迟工作队列基于内核工作队列实现,同时创建优先级为0(最高优先级)的执行线程。对于多核处理器可以选择每个核有自己独立的工作队列,也可以和单核一样使用单一工作队列模式。

API 功能
API_InterDeferGet 获得对应 CPU 的中断延迟队列
API_InterDeferContext 是否在中断或 defer 上下文
API_InterDeferJobAdd 向中断延迟处理队列加入任务
API_InterDeferJobDelete 从中断延迟处理队列删除任务

中断延迟工作队列概念,原理,用法详见《SylixOS中断延迟队列》

基于系统中断向量表实现

注意是系统中断向量表不是处理器的异常向量表。这里只存储系统级的中断信息。

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;
/*********************************************************************************************************IRQ FLAG (设置为 QUEUE 模式向量后, 系统无法再返回非 QUEUE 模式向量)
*********************************************************************************************************/#define LW_IRQ_FLAG_QUEUE                               0x0001          /*  单向量, 多服务              */
#define LW_IRQ_FLAG_PREEMPTIVE                          0x0002          /*  是否允许抢占 (arch负责实现) */
#define LW_IRQ_FLAG_SAMPLE_RAND                         0x0004          /*  是否可用作系统随机数种子    */
#define LW_IRQ_FLAG_GJB7714                             0x0008          /*  GBJ7714 无返回值服务        */
/*********************************************************************************************************系统中断向量表
*********************************************************************************************************/
#define LW_CFG_MAX_INTER_SRC                    256     /*  系统使用中断向量表大小,中断源数量   <  9999 */
__KERNEL_EXT LW_CLASS_INTDESC        _K_idescTable[LW_CFG_MAX_INTER_SRC];
/*********************************************************************************************************中断向量表
*********************************************************************************************************/#define LW_IVEC_GET_IDESC(vector)       \(&_K_idescTable[vector])#define LW_IVEC_GET_FLAG(vector)        \(_K_idescTable[vector].IDESC_ulFlag)#define LW_IVEC_SET_FLAG(vector, flag)  \(_K_idescTable[vector].IDESC_ulFlag = (flag))
/*********************************************************************************************************
** 函数名称: API_InterVectorBaseGet
** 功能描述: 获得系统中断向量表基地址
** 输 入  : NONE
** 输 出  : 基地址指针
** 全局变量:
** 调用模块: API 函数
********************************************************************************************************/
LW_API
PVOID  API_InterVectorBaseGet (VOID)
{    return  ((PVOID)&_K_idescTable[0]);
}
/*********************************************************************************************************
** 函数名称: API_InterVectorSetFlag
** 功能描述: 设置指定中断向量的特性.
** 输 入  : ulVector                      中断向量号
**           ulFlag                        特性
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块:
** 注  意  : LW_IRQ_FLAG_QUEUE 必须在安装任何一个驱动前设置, 且设置后不再能取消.最好放在 bspIntInit() 函数中完成设置.API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterVectorSetFlag (ULONG  ulVector, ULONG  ulFlag)
{INTREG              iregInterLevel;PLW_CLASS_INTDESC   pidesc;if (_Inter_Vector_Invalid(ulVector)) {_ErrorHandle(ERROR_KERNEL_VECTOR_NULL);return  (ERROR_KERNEL_VECTOR_NULL);}pidesc = LW_IVEC_GET_IDESC(ulVector);LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel);         /*  关闭中断同时锁住 spinlock   */if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_QUEUE) {               /*  已经是 QUEUE 类型中断向量   */LW_IVEC_SET_FLAG(ulVector, ulFlag | LW_IRQ_FLAG_QUEUE);} else {LW_IVEC_SET_FLAG(ulVector, ulFlag);}LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel);        /*  打开中断, 同时打开 spinlock */return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: API_InterVectorGetFlag
** 功能描述: 获得指定中断向量的特性.
** 输 入  : ulVector                      中断向量号
**           *pulFlag                      特性
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块: API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterVectorGetFlag (ULONG  ulVector, ULONG  *pulFlag)
{INTREG              iregInterLevel;PLW_CLASS_INTDESC   pidesc;if (_Inter_Vector_Invalid(ulVector)) {_ErrorHandle(ERROR_KERNEL_VECTOR_NULL);return  (ERROR_KERNEL_VECTOR_NULL);}if (!pulFlag) {_ErrorHandle(ERROR_KERNEL_MEMORY);return  (ERROR_KERNEL_MEMORY);}pidesc = LW_IVEC_GET_IDESC(ulVector);LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel);         /*  关闭中断同时锁住 spinlock   */*pulFlag = LW_IVEC_GET_FLAG(ulVector);LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel);        /*  打开中断, 同时打开 spinlock */return  (ERROR_NONE);
}

基于中断服务函数对象和链表实现

具体的中断服务函数对象是挂接在对应的系统中断向量上的,可以同时挂接多个中断服务,即SylixOS可支持单向量多服务模式。
中断的注册,断开,响应都是基于对中断服务函数对象的操作。这部分相对复杂,下面章节单独说明。

其他

为了便于测试中断服务耗时或插入其他中断操作,系统还提供API_InterVectorMeasureHook接口,可注册两个回调函数,在进入和退出中断时调用。使用该功能需要打开LW_CFG_INTER_MEASURE_HOOK_EN宏设置。

/*********************************************************************************************************中断测量回调
*********************************************************************************************************/
VOIDFUNCPTR     _K_pfuncInterVectorMeasureEnter = LW_NULL;
VOIDFUNCPTR     _K_pfuncInterVectorMeasureExit  = LW_NULL;
/*********************************************************************************************************
** 函数名称: API_InterVectorMeasureHook
** 功能描述: 安装/卸载中断向量测量回调
** 输 入  : pfuncEnter        中断进入回调
**           pfuncExit         中断退出回调
** 输 出  : NONE
** 全局变量:
** 调用模块: API 函数
*********************************************************************************************************/
LW_API
VOID  API_InterVectorMeasureHook (VOIDFUNCPTR  pfuncEnter, VOIDFUNCPTR  pfuncExit)
{INTREG    iregInterLevel;iregInterLevel = __KERNEL_ENTER_IRQ();_K_pfuncInterVectorMeasureEnter = pfuncEnter;_K_pfuncInterVectorMeasureExit  = pfuncExit;__KERNEL_EXIT_IRQ(iregInterLevel);
}

SylixOS中的中断接口基础实现相关推荐

  1. SylixOS中的中断服务对象

    系统中断向量表 typedef struct {LW_LIST_LINE_HEADER IDESC_plineAction; /* 判断中断服务函数列表 */ULONG IDESC_ulFlag; / ...

  2. SylixOS中MTD调用底层接口流程分析

    1. MTD设备与底层驱动的关系   MTD设备是一种特殊的抽象设备,它用于简化驱动开发.它是底层硬件和上层软件的桥梁,无论对Nand Flash或是Nor Flash,它都提供了统一的框架供上层文件 ...

  3. JavaScript零基础入门 13:DOM规范中的MutationObserver接口

    目录 一.MutationObserver接口 二.MutationObserver基本用法 1.observe()方法 2.回调与MutationRecord 3.disconnect()方法 4. ...

  4. JAVA中的remote接口_JAVA基础:TravelAgentRemote(远程接口)

    创建TravelAgent EJB的第一步是定义它的远程接口.该接口规定了允许客户端调用的EJB业务方法.客户端与TravelAgent的createCaben()和findCabin()方法进行交互 ...

  5. SylixOS中select原理及使用分析

    2019独角兽企业重金招聘Python工程师标准>>> 1. select接口简介 1.1 select接口使用用例 select是操作系统多路I/O复用技术实现的方式之一. 多路I ...

  6. Linux中的中断管理机制

    1.中断相关基础知识介绍 1.1.中断产生背景 假设现在CPU需要去获取一个键盘的时间,如果处理器发出一个请求信号之后一直在轮询键盘的响应,由于键盘响应速度比处理器慢得多并且需要等待用户输入,这对于C ...

  7. Java 接口基础详解,java开发面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  8. SylixOS中的CPU集合及其操作

    SylixOS中的CPU集合及其操作 SylixOS支持SMP多核模式,在表示CPU集合时(如中断和线程绑定)通过一个位图来表示,操作和SylixOS位图接口类似,但并需要快速查找最低位,所以并不使用 ...

  9. Keyboard驱动中button中断的处理机制

    Keyboard驱动中button中断的处理机制 ********************************LoongEmbedded************************ 作者:Lo ...

最新文章

  1. php 清除之前echo_PHP入门读书笔记(三): 常量和变量
  2. AndoridSQLite数据库开发基础教程(5)
  3. FFmpeg的添加logo,去logo
  4. Android --- ERROR: Failed to resolve: xxx Affected Modules: xxx
  5. 训练softmax分类器实例_CS224N NLP with Deep Learning(四):Window分类器与神经网络
  6. mysql 授权truncate_有没有办法在MySQL中的TRUNCATE或DROP TABLE上有效地进行GRANT?
  7. ExtJs学习笔记(2)_Basic GridPanel[基本网格]
  8. 201507之佛山移动实习
  9. 人工智能平台 H2O.ai
  10. GeoTiff及GDAL切图(java)
  11. 【通信】基于matlab GUI循环编码译码【含Matlab源码 1348期】
  12. 麻省理工遍地走,6年经验安卓程序员面试微软,靠这份思维脑图拿下Offer!
  13. windows NT的安全性
  14. 一次 svchost.exe 进程占用大量网络带宽的排查
  15. highcharts多坐标轴混合图
  16. 同步模式之保护性暂停
  17. 如何使用 Swift 开发简单的条形码检测器?
  18. 湖北工程学院计算机基础实验报告,学院圆满举行2019级《计算机应用基础》 第一批线上测试试点工作...
  19. 樱桃是樱花的果实吗?
  20. oracle查询大于某个日期的数据,查看某天(或某个时间区间)的数据,请别用between ... and ......

热门文章

  1. SCA-IOT2050 连接至阿里云IOT平台,并通过阿里云IOT控制PLC
  2. VS Code实现python代码语法检查、格式规范化、自动换行字数限制
  3. Mathmatica多项式带余除法代码
  4. 从0到1000万:哔哩哔哩直播架构演进史
  5. 三个基本的布尔逻辑算符是_布尔逻辑运算符有几种,定义和功能分别是什么
  6. AIOps需要翻越的「三座大山」
  7. c语言bb,bb平台,指针,c语言.doc
  8. [Flink 日记]Exceeded checkpoint tolerable failure threshold.
  9. 从南极之争谈软件架构十个技巧,及…
  10. Python九宫格切图创意出圈—点赞,点赞,点赞,超美滴