SylixOS中的中断接口基础实现
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中的中断接口基础实现相关推荐
- SylixOS中的中断服务对象
系统中断向量表 typedef struct {LW_LIST_LINE_HEADER IDESC_plineAction; /* 判断中断服务函数列表 */ULONG IDESC_ulFlag; / ...
- SylixOS中MTD调用底层接口流程分析
1. MTD设备与底层驱动的关系 MTD设备是一种特殊的抽象设备,它用于简化驱动开发.它是底层硬件和上层软件的桥梁,无论对Nand Flash或是Nor Flash,它都提供了统一的框架供上层文件 ...
- JavaScript零基础入门 13:DOM规范中的MutationObserver接口
目录 一.MutationObserver接口 二.MutationObserver基本用法 1.observe()方法 2.回调与MutationRecord 3.disconnect()方法 4. ...
- JAVA中的remote接口_JAVA基础:TravelAgentRemote(远程接口)
创建TravelAgent EJB的第一步是定义它的远程接口.该接口规定了允许客户端调用的EJB业务方法.客户端与TravelAgent的createCaben()和findCabin()方法进行交互 ...
- SylixOS中select原理及使用分析
2019独角兽企业重金招聘Python工程师标准>>> 1. select接口简介 1.1 select接口使用用例 select是操作系统多路I/O复用技术实现的方式之一. 多路I ...
- Linux中的中断管理机制
1.中断相关基础知识介绍 1.1.中断产生背景 假设现在CPU需要去获取一个键盘的时间,如果处理器发出一个请求信号之后一直在轮询键盘的响应,由于键盘响应速度比处理器慢得多并且需要等待用户输入,这对于C ...
- Java 接口基础详解,java开发面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...
- SylixOS中的CPU集合及其操作
SylixOS中的CPU集合及其操作 SylixOS支持SMP多核模式,在表示CPU集合时(如中断和线程绑定)通过一个位图来表示,操作和SylixOS位图接口类似,但并需要快速查找最低位,所以并不使用 ...
- Keyboard驱动中button中断的处理机制
Keyboard驱动中button中断的处理机制 ********************************LoongEmbedded************************ 作者:Lo ...
最新文章
- php 清除之前echo_PHP入门读书笔记(三): 常量和变量
- AndoridSQLite数据库开发基础教程(5)
- FFmpeg的添加logo,去logo
- Android --- ERROR: Failed to resolve: xxx Affected Modules: xxx
- 训练softmax分类器实例_CS224N NLP with Deep Learning(四):Window分类器与神经网络
- mysql 授权truncate_有没有办法在MySQL中的TRUNCATE或DROP TABLE上有效地进行GRANT?
- ExtJs学习笔记(2)_Basic GridPanel[基本网格]
- 201507之佛山移动实习
- 人工智能平台 H2O.ai
- GeoTiff及GDAL切图(java)
- 【通信】基于matlab GUI循环编码译码【含Matlab源码 1348期】
- 麻省理工遍地走,6年经验安卓程序员面试微软,靠这份思维脑图拿下Offer!
- windows NT的安全性
- 一次 svchost.exe 进程占用大量网络带宽的排查
- highcharts多坐标轴混合图
- 同步模式之保护性暂停
- 如何使用 Swift 开发简单的条形码检测器?
- 湖北工程学院计算机基础实验报告,学院圆满举行2019级《计算机应用基础》 第一批线上测试试点工作...
- 樱桃是樱花的果实吗?
- oracle查询大于某个日期的数据,查看某天(或某个时间区间)的数据,请别用between ... and ......
热门文章
- SCA-IOT2050 连接至阿里云IOT平台,并通过阿里云IOT控制PLC
- VS Code实现python代码语法检查、格式规范化、自动换行字数限制
- Mathmatica多项式带余除法代码
- 从0到1000万:哔哩哔哩直播架构演进史
- 三个基本的布尔逻辑算符是_布尔逻辑运算符有几种,定义和功能分别是什么
- AIOps需要翻越的「三座大山」
- c语言bb,bb平台,指针,c语言.doc
- [Flink 日记]Exceeded checkpoint tolerable failure threshold.
- 从南极之争谈软件架构十个技巧,及…
- Python九宫格切图创意出圈—点赞,点赞,点赞,超美滴