windows驱动开发-中断(一)

中断是windows中最难的一部分,这是因为中断本身属于操作系统的一部分,理解了中断和内存,对整个系统也就了解了。

中断部分会先从中断优先级、中断处理、中断服务例程入手,大概讲述一下中断的概念;接着从中断的一般实现来讲解;最后我们会实际分析PCI中断相关的部分。

中断优先级

再看中断之前,我们闲了接一下中断优先级的概念,在之前我们也提到过内核代码的执行级别,那个时候只是简单的说一下代码的运行级别,但实际上,这个概念是中断优先级才对。

windows使用0~31的优先级来描述中断,数值越大,中断优先级越高,详细的描述如下:

PASSIVE_LEVEL 	0 
APC_LEVEL 		1 
DISPATCH_LEVEL 	2 

DIRQL: from 3 to 26 for device ISR

PROFILE_LEVEL 	27
SYNCH_LEVEL 	28
CLOCK_LEVEL     28
IPI_LEVEL 		29
POWER_LEVEL 	30
HIGH_LEVEL 		31

0~2级别的中断称为软件中断,它们定义在内核代码中;剩下称为硬件中断,定义在HAL(硬件抽象)层中;硬件中断的3~26号称为设备中断,是给windows设备使用的;27~31号中断是留给处理器使用的中断。

HIGH_LEVEL是最高级别的中断,用于一些不可中断的执行过程,比如说,当发生蓝屏的时候,windows会将优先级提升到HIGH_LEVEL;

POWER_LEVEL是电源中断,但是windows中并没有使用它;     

IPI_LEVEL是同步处理器之间通讯的中断;     

CLOCK_LEVEL 是时钟中断,CPU利用这个中断来实现定时器;       

PROFILE_LEVEL是性能剖析中断,在windows进行性能剖析的时候使用;     

Device IRQL则是设备驱动程序使用的,它们可以和设备提供的中断服务例程;

代码运行在某个优先级,是指代码在运行的时候,内核会将优先级提高到某个优先级,事实上,综合前面的部分,我们很容易得到结论,这个说法指的是软件中断,而非硬件中断,不过要注意,内核函数的说明中会明确指出代码运行的优先级,要注意这一点。

3~26的中断等级是设备驱动程序使用的,它们并不是按照加载到内核的顺序确认的,事实上,除了总线驱动,一般也不需要考虑这个问题,不过我们仍然可以在设备管理器中看到一点踪迹:

b1b50be19faa4a789e2b2b222e8daeab.png

这是我从设备管理器中的截图,在USB 3.1总线上,会有一个资源选项卡,其中会给出当前总线的IRQ,这个IRQ后面会被映射为某个IRQL。

在上图中已经能够推断出这个USB总线的寄存器范围是84500000~8450FFFF,它的大小就是0xFFFF;其次,这个设备注册的中断服务例程IRQL等级是20;

实际上,现在内部总线几乎都是PCI总线,大部分都在PCI复合设备上,系统中另外一个中断来源则是GPIO。

中断的处理

Intel x86定义了256个中断向量,这些中断向量通过中断描述符来表达,这些描述符存在中断描述符表IDT中,中断描述符寄存器会在启动后,中断向量编程完成后存储中断描述符表的地址,在中断发生时,控制权转移到中断服务例程执行。

注意,虽然只有256个中断,但是处理器可以处理的中断数非常多,因为在中断描述符表中,32!256号中断对应的是一个中断处理链,同级别的中断可能来自于不同的设备,例如USB总线上的N个设备,可能都挂到一个中断处理例程上。

举个例子,当用0来做除数的时候,在译码周期会被检测到,此时CPU就会将根据异常来将中断向量中0号中断地址从IDTR中取出,将寄存器、栈保存下来,然后跳转到中断的入口点,执行中断,执行完中断之后,再跳回原来的指令流。在这种过程中,我们会发现,保存当前寄存器和栈是希望这个中断可以被处理,异常和中断都是用同一套机制来处理的。

先说异常,对于异常,有三种可能: 错误、异常、终止:

