中断处理

首先在获得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_state=1;

                            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_state=0;

                            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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java calendar计算时间差_Java Calendar 计算时间差

linux下创建文件与目录时默认被赋予了什么样的权限&quest;当我们创建一个新的文件或目录的时候,他的默认权限是什么? umask--指定当前使用者在创建文件或目录的时候默认的权限值 [rootiZ288fgkcpkZ default]# umask [roo ...x86平台转x64平台关于内联汇编不再支持的解决x8…

SVG-不是图片的图片

SVG-不是图片的图片 导语&#xff1a; 可缩放矢量图形&#xff08;Scalable Vector Graphics&#xff0c;SVG&#xff09;是基于可扩展标记语言&#xff08;XML&#xff09;&#xff0c;用于描述二维矢量图形的一种图形格式。SVG由W3C制定&#xff0c;是一个开放标准。另SVG还是…

LeetCode 1490. 克隆 N 叉树(DFS/BFS)

文章目录1. 题目2. 解题2.1 DFS2.2 BFS1. 题目 给定一棵 N 叉树的根节点 root &#xff0c;返回该树的深拷贝&#xff08;克隆&#xff09;。 N 叉树的每个节点都包含一个值&#xff08; int &#xff09;和子节点的列表&#xff08; List[Node] &#xff09;。 class Node …

奇数阶幻方 java_N(奇数)阶幻方-java实现代码

看完最强大脑&#xff0c;有一期是说N阶幻立方的&#xff0c;作为一个程序员&#xff0c;我的第一反应时我可以用程序实现&#xff0c;在此公布N(奇数)阶幻方的java实现代码&#xff1a;package com.lzugis.test;public class Practice {public static int[][] magicOdd(int n)…

NSDateFormatter设定日期格式

部分日期格式的总结&#xff1a; NSDateFormatter * dateFormatter [[[NSDateFormatter alloc] init]autorelease]; [dateFormatter setAMSymbol:"AM"]; [dateFormatter setPMSymbol:"PM"]; [dateFormatter setDateFormat:"dd/MM/yyyy hh:mmaaa"…

LeetCode 1265. 逆序打印不可变链表(递归)

文章目录1. 题目2. 解题1. 题目 给您一个不可变的链表&#xff0c;使用下列接口逆序打印每个节点的值&#xff1a; ImmutableListNode: 描述不可变链表的接口&#xff0c;链表的头节点已给出。 您需要使用以下函数来访问此链表&#xff08;您 不能 直接访问 ImmutableListNo…

zz面试题小结

如果搞过ACM的人&#xff0c;找工作的确很好找&#xff0c;基本微软、百度之类都可以很容易拿到offer&#xff0c;我不是算法牛人&#xff0c;没搞过ACM&#xff0c;没拿过什么奖&#xff0c;没进过什么实验室&#xff0c;水平一般&#xff0c;所以更能代表大众吧。 总结一些常…

java流的传递方式是_java中数据的传递方式到底是怎样的!

今天早上我了一道有关java的题。主要考点是考java中值得传递方式。之前我在javaoo里总结的是&#xff1a;基本数据类型中保存的是实际的值,引用数据类型保存的是被引用的内存地址&#xff0c;那么基本数据类型就是按值传递&#xff0c;引用数据类型就是按地址来传递的。(难道我…

LeetCode 408. 有效单词缩写

文章目录1. 题目2. 解题1. 题目 给一个 非空 字符串 s 和一个单词缩写 abbr &#xff0c;判断这个缩写是否可以是给定单词的缩写。 字符串 “word” 的所有有效缩写为&#xff1a; ["word", "1ord", "w1rd", "wo1d", "wor1&qu…

java 钩子线程_java-钩子线程

在线上Java程序中经常遇到进程程挂掉&#xff0c;一些状态没有正确的保存下来&#xff0c;这时候就需要在JVM关掉的时候执行一些清理现场的代码。Java中得ShutdownHook提供了比较好的方案。JDK在1.3之后提供了Java Runtime.addShutdownHook(Thread hook)方法&#xff0c;可以注…

LeetCode 604. 迭代压缩字符串

