windows驱动开发---中断级(IRQL)

来源:互联网 发布:java生成临时文件 编辑:程序博客网 时间:2024/06/05 12:50

最近开始入门windows 驱动开发,遇到一个IRQL。不知道何解,于是找了些资料,顺带记录下。下面的东西可能有不准确,如发现错误之处请指正,以免误导他人(罪过),谢谢!。

1.什么是中断级(IRQL)

中断是一个大家都很熟悉的概念,这里只通俗的解释一下。假如我正在课堂看小说,这时老师过来了,于是我以大家都有的速度迅速将将小说切换为课本。这个过程中,“老师过来”中断了“看小说”转而为“看课本”。如果把我看成CPU,则“看”即CPU的动作(执行周期),“小说”是CPU当前执行的内容,“老师来了”引发一个中断信号,作为对这个中断信号的响应,CPU执行的内容由“小说”切换为“课本”。老师来了我之所以改看小说为看课本,可能基于两个原因(这也是响应中断的原因):

a.(处理紧急事务)我当时”悠哉的看小说“,老师的到来让我突然有了一个”看课本来骗过老师“的任务,于是我果断执行了。

b.(做更有意义的事情)我觉得看课本比看小说更有出息,所以我也果断执行了。(可能是老师的到来让我觉悟了)

对于不同的中断,其优先级通常是不一样的,即对中断的响应处理优先程度。比如说,我正在马路上走,这时突然前面出现一美女,同时后面出现一加速前进的车。这时,虽然我很想去追那美女,但我必须先停下来先让汽车过去。因为躲过汽车的优先级大于追美女。(话说,被汽车撞飞,一切美女就都是浮云了)。也就是说在处理一大堆中断时,我们是有个急缓先后的处理顺序。

IRQL是中断请求(Interrupt request)和级别(Level)两个词结合,即表示中断的优先级,简称中断级。

2. 选择性的响应中断

   虽然中断信号的到来表示有事情发生了,需要我们去处理。但有些时候,我们并不希望别人来打断我们当前所作的事,除非导致中断信号的事情非处理不可否则有严重的后果。这时我们就需要选择性的响应中断,对于不重要的中断全部屏蔽掉。比如说,一个医生正在实施重要手术,这时医生肯定是不希望被手机铃声打扰的,于是他将手机关机屏蔽手机产生的中断。但手术过程中发现血量不够了,这时他必须暂时停止手术去取血浆(假设只有他一个人在实施手术)。

这个过程就是选择性的响应中断。

3.驱动编程中IRQL的含义

驱动编程时,IRQL表示程序可以响应那些级别中断,而对那些级别的中断可以屏蔽掉。下面是Windows NT头文件中定义的IRQL表:

IRQL

X86 IRQL Value

AMD64IRQL Value

IA64 IRQL Value

Description

PASSIVE_LEVEL

0

0

0

User threads and most kernel-mode operations

APC_LEVEL

1

1

1

Asynchronous procedure calls and page faults

DISPATCH_LEVEL

2

2

2

Thread scheduler and deferred procedure calls (DPCs)

CMC_LEVEL

N/A

N/A

3

Correctable machine-check level (IA64 platforms only)

Device interrupt levels (DIRQL)

3-26

3-11

4-11

Device interrupts

PC_LEVEL

N/A

N/A

12

Performance counter (IA64 platforms only)

PROFILE_LEVEL

27

15

15

Profiling timer for releases earlier than Windows 2000  

SYNCH_LEVEL

27

13

13

Synchronization of code and instruction streams across processors

CLOCK_LEVEL

N/A

13

13

Clock timer

CLOCK2_LEVEL

28

N/A

N/A

Clock timer for x86 hardware

IPI_LEVEL

29

14

14

Interprocessor interrupt for enforcing cache consistency

POWER_LEVEL

30

14

15

Power failure

HIGH_LEVEL

31

15

15

Machine checks and catastrophic errors; profiling timer for Windows XP and later releases



对于驱动编程,我们通常只会接触到 0到2的IRQL以及DIRQL。    

PASSIVE_LEVEL:线程即运行在该中断级别上,它对所有中断都作出响应。用户模式代码都是运行在该中断级别上。

APC_LEVEL:当I/o 操作完成时,系统会产生这个中断。为了响应这个中断,应用程序向I/O 完成中断处理例程队列中插入一个APC回调函数,当I/O完成时,该APC函数被调用。如果你不想对这个中断做出响应,你就可以将IRQL提升至APC_LEVEL。这时当I/O完成时,应用程序将不会受到该中断信号。可以调用KeEnterCriticalRegion或KeEnterGuardedRegion来将IRQL提升至该级别。APC中断通常是由处理器引发,可以想自己发出也可是像其他处理器发出。一般情况下,是不应该的使用的APC_LEVEL的,除非你想使用Fast Mutexes之类的东西。

DISPATCH_LEVEL: 为了能够执行多任务,系统必须允许线程调度。而线程调度的根本就是靠时钟中断来保证的,该级别的中断即调度中断。当你的代码运行的IRQL被提升为DISPATH_LEVEL时,就意味着你的代码不在受线程中断影响力。你的代码会一直运行直到你将IRQL设置为低于DISPATH_LEVEL为止。这中间如果发生缺页错误之类的IRQL级别在DISPATH_LEVEL之下的严重中断时,这些中断均不会被处理。这时,代码将无法正常运行。所以,DISPATH_LEVEL的使用绝对要慎之又慎。只有在是偶那个自旋锁时,你才应该考虑选择该IRQL。

其他IRQL,这里暂不讨论了。

参考资料:http://blogs.msdn.com/b/doronh/archive/2010/02/02/what-is-irql.aspx




原创粉丝点击