对于错误,处理器期待可以恢复,故处理完之后,指令流会回到出现错误的那条指令持续执行,典型的例子是页面错误,中断处理程序会将错误的页面找到并调入系统,然后再执行错误指令即可;

对于异常,处理器也期待可以恢复,故会发挥到下一条指令,典型的例子是调试断点;

至于终止,处理器已经不期待指令流可以执行了,所以指令流不会再回去执行了。

中断和异常不一样的是,中断是异步的,所以当中断会被分为上半部分和下半部分(这个说法是Linux的,但是这个说法很好的诠释了中断处理的本质,上半部分用于处理最紧急的事件,下半部分则处理不那么紧急的事件),上半部分执行完后,代码流可能会返回之前的指令流,此时中断处理可能还没完成,直到下半部分处理完,中断才算完成,不过此时之前的指令流可能已经执行完了,故中断可以是异步的,就是源自于此。

比如说,在上面的USB总线的中断到来时候,windows正在执行某个线程,此时如果处理器可以响应这个USB中断,那么它会将当前线程压入堆栈,然后控制权交给中断服务例程,中断服务例程则会处理最紧急的部分,例如说将总线上的数据取下,然后中断服务例程会插入一个DPC/APC/工作项,将中断的下半部分一些不重要的事情会放在这些处理方式中里面执行,指令流再返回之前的指令流,或者不返回接着执行DPC也是可能的。

中断的异步性是通过DPC/APC/工作项来体现的,总线驱动的中断处理例程往往只会处理非常短的时间,它可能仅仅将数据拷贝一下或者设置一下,然后就马上返回了;处理器不应该在高级别的IRQL下运行太久的时间,这会导致性能急剧下降,对其他中断的响应速度下降。

中断服务例程

生成中断的设备驱动程序必须至少有一个中断服务例程 (ISR) 。ISP例程必须执行适用于设备的任何操作来消除中断,可能包括阻止设备中断;它应仅执行保存状态并将DPC 排队的必要操作,以低于执行ISP例程的优先级(IRQL)完成I/O操作。

驱动程序的ISP例程在中断上下文中执行,由 IoConnectInterruptEx 的 SynchronizeIrql 参数指定为某个系统分配的 DIRQL。

ISP例程是可中断的,具有更高系统分配DIRQL的另一个设备可以随时中断或高IRQL系统中断。

在系统调用ISP例程之前,它会获取中断的自旋锁,因此ISP例程不能在另一个处理器上同时执行。ISP例程返回后,系统会释放旋转锁。

由于ISP例程以相对较高的IRQL运行,因此它使用当前处理器上的等效或更低IRQL屏蔽中断,因此它应尽快返回控制权。 此外,在DIRQL 上运行ISP例程会限制ISP例程可以调用的支持例程集。 

通常,ISP例程执行以下常规步骤:

如果导致中断的设备不受ISP例程支持,则ISP例程将立即返回 FALSE。

否则,ISP例程会根据需要清除中断,保存所需的任何设备上下文,并将DPC 排队以在较低的IRQL处完成I/O操作。然后,ISP例程必须返回 TRUE。

具体而言,在不涉及重叠设备I/O操作的驱动程序中,ISP例程应执行以下操作:

1. 确定中断是否为虚假中断。 如果是,请立即返回 FALSE ,以便立即调用中断设备的ISP例程。 否则,请继续中断处理。

2. 如有必要,请停止设备中断。

3. 收集DPCForISP例程(或 CustomDpc) 例程完成当前操作的I/O处理所需的任何上下文信息。

4. 将此上下文存储在DpcForISP例程或CustomDpc例程可访问的区域中,通常存储在处理当前I/O请求导致中断的目标设备对象的设备扩展中。

如果驱动程序与I/O操作重叠,则上下文信息必须包括DPC 例程需要完成的未完成请求计数,以及DPC 例程完成每个请求所需的任何上下文。 如果在DPC 运行之前调用ISP例程来处理另一个中断,则它不得覆盖DPC 尚未完成的请求的已保存上下文。