文章目录1. 题目2. 解题1. 题目 对于一个压缩字符串&#xff0c;设计一个数据结构&#xff0c;它支持如下两种操作&#xff1a; next 和 hasNext。 给定的压缩字符串格式为&#xff1a;每个字母后面紧跟一个正整数&#xff0c;这个整数表示该字母在解压后的字符串里连续出现的…

java郝斌_郝斌Java自学教程全集打包

课程介绍&#xff1a;1_Java概述_12_Java概述_23_Java概述_34_Java的卸载5_Java的安装6_环境变量的设置7_常见dos命令 文件名和类名不同时编译运行的问题8_变量命名规则 数据类型 运算符 格式化输出 流程控制9_复习上节课10_类和对象11_内存分配12_访问控制符_113_访问控制符_2…

LeetCode 1056. 易混淆数(哈希)

文章目录1. 题目2. 解题1. 题目 给定一个数字 N&#xff0c;当它满足以下条件的时候返回 true&#xff1a; 原数字旋转 180 以后可以得到新的数字。 如 0, 1, 6, 8, 9 旋转 180 以后&#xff0c;得到了新的数字 0, 1, 9, 8, 6 。 2, 3, 4, 5, 7 旋转 180 后&#xff0c;得到…

hoj2677 Instruction Set // poj3253Fence Repair 哈夫曼树

/* 哈弗曼编码&#xff0c;比如权值为 a:1 b:1 c:2 d:3 e:5 f:6 的树 1.开始时由最小的两个数 a:1 b:1组成一棵树 2.接着由新的最小的两个数 2 c:2 d:3 e:5 f:6 中的 2 c:2组成新的树 3.接着由最小的两个数 4 d:3 组成新的树 4.接着由最小的两个数 e:5 f:6 组成一棵树 5.接着由…

java数组的实现_Java数组HashCode实现

这很奇怪。一位同事询问了java中myArray.hashCode()的实现。我以为我知道&#xff0c;但是后来我进行了一些测试。检查下面的代码。我注意到的奇怪想法是&#xff0c;当我编写第一个系统时&#xff0c;结果是不同的。请注意&#xff0c;这几乎就像报告内存地址并修改类一样&…

LeetCode 624. 数组列表中的最大距离

文章目录1. 题目2. 解题2.1 暴力超时2.2 优化1. 题目 给定 m 个数组&#xff0c;每个数组都已经按照升序排好序了。 现在你需要从两个不同的数组中选择两个整数&#xff08;每个数组选一个&#xff09;并且计算它们的距离。 两个整数 a 和 b 之间的距离定义为它们差的绝对值 |…

strcpy()函数一个简单那程序来了解一下它。。

View Code #include <stdio.h>#include <string.h>int main() { char a[5] "ABCD"; char b[8] "abcdefg"; char c[8] "abcdefg"; char d[5] "ABCD";strcpy(a,b); //长的复制给短的strcpy(c,d);//短的复制给长的print…

java怎么调用7zip进行压缩_JAVA使用7-zip解压缩带密码的Zip文件(非Proccess方法)...

首先到sourceforge网站下载sevenzipjbinding压缩包我下载的版本是sevenzipjbinding-4.65-1.04-rc-extr-only-AllWindows.zippublicvoidunzipDirWithPassword( final String sourceZipFile ,final String destinationDir , final String password ){RandomAccessFile randomAcce…

LeetCode 156. 上下翻转二叉树(DFS)*

文章目录1. 题目2. 解题1. 题目 给定一个二叉树&#xff0c;其中所有的右节点要么是具有兄弟节点&#xff08;拥有相同父节点的左节点&#xff09;的叶节点&#xff0c;要么为空 将此二叉树上下翻转并将它变成一棵树&#xff0c; 原来的右节点将转换成左叶节点。返回新的根。 …

httpd 分页_更改 Apache httpd.conf 配置文件

提示&#xff1a;如果在虚拟主机商配置&#xff0c;请直接配置第三、四步&#xff0c;因为支持 .htaccess 的空间已经配置好了前面两步。用编辑器打开 Apache 配置文件 httpd.conf(该文件位于 Apache 安装目录Apache2conf)&#xff0c;并按如下步骤修改&#xff0c;。一、加载了…