深圳建立企业网站,最近发生的热点事件,开发一个app需要多少钱,城阳建设局网站首先在获得PCI配置空间资源的时候#xff0c;就要获得中断资源#xff0c;根据CM_PARTIAL_RESOURCE_DESCRIPTOR 结构的 Type 域来区分需要获得什么样的中断资源的时候#xff0c;如果Type类型为#xff1a;CmResourceTypeInterrupt#xff0c;此时需要将中断资源从CM_PART…首先在获得PCI配置空间资源的时候就要获得中断资源根据CM_PARTIAL_RESOURCE_DESCRIPTOR 结构的 Type 域来区分需要获得什么样的中断资源的时候如果Type类型为CmResourceTypeInterrupt此时需要将中断资源从CM_PARTIAL_RESOURCE_DESCRIPTOR中取出 irql (KIRQL) resource-u.Interrupt.Level; //中断级别 vector resource-u.Interrupt.Vector; // 中断向量 affinity resource-u.Interrupt.Affinity; mode (resource-Flags CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive; irqshare resource-ShareDisposition CmResourceShareShared; gotinterrupt TRUE; 获取以上这些信心之后我们就可以注册中断通过IoConnectInterrupt()函数来实现 函数定义如下 IoConnectInterrupt OUT PKINTERRUPT *InterruptObject//指向驱动程序提供的中断对象存储地址该参数随后 //要传递给KeSynchronizeExecution。 OUT PKSERVICE_ROUTINE ServiceRoutine//中断服务例程的入口 IN PVOID ServiceContext//指向驱动指定的即将传递给ISR的参数ServiceContext必须在 //常驻内存中可以是驱动程序创建的设备驱动的设备扩展也可 //以是驱动创建的控制对象的控制拓展还可以是设备驱动分配的 //非分页内存。 IN PKSPIN_LOCK SpinLock OPTIONAL//指向已经初始化的自旋所驱动程序负责自旋所的存 //储并且该自旋所将用来同步被驱动程序其它例程共 //享的数据的访问该参数在ISR处理多个中断向量或 //者驱动程序包含不止一个ISR时需要设置否则驱 //动程序不需要为中断自旋所分配存储空间参数设置 //为NULL。 IN ULONG Vector //输入获取的中断向量 IN KIRQL Irql //输入获取的中断优先级DIRQL IN KIRQL SynchronizeIrql //指明ISR执行所在的DIRQL当ISR需要处理多个中断 //向量或者驱动程序有多个ISR的时候该值选择全部中 //断资源的u.Interrupt.Level中的最高值否则和上面的 //Irql变量相等。 IN KINTERRUPT_MODE InterruptMode//电平触发或者边沿触发 IN BOOLEAN ShareVector //指明中断向量是否是可共享的。 IN KAFFINITY ProcessorEnableMask//指定一个KAFFINITY值用来说明设备中断可以在什 //么样的处理器平台上发生。 IN BOOLEAN FloatingSave //指明是否需要保存设备中断时的浮点堆栈在X86平 //台下该值必须是FALSE。 实际使用时 status IoConnectInterrupt(pdx-InterruptObject, (PKSERVICE_ROUTINE) ISRInterrupt, (PVOID) pdx, NULL, vector, irql, irql, mode, irqshare, affinity, FALSE); 第二个参数为我们自定义的中断服务例程当驱动通过这个函数接收中断之后调用相应的DPC(deferred procedure calls延迟过程调用)处理函数DPC的使用主要是为了提高处理效率。但是首先要注册DPC处理函数通过 VOID KeInitializeDpc( __out PRKDPC Dpc, __in PKDEFERRED_ROUTINE DeferredRoutine, __in_opt PVOID DeferredContext ); 来实现注册DPC处理函数。 实际应用 KeInitializeDpc(pdx-fdo-Dpc,DPCForISR,NULL); BOOLEAN ISRInterrupt(PKINTERRUPT InterruptObject, PDEVICE_EXTENSION pdx) { //中断响应通知硬件该中断已经处理不用再发该中断 WRITE_REGISTER_ULONG((PULONG) pdx-pHBARegs-IntrMask,0x00000001); pdx-inthw_cnt; KeInsertQueueDpc(pdx-fdo-Dpc,pdx-fdo,pdx-fdo-CurrentIrp ); return TRUE; } 在该函数中将中断请求插入到中断处理队列中交由DPC来处理 BOOLEAN KeInsertQueueDpc( __inout PRKDPC Dpc, __in_opt PVOID SystemArgument1, __in_opt PVOID SystemArgument2 ); DPC的标准格式为 KDEFERRED_ROUTINE CustomDpc; VOID CustomDpc( __in struct _KDPC *Dpc, __in_opt PVOID DeferredContext, __in_opt PVOID SystemArgument1, __in_opt PVOID SystemArgument2 ) { ... } 其中参数注意来源 Dpc [in] Caller-supplied pointer to a KDPC structure, which represents the DPC object that is associated with this CustomDpc routine. DeferredContext [in, optional] Caller-supplied pointer to driver-defined context information that was specified in a previous call to KeInitializeDpc. SystemArgument1 [in, optional] Caller-supplied pointer to driver-supplied information that was specified in a previous call to KeInsertQueueDpc. SystemArgument2 [in, optional] Caller-supplied pointer to driver-supplied information that was specified in a previous call to KeInsertQueueDpc. 这里DPC可以这样设计 VOID DPCForISR(IN PKDPC Dpc,IN PVOID Context,IN PVOID fdo,IN PVOID pIrp) { PDEVICE_EXTENSION pdx (PDEVICE_EXTENSION) ((PDEVICE_OBJECT)fdo)-DeviceExtension; KeAcquireSpinLock(pdx-spinLock,pdx-oldIrql); //Int_stat 寄存器由硬件填写的 int_status READ_REGISTER_ULONG((PULONG) pdx-pHBARegs-Int_stat); KdPrint((interrupt!int status is 0x%0x\n,int_status)); while(int_status) //循环处理中断直到处理完 { if(int_status INT_RECV_0 int_status INT_RECV_23) { RecvTask(pdx,int_status-1); pdx-recint_cnt[int_status-1]; } if(int_status INT_LINK0_BUILD int_status INT_LINK3_BUILD) { pdx-rx_fc_desc_buf_virt[int_status-25]-link_state1; pdx-bldint_cnt[int_status-25]; KdPrint((Build!int status is 0x%0x\n,int_status)); } if(int_status INT_LINK0_BREAK int_status INT_LINK3_BREAK) { pdx-rx_fc_desc_buf_virt[int_status-29]-link_state0; pdx-brkint_cnt[int_status-29]; } pdx-intsw_cnt; int_status READ_REGISTER_ULONG((PULONG) pdx-pHBARegs-Int_stat); KdPrint((interrupt!int status is 0x%0x\n,int_status)); } return ; } 在DPC中完成具体的操作这样中断处理就结束了。 转载于:https://www.cnblogs.com/zhuyp1015/archive/2012/03/14/2396630.html