5. 如果驱动程序具有DPCForISP例程例程,请使用指向当前 IRP、目标设备对象和已保存上下文的指针调用 IoRequestDpc 。 IoRequestDpc 会将DPCForISP例程例程排入队列,只要IRQL低于处理器上的DISPATCH_LEVEL即可运行。

如果驱动程序具有CustomDpc例程,请使用指向与CustomDpc 例程关联的DPC 对象的指针 (调用 KeInsertQueueDpc) 指向CustomDpc例程完成操作所需的任何已保存上下文的指针。

通常,ISP例程还会传递指向当前 IRP 和目标设备对象的指针。 只要IRQL低于处理器上的DISPATCH_LEVEL, 就会运行CustomDpc例程。

6. 返回 TRUE 以指示其设备生成了中断。

通常,ISP例程不会执行实际I/O处理来满足 IRP。 相反,它会停止设备中断,设置必要的状态信息,并将驱动程序的DPCForISP例程或CustomDpc排队,以执行任何必要的I/O处理来满足导致设备中断的当前请求后返回。

ISP例程必须在尽可能短的时间间隔内以DIRQL运行。 遵循此准则会增加计算机中每台设备的I/O吞吐量,因为以DIRQL运行会屏蔽系统为其分配了较小或相等IRQL值的所有中断。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/579658.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot 集成 activemq

文章目录 一:说明二:e-car项目配置1 引入activemq依赖2 application启动类配置消息监听3 application.yml配置4 MQConfig.java 配置类5 ecar 项目中的监听6 junit 发送消息 三:tcm-chatgpt项目配置5 MQListener.java 监听消息 三 测试启动act…

Docker② —— Cgroups详解

1. 概述 Cgroups 的全称是control groups,cgroups为每种可以控制的资源定义了一个子系统。Cgroups分为三个部分: cgroup 本身:对进程进行分组hierarchy:将 cgroup 形成树形结构subsystem:真正起到限制作用的部组件 cp…

【vscode】2024最新!vscode云端配置同步方案:code settings sync

小tian最近对电脑进行了系统重装,结果vscode相关配置和插件都没有保存记录,还好公司电脑里还有。痛定思痛,决定写一篇vscode云端同步配置方案,以作记录和分享~ 步骤一:安装vscode插件:code settings sync …

云贝餐饮连锁V2-2.9.9源码

云贝餐饮连锁V2独立版、版本更新至2.9.9,小程序、公众号版本,全插件,公众号小程序端,独立版; 带商家端,修复收银台、排队点餐、堂食点餐;最新版更新 搭建环境教程: 系统环境:CentO…

【04】JAVASE-循环语句【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture:波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。…

算法学习笔记Day9——动态规划基础篇

一、介绍 本文解决几个问题:动态规划是什么?解决动态规划问题有什么技巧?如何学习动态规划? 1. 动态规划问题的一般形式就是求最值。动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多&#xff…

微信小程序小游戏开发,微信开发者工具提示该目录下的项目(wxapp2)已在工具中创建,怎么办

微信小程序小游戏开发,微信开发者工具提示该目录下的项目(wxapp2)已在工具中创建,怎么办 情况描述, 导入一个项目的时候,导入成了小游戏项目了 想换成小游戏项目,变不了了,提示 “…

未来已来:解锁AGI的无限潜能与挑战

未来已来:解锁AGI的无限潜能与挑战 引言 假设你有一天醒来,发现你的智能手机不仅提醒你今天的日程,还把你昨晚做的那个奇怪的梦解释了一番,并建议你可能需要减少咖啡摄入量——这不是科幻电影的情节,而是人工通用智能…

解决Milvus官网提供的单机版docker容器无法启动,以及其它容器进程与Milvus容器通信实现方案【Milvus】【pymilvus】【Docker】

文章目录 问题预备知识方案获取pymilvus获取milvus 实例多容器通信 问题 我的需求是做混合检索单机版可以满足,要走Docker容器部署,还需要和另一个容器中的程序做通信。官方文档提供的Milvus安装启动Milvus方案,见文档:传送门 我…

wlan二层直连组网实验(ensp)

