设备触发中断后进入的例程
当进入中断服务例程后,IRQL会提升到设备对应的IRQL级别
传统PC用2片 中断控制器8259A 芯片级联-》16个中断信号源 0-15 多个设备可以共享一个中断号
新的PC使用新的中断控制器,将中断信号扩展到24个
Windows 将中断的概念继续拧扩展 32个中断级别 IRQL
0-2 级别 PASSIVE_LEVEL 到 DISPATCH_LEVEL 软中断
3-31 硬件中断
0-31 级别逐次升高
一般线程在0 界别,负责调度线程的内核代码运行再1 级别
DDK把硬件中断称为 DIRQL
中断服务例程 ISR
发生硬件设备的中断信号后,DIRQL级别下,系统调用相应的ISR
驱动程序使用ISR
1)首先 获得 中断对象 (INTERRUPT的数据结构) DDK驱动和 WDM驱动不同 以后学习
2)IoConnectInterrupt 将中断对象和ISR 联系起来,这样中断信号来临时就会进入 ISR处理
ISR运行再DIRQL级别
为了不让ISR打断运行,秩序将IRQL提升至相应的DIRQL即可
与ISR 函数同步的函数
BOOLEAN KeSynchronizeExecution( //Synchronize 是同步的意思 IN PKINTERRUPT Interrupt, //中断指针 ISR与这个对象关联着 IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, //将当前IRQL提升至 中断对象相应的DIRQL,并执行这个例程 IN PVOID SynchronizeContext //上面这个例程的参数 );
当运行到这个函数时,ISR不会打断 它 提供的例程,需要将同步代码放入 它提供的例程
DPC例程
和 中断 服务例程配合使用
中断服务例程处于很高的IRQL,会打断正常运行的线程
DPC例程运行再相对较低的 DISPATCH_LEVEL级别,
因此一般将不紧急处理的代码放在DPC例程中,
紧急的代码放在中断服务例程中
延迟过程调用例程DPC
运行再1 上级别,除了ISR 其他例程不会打断
一般 ISR运行时间不宜长
ISR代码尽量少
不重要的响应代码 从ISR -》DPC例程中
DpcForISR
使用DPC例程
1)初始化DPC对象 KeInitializeDpc (一般在DriverEntry + AddDevice 中初始化)
KeInitializeDpc(&dpx->DPC, DpcForISR,(PVOID)context);
VOID KeInitializeDpc( IN PRKDPC Dpc, //需要初始化的DPC对象指针 IN PKDEFERRED_ROUTINE DeferredRoutine, //DPC关联的DPC例程 IN PVOID DeferredContext //传入DPC例程的参数 );
ISR中执行简单的处理,不重要的放入DPC例程