- 浏览: 970871 次
- 性别:
- 来自: 珠海
文章分类
最新评论
-
Yunjey:
Yunjey 写道这样子的话、grid中的editable如何 ...
Flex创建可编辑以及分页的DataGrid -
Yunjey:
这样子的话、grid中的editable如何设置啊?!
Flex创建可编辑以及分页的DataGrid -
di1984HIT:
写的很好~~
JCalendar组件 -
sanny81:
此文真棒!感谢一路风尘的奉献!
但我有一疑 ...
Filter发送自定义数据详解 -
umgsai:
求完整demo umgsai@126.com
Flex和Jsp创建用户登入系统
Windows NT为每个硬件中断和少数软件事件赋予了一个优先级,即中断请求级(interrupt request level - IRQL)。IRQL为单CPU上的活动提供了同步方法,它基于下面规则:
一旦某CPU执行在高于PASSIVE_LEVEL的IRQL上时,该CPU上的活动仅能被拥有更高IRQL的活动抢先。
图4-1显示了x86平台上的IRQL值范围。(通常,这个IRQL数值要取决于你所面对的平台) 用户模式程序执行在PASSIVE_LEVEL上,可以被任何执行在高于该IRQL上的活动抢先。许多设备驱动程序例程也执行在 PASSIVE_LEVEL上。第二章中讨论的DriverEntry 和AddDevice 例 程就属于这类,大部分IRP派遣例程也属于这类。
某些公共驱动程序例程执行在DISPATCH_LEVEL上,而DISPATCH_LEVEL级要比PASSIVE_LEVEL级高。这些公共例程 包括StartIo 例程,DPC(推迟过程调用)例程,和其它一些例程。这些例程的共同特点是,它们都需要访问设备对 象和设备扩展中的某些域,它们都不受派遣例程的干扰或互相干扰。当任何一个这样的例程运行时,上面陈述的规则可以保证它们不被任何驱动程序的派遣例程抢 先,因为派遣例程本身执行在更低级的IRQL上。另外,它们也不会被同类例程抢先,因为那些例程运行的IRQL与它们自己的相同。只有拥有更高IRQL的 活动才能抢先它们。
图4-1. 中断请求级
在DISPATCH_LEVEL级和PROFILE_LEVEL级之间是各种硬件中断级。通常,每个有中断能力的设备都有一个IRQL,它定义了该 设备的中断优先级别。WDM驱动程序只有在收到一个副功能码为IRP_MN_START_DEVICE的IRP_MJ_PNP请求后,才能确定其设备的 IRQL。设备的配置信息作为参数传递给该请求,而设备的IRQL就包含在这个配置信息中。我们通常把设备的中断级称为设备IRQL,或DIRQL。
其它IRQL级的含义有时需要依靠具体的CPU结构。这些IRQL通常仅被Windows NT内核内部使用,因此它们的含义与设备驱动程序的编写不是特别密切相关。例如,我将要在本章后面详细讨论的APC_LEVEL,当系统在该级上为某线程 调度APC(异步过程调用)例程时不会被同一CPU上的其它线程所干扰。在HIGH_LEVEL级上系统可以执行一些特殊操作,如系统休眠前的内存快照、 处理bug check、处理假中断,等等。
IRQL的变化
为了演示IRQL的重要性,参见图4-2,该图显示了发生在单CPU上的一系列事件。在时间序列的开始处,CPU执行在PASSIVE_LEVEL 级上。在t1时刻,一个中断到达,它的服务例程执行在DIRQL1上,该级是在DISPATCH_LEVEL和PROFILE_LEVEL之间的某个 DIRQL。在t2时刻,另一个中断到达,它的服务例程执行在DIRQL2上,比DIRQL1低一级。我们讨论过抢先规则,所以CPU将继续服务于第一个 中断。当第一个中断服务例程在t3时刻完成时,该中断服务程序可能会请求一个DPC。而DPC例程是执行在DISPATCH_LEVEL上。所以当前存在 的未执行的最高优先级的活动就是第二个中断的服务例程,所以系统接着执行第二个中断的服务例程。这个例程在t4时刻结束,假设这之后再没有其它中断发 生,CPU将降到DISPATCH_LEVEL级上执行第一个中断的DPC例程。当DPC例程在t5时刻完成后,IRQL又落回到原来的 PASSIVE_LEVEL级。
图4-2. 变 化中的中断优先级
遵循下面规则,你可以利用IRQL的同步效果:
所有对共享数据的访问都应该在同一(提升的)IRQL上进行。
换句话说,不论何时何地,如果你的代码访问的数据对象被其它代码共享,那么你应该使你的代码执行在高于PASSIVE_LEVEL的级上。一旦越过 PASSIVE_LEVEL级,操作系统将不允许同IRQL的活动相互抢先,从而防止了潜在的冲突。然而这个规则不足以保护多处理器机器上的数据,在多处 理器机器中你还需要另外的防护措施——自旋锁(spin lock)。如果你仅关心单CPU上的操作,那么使用IRQL就可以解决所有同步问题。但事实上,所有WDM驱动程序都必须设计成能够运行在多处理器的系 统上。
IRQL与线程优先级
线程优先级是与IRQL非常不同的概念。线程优先级控制着线程调度器的调度动作,决定何时抢先运行线程以及下一次运行什么线程。然而,当IRQL级 高于或等于DISPATCH_LEVEL级时线程切换停止,无论当前活动的是什么线程都将保持活动状态直到IRQL降到DISPATCH_LEVEL级之 下。而此时的“优先级”仅指IRQL本身,由它控制到底哪个活动该执行,而不是该切换到哪个线程的上下文。
IRQL和分页
执行在提升的IRQL级上的一个后果是,系统将不能处理页故障(系统在APC级处理页故障)。这意味着:
执行在高于或等于DISPATCH_LEVEL级上的代码绝对不能造成页故障。
这也意味着执行在高于或等于DISPATCH_LEVEL级上的代码必须存在于非分页内存中。此外,所有这些代码要访问的数据也必须存在于非分页内 存中。最后,随着IRQL的提升,你能使用的内核模式支持例程将会越来越少。
DDK文档中明确指出支持例程的IRQL限定。例如,KeWaitForSingleObject 例程有两个限 定:
- 调用者必须运行在低于或等于DISPATCH_LEVEL级上。
- 如果调用中指定了非0的超时,那么调用者必须严格地运行在低于DISPATCH_LEVEL的IRQL上。
上面这两行想要说明的是:如果KeWaitForSingleObject真的被阻塞了指定长的时间(你指定的非0超时),那么你必定运行在低于 DISPATCH_LEVEL的IRQL上,因为只有在这样的IRQL上线程阻塞才是允许的。如果你所做的一切就是为了检测事件是否进入信号态,则可以执 行在DISPATCH_LEVEL级上。但你不能在ISR或其它运行在高于DISPATCH_LEVEL级上的例程中调用 KeWaitForSingleObject例程。
IRQL的隐含控制
在大部分时间里,系统都是在正确的IRQL上调用驱动程序中的例程。虽然我们还没有详细地讨论过这些例程,但我希望举一个例子来表达这句话的含义。 你首先遇到的I/O请求就是I/O管理器调用你的某个派遣例程来处理一个IRP。这个调用发生在PASSIVE_LEVEL级上,因为你需要阻塞调用者线 程,还需要调用其它支持例程。当然,你不能在更高的IRQL级上阻塞一个线程,而PASSIVE_LEVEL也是唯一能让你无限制地调用任何支持例程的 IRQL级。
如果你的派遣例程通过调用IoStartPacket 来排队IRP,那么你第一个遇到的请求将发生在I/O管理 器调用你的StartIo例程时。这个调用发生在DISPATCH_LEVEL级,因为系统需要在没有其它例程(这些例程能在队列中插入或删除IRP)干 扰的情况下访问I/O队列。回想一下前面提到的规则:所有对共享数据的访问都应该在同一(提升的)IRQL级上进行。因为每个能访问IRP队列的例程都执 行在DISPATCH_LEVEL级上,所以任何例程在操作队列期间都不可能被打断(仅指在单CPU系统)。
之后,设备可能生成一个中断,而该中断的服务例程(ISR)将在DIRQL级上被调用。设备上的某些寄存器也许不能被安全地共享。但是,如果你仅在 DIRQL上访问那些寄存器,可以保证在单CPU计算机上没人能妨碍你的ISR执行。如果驱动程序的其它代码需要访问这些关键的硬件寄存器,你应该让这些 代码仅执行在DIRQL级上。KeSynchronizeExecution 服务函数可以帮助你强制执行这个规则,我 将在第七章的“与中断处理连接”段中讨论这个函数。
再往后,你应该安排一个DPC调用。DPC例程执行在DISPATCH_LEVEL级上,它们需要访问你的IRP队列,并取出队列中的下一个请求, 然后把这个请求发送给StartIo例程。你可以调用IoStartNextPacket 服务函数从队列中提取下一个 请求,但必须在DISPATCH_LEVEL级上调用。该函数在返回前将调用你的StartIo例程。注意,这里的IRQL吻合得相当巧妙:队列访问,调 用IoStartNextPacket,和调用StartIo都需要发生在DISPATCH_LEVEL级上,并且系统也是在这个IRQL级上调用DPC 例程的。
尽管明确地控制IRQL也是可能的,但几乎没有理由这样做,因为你需要的IRQL和系统调用你时使用的IRQL总是相应的。所以不必不时地提高 IRQL,例程希望的IRQL和系统使用的IRQL几乎总是正确对应的。
IRQL的明确控制
如果必要,你还可以在当前处理器上临时提升IRQL,然后再降回到原来的IRQL,使用KeRaiseIrql 和KeLowerIrql 函 数。下面代码运行在PASSIVE_LEVEL级上:
KIRQL oldirql; <--1 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); <--2 KeRaiseIrql(DISPATCH_LEVEL, &oldirql); <--3 ... KeLowerIrql(oldirql); <--4 |
- KIRQL定义了用于保存IRQL值的数据类型。我们需要一个变量来保存当前IRQL。
- 这个ASSERT断定了调用KeRaiseIrql的必要条件:新IRQL必须大于或等于当前IRQL。如果这个关系不成 立,KeRaiseIrql将导致bug check。(即用死亡蓝屏报告一个致命错误)
- KeRaiseIrql把当前的IRQL提升到第一个参数指定的IRQL级上。它同时还把当前的IRQL值保存到第二个参数指定的变量 中。在这个例子中,我们把IRQL提升到DISPATCH_LEVEL级,并把原来的IRQL级保存到oldirql 变 量中。
- 执行完任何需要在提升的IRQL上执行的代码后,我们调用KeLowerIrql把IRQL降低到调用KeRaiseIrql时的级 别。
DDK文档中提到,你必须用与你最近的KeRaiseIrql调用所返回的值调用KeLowerIrql。这在大的方面是对的,因为你提升了 IRQL就必须再降低它。然而,由于你调用的代码或者调用你的代码所做的各种假设会使后面的决定变得不正确。所以,文档中的这句话从严格意义上讲是不正确 的。应用到KeLowerIrql函数的唯一的规则就是新IRQL必须低于或等于当前IRQL。
当系统调用你的驱动程序例程时,你降低了IRQL(系统调用你的例程时使用的IRQL,或你的例程希望执行的IRQL),这是一个错误,而且是严重 错误,尽管你在例程返回前又提升了IRQL。这种打破同步的结果是,某些活动可以抢先你的例程,并能访问你的调用者认为不能被共享的数据对象。
有一个函数专用于把IRQL提升到DISPATCH_LEVEL级:
KIRQL oldirql = KeRaiseIrqlToDpcLevel(); ... KeLowerIrql(oldirql) |
注意:该函数仅在NTDDK.H中声明,WDM.H中并没有声明该函数,因此WDM驱动程序不应该使用该函数。
原文地址 http://hi.baidu.com/wukongafei/blog/item/7f96853e14fb47fe838b1345.html
发表评论
-
Filter驱动:过滤(修改)接受数据包
2010-04-20 16:18 9310Filter驱动可以实现简单的防火墙功能。它可以过滤所有接收到 ... -
Ndis过滤驱动:拷贝NetBufferList数据
2010-04-19 22:40 9558今天我们来看看如何拷贝NBL中的数据。有时候需要更改数据包中的 ... -
在Filter驱动内核中获取IP地址
2010-04-18 01:48 3893项目开发中有时候需要在Filter驱动中获取有效地Unic ... -
如何在内核中获得当前系统时间
2010-04-16 15:08 2719在 Windows NT 内核中你是无法使用 tim ... -
Filter发送自定义数据详解
2010-04-16 10:30 5757... -
DebugPrint 格式说明符
2010-04-13 19:46 17651) 直接打印字符串。 DbgPrint(“Hello ... -
WDK+Visual Studio 2008配置编译驱动
2010-04-12 23:36 5563Introduction As it is known, ... -
疑问:关于内存释放
2010-04-12 21:33 1454今天碰到一个比较棘手的内存处理问题。 首先来看一个数据结构: ... -
Windows NT 驱动程序开发人员提示 -- 应注意避免的事项
2010-04-10 11:32 2323原讨论链接: http://community.cs ... -
关于DeviceIoControl实现异步的笔记【2】
2010-04-09 23:17 5101前面我们谈到了关于异步I/O的实现:关于DeviceIoCon ... -
关于DeviceIoControl实现异步的笔记【1】
2010-04-08 22:26 11743一直所做的都是同步实现的。当然很多情况这并不是很好的解决问题。 ... -
驱动和应用层的异步通信
2010-04-08 20:55 5405作 者: sislcb时 间: 2008-01-28,11:1 ... -
Windows系统编程之异步I/O和完成端口
2010-04-08 19:40 2317一、 同步I/O和异步I/O ... -
纵横捭阖C++之从异步谈起
2010-04-08 19:31 3217一般来说,简单的异步(Asynchronous)调用是这样一种 ... -
使用DeviceIoControl通信
2010-04-04 22:53 7904在很多时候,某些用户需要与底层驱动有一个交互式的操作,所 ... -
在驱动中使用链表
2010-04-03 14:06 3291文章作者:grayfox 作 ... -
疑问:数据包Length增大的原因
2010-04-01 14:35 1366现象: 自己定义一个仅含有Ethernet Header的数 ... -
疑问:为何无线网卡无法发送数据?
2010-03-30 22:42 4564所有的测试流程表明,程序已经成功的创建新的数据包,然后调用Nd ... -
InsertHeadList和CONTAINING_RECORD
2010-03-29 16:36 3754LIST_ENTRY定义一个双向链表的数据结构: typed ... -
如何区分不同的Filter Module Instance
2010-03-29 14:50 1538前文 说到如何区分不同Filter Module Inst ...
相关推荐
当一个中断正在处理时,若另一个更高级别的中断请求到来,单片机将挂起当前中断处理程序转而去执行更高优先级的中断服务程序,这就是所谓的中断嵌套。 #### 二、程序结构与逻辑 ##### 1. 宏定义与预处理 在程序的...
本章节主要介绍驱动程序中关于同步处理的基本概念、同步与异步的区别、中断请求级的相关知识,以及如何通过同步机制来解决函数不可重入性的问题。 首先,同步处理在驱动程序开发中尤为重要,因为在多线程环境中,多...
中断系统共有5个中断请求源,两个中断优先级,可以实现两级中断服务程序嵌套。每一中断源可用软件独立控制为允许中断或关中断状态,中断优先级均可用软件来设置。 三、AT89S51单片机的中断请求源 AT89S51单片机的...
- 如果在处理一个中断请求的过程中又有更高优先级的中断请求到来,那么单片机会暂时停止当前的中断处理程序,转而去处理更高优先级的中断请求。 - 这种机制进一步提高了系统的响应速度和处理效率。 #### 五、中断...
当这些模块完成特定任务或检测到某个条件时,它们可以通过中断信号线向PS发送中断请求。 实现ZYNQ PS响应PL中断的过程主要包括以下步骤: 1. **中断触发**:在PL中,通过配置中断控制器或者直接使用特定的GPIO引脚...
1 综述了Windows驱动的发展现状,指出了目前存在的问题,详细分析了 WDF模型,包括WDF驱动程序的基本结构、框架对象、I/O模型、电源状态和中断请求级,并分析了 I/O请求包的处理过程和传输方式。 2、根据PCIe的WDF驱动...
这些中断源都有各自的中断请求标志,当满足中断条件时,相应的标志会被置位,向CPU发出中断请求。 中断优先级的设置对于单片机系统的响应速度和处理效率至关重要。51单片机的中断优先级分为两个级别:高优先级和低...
如果同时有多个中断请求发生,具有较高优先级的中断请求将会优先被处理。在一些扩展的51单片机中,已经具备了4个或者更多的优先级以及更多的中断源,以适应更复杂的系统需求。 中断优先级分为查询优先级和执行...
中断是一种异步通信方式,允许CPU暂停当前执行的任务,响应来自硬件或软件的请求。在MIPS中,中断可以分为硬件中断和软件中断,前者通常由外部设备如键盘、网络接口等触发,后者则由操作系统通过特定指令(如`...
AT89S51的中断技术概述主要体现在中断系统能够实时响应中断请求源,中断请求源可以是内部功能部件,如定时器/计数器溢出,也可以是外部设备,如外部中断请求。中断请求发生时,单片机会暂停当前运行的程序,转而执行...
中断控制器在计算机系统中起着至关重要的作用,它负责管理和响应来自硬件或软件的中断请求。在本项目中,我们关注的是一个用Verilog语言编写的中断控制器,它支持两种类型的中断输入:高低脉冲和高低电平。中断输出...
IAP15W4K58S4单片机的中断系统有21个中断请求源,2个优先级,可以实现二级中断服务嵌套。由IE、IE2、INT_CLKO等特殊功能寄存器控制CPU是否相应中断请求;由中断优先级高存器IP、IP2安排各中断源的优先级;同优先级内...
5. **中断请求信号**:当有未屏蔽的中断且具有最高优先级时,产生中断请求信号,传递给处理器。 6. **中断清除逻辑**:处理器响应中断后,通过写入中断清除命令来消除中断状态。 在实际应用中,中断控制器还需要...
一般而言,执行在较高中断请求级(IRQL)的代码需要驻留在非分页池中,因为它们不能触发页故障。 4. **中断请求级(IRQL)**:IRQL是衡量硬件中断和软件事件优先级的指标。IRQL越高,优先级越高。所有用户模式程序...
中断的概念是指当单片机接收到外部或内部的中断请求时,CPU会暂停当前任务,转而执行中断服务程序来处理这个事件。处理完毕后,CPU会返回到中断前的位置,继续未完成的工作。这个过程包括中断响应、保护现场、中断...
当中断正在执行时,如果CPU接收到更高优先级的中断请求,并且已经设置了相应的中断优先级,那么新的中断请求可以打断当前中断处理过程,这就是中断嵌套。在没有设置中断优先级寄存器IP的情况下,51单片机将严格按照...
DSP 中断向量表和中断子向量表是 DSP 控制器中不可或缺的组件,它们负责管理 DSP 控制器的中断请求,并将外设中断映射到 CPU 中断。中断向量表是一个重要的知识点,了解其编写和配置方法对 DSP 控制器的设计和实现...
中断系统是计算机硬件中的一个重要组成部分,它允许CPU在执行正常任务的同时,响应来自硬件设备的突发事件,例如外部中断请求或内部计数器溢出。中断处理机制极大地提升了CPU的工作效率,因为它使得CPU可以在完成...
中断判优是根据中断优先级,找出最高级别的中断源,首先响应其中断请求,处理完后再响应较低一级的中断源。 中断响应是 CPU 接到中断请求信号后,在满足条件的情况下, CPU 进入中断响应周期,自动完成断点保护和...