目录 1. VLAN 端口类型及参数设计2. IP 地址规划3. WLAN数据规划(1) DHCP服务器配置(2) AC 源接口地址、认证方式配置(3) AP 组的创建(4) 创建域管理模板、国家码认证(5) 创建安全模板(6) 创建SSID模板(7) 创建VAP模板(8) AP组绑定模板(9) 查看: 1. VLAN 端口类型及…

以太网LAN双向透明传输CH9120透传芯片实现以太网转232串口转485转TTL串口

网络串口透传芯片 CH9120 1、概述 CH9120 是一款网络串口透传芯片。CH9120 内部集成 TCP/IP 协议栈,可实现网络数据包和串口数据的双向透明传输,具有 TCP CLIENT、TCP SERVER、UDP CLIENT 、UDP SERVER 4 种工作模式,串口波特率最高可支持到…

03 Docker入门Dockerfile详解及镜像创建

1.1 使用 Dockerfile 构建镜像 新建一个 Dockerfile 文件vi Dockerfile 将下面的内容复制粘贴进去:## Base Images ## 从天池基础镜像构建(from的base img 根据自己的需要更换,建议使用天池open list镜像链接:https://tianchi.aliyun.com/forum/postDetail?postId=67720) F…

【Unity动画系统】动画状态基本属性与相关API、IK简单概述

动画状态基本属性与相关API Tag:判断是否当前播放着相对应Tag的动画,如果是,那么玩家的输入就是无效的。 using UnityEngine.InputSystem;public AnimatorStateInfo stateInfo;void State(){//stateInfo animator.GetCurrentAnimatorStateIn…

AcrelEMS-MH民航机场智慧能源管平台解决方案【可靠供电/降低能耗/高效运维】

民航机场行业背景 自2012年以来,我国民航运输规模出现了显著增长,旅客运输量:从2012年的3.19亿人次上升至2019年的6.6亿人次(注:为剔除疫情影响,此处采取疫情前2019年的数据,下同)&…

数据结构七:线性表之链式栈的设计

在上篇博客,学习了用数组实现链的顺序存储结构,那是否存在用单链表实现栈的链式存储结构,答案是当然的,相比于顺序栈,用数组实现的栈效率很高,但若同时使用多个栈,顺序栈将浪费很多空间。用单链…

用NuGet安装 Oracle ODP.NET

oracle官网原文:Using NuGet to Install and Configure Oracle Data Provider for .NET Using NuGet to Install and Configure Oracle Data Provider for .NET In this section, you will install ODP.NET NuGet packages from nuget.org. Select View > Solut…

PDF 正确指定页码挂载书签后,书签页码对不上

这个问题与我的另一篇中方法一样 如何让一个大几千页的打开巨慢的 PDF 秒开-CSDN博客 https://blog.csdn.net/u013669912/article/details/138166922 另做一篇原因是一篇文章附带一个与该文章主题不相关的问题时,不利于被遇到该问题的人快速搜索发现以解决其遇到的…

8_手眼标定总结_auboi5机械臂与海康平面相机

经过不断地学习与调试,不断地学习网络上其他同志分享的资料,opencv手眼标定迎来了阶段性结束。实际测试结果在机械臂坐标系中X方向差5mm左右。 代码参考《https://blog.csdn.net/wanggao_1990/article/details/81435660》 注意事项: ①标定…

AG32 MCU在触摸屏的应用(AGM FPGA/MCU行业应用)

传统的屏驱MCU常见应用于洗衣机、空调、空调面板、仪器仪表等人机交互界面显示场景中,通常是以段码的形式显示设备运转的时间、温度、测量结果等简单运行数据,随着人机交互需求丰富化,智能家居设备、摩托车、电动车等产品也逐步增加了屏幕显示…

如何在 Ubuntu 12.04 上使用 Apache 配置 WebDAV 访问

简介 WebDAV 是内置在 HTTP 中的分布式网络编辑实现,允许您轻松共享文件并与他人协作。 我们可以在 Web 服务器中安装此扩展,以允许通过 Web 浏览器远程读写访问本地文件。在本指南中,我们将在带有 Apache Web 服务器的 Ubuntu 12.04 VPS 上…