阅读:1535回复:18
基于ISA卡的VxD驱动捕获中断的问题
我前两天在microsoft.public.development.device.drivers发了帖子询问,但是估计老外们看了我写的英文没有几个活下来的。有一个坚强的还回了帖,真令人敬佩!下面是我发的帖,估计咱中国人都看得懂,
Hello all: I made a VxD to handle a interrupt from an ISA card. I made it by VToolsD. In interrupt handle, a page faule occured. Here it is: VOID XMyIRQ::OnHardwareInt(VMHANDLE hVM) { assert(hVM); Out_Debug_String(\"assert(hVM) OK!\\n\"); MyGlobalEvent* pEvent = new MyGlobalEvent(); Out_Debug_String(\"Create new event OK!\\n\"); if (pEvent) pEvent->schedule(); // <<--debug message:Break due to page fault(0Eh) //interrupt over pIRQ->sendPhysicalEOI(); // tell VPICD to clear the interrupt Out_Debug_String(\"VPICD_Phys_EOI(hIRQ) OK!\\n\"); } In SoftIce, I press continue, it will continue. And go in MyGlobalEvent::handler. Here it is: VOID MyGlobalEvent::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, PVOID refData) { // whatever your handler does // (now safe to use any VMM service) Out_Debug_String(\"In Event handler,read CN1!\\n\"); UCHAR i; i=_inp(CN1); Out_Debug_Chr(i); // pIRQ->sendPhysicalEOI(); // tell VPICD to clear the interrupt // Out_Debug_String(\"VPICD_Phys_EOI(hIRQ) OK!\\n\"); Out_Debug_String(\"\\nInvoke the callback!\\n\"); _VWIN32_QueueUserApc(ring3func, (DWORD)i, TheThread); //<<--here ,a lot of page faults were shown, at last, it\'s hang. } I\'m a greenhand in this part. Please help me! 这个是老外的回帖: I\'m not quite sure if you can allocate memory (call new) in the interrupt handler. 我的疑问是:我完全按照VToolsD所提供的方法写的,这是VTooolsD提供的例程: VOID XEOC_IRQ::OnHardwareInt(VMHANDLE hVM) { //dprintf(\"DATAACQ: IRQ index %d\",dataindex); *pdatacursor = _inp(data_ac_base+0); pdatacursor++; dataindex++; // schedule a global event if (dataindex==buffersize) { EOC_GlobalEvent* pEvent = new EOC_GlobalEvent(); if (pEvent) { pEvent->schedule(); dataindex=0; pdatacursor=(PCHAR)pdatabase; } else { dataindex--; pdatacursor--; } } pEOC_IRQ->sendPhysicalEOI(); } 我的VxD运行时,能捕获第一个中断,但以后就是Page Fault了,现在更惨:一有中断,机子就重启。 我不明白为什么我用的就是错的,它提供的例程是关于数据采集的,我没办法试。我写的程式是按照它的说明文档写的,并且例程也与我写的相符,为什么一运行就会出错?说明文档中介绍得很清楚,应该在GlobalEvent中调用服务,不能在中断服务中调用。 我几乎是把说明文档中的例程临摹下来的,可还是PageFault,请大虾指点!! 另外请问:在VxD处理中断的环境中,能否用APC的方式与Win32 App通讯?我在两个资料中看到两种答案,不知道该相信哪一种。请高手指点!分不是问题,只要能帮我搞通,我可以蹲在这里给大家泡分! 附件是VxD和应用程式主要的源文件 |
|
|
沙发#
发布于:2003-03-08 10:28
怎么有new没有delete?
|
|
板凳#
发布于:2003-03-08 16:57
非要用apc吗?
|
|
地板#
发布于:2003-03-08 23:44
当然不一定用APC,只不过比Event简单,只要能通过,什么都行!
求楼上大哥指点指点,我是个新手,都是自己摸索的,好困难哪。 帮帮忙吧! :D :D :D |
|
地下室#
发布于:2003-03-09 12:03
你的ring3 function要干什么呢?
|
|
5楼#
发布于:2003-03-10 12:59
情况是这样的:
一个ISA卡,每秒钟有200次中断,程序要对中断计数,并且有中断来驱动整个程序运作。我的设想是这样的:VXD捕获中断后,对中断计数,然后发送消息(以计数值为参数)驱动主程序,请问这样是否可行,我写的程序是否有漏洞,所以才会有页面错误?请指教! |
|
6楼#
发布于:2003-03-10 16:50
我都是用event的,apc还真是没有用过。 :D
vxd向app发消息也可以的。 |
|
7楼#
发布于:2003-03-10 17:32
我是个新手,只对VxD了解一些皮毛,书上讲Event 比APC复杂,但比APC效率高。既然大侠擅长Event,那就请帮我看看这段代码,为什么会有页面错误呢?我是照着VToolsD的例子写的,怎么还有错?
VOID XMyIRQ::OnHardwareInt(VMHANDLE hVM) { assert(hVM); MyGlobalEvent* pEvent = new MyGlobalEvent(); if (pEvent) pEvent->schedule(); // <<--debug message:Break due to page fault(0Eh) //interrupt over ...... } 详细的程序在最上面的附件里有,请大侠一定帮帮忙,我已经困在这里有好几个月了! :( :( :( |
|
8楼#
发布于:2003-03-10 22:37
你用si看看pEvent
vtoolsd说可以在interrupt level用new,但是还是看看吧。 |
|
9楼#
发布于:2003-03-11 10:52
您说的si是softICE 吧,
您的意思是vtoolsd说可以在interrupt level用new 这个结论并不正确是吗? 我又看了两天书,看出我的程序是个四不象,APC 和Event两种方法都有,我决定用Event的方法,但是VToolsD生成的代码里缺少了很多东西,比如说一些参数。我该怎么用呢?请指教! |
|
10楼#
发布于:2003-03-12 16:03
我和那个老外的想法一样。我曾经在中断中分配M,也死机,就是在GlobalEvent中也一样。所以要另想办法。我目前还没有好办法。
|
|
11楼#
发布于:2003-03-12 17:52
我也有过这样的想法,不过VToolsD附带的例子中就有在中断中new Event的,我把它编译出来,用DriverMonitor载入了一下,一切正常,但是由于我没有中断,SoftICE的Genint也不大会用,所以没有在试。我的程序也是一样的,能够new Event,但是在中断处理过程中出现页面错误,机器down掉。我现在正在努力改写自己的程序,向例子靠拢,我就不信搞不定!
下面是例子代码中的部分代码: VOID XEOC_IRQ::OnHardwareInt(VMHANDLE hVM) { //dprintf(\"DATAACQ: IRQ index %d\",dataindex); *pdatacursor = _inp(data_ac_base+0); pdatacursor++; dataindex++; // schedule a global event if (dataindex==buffersize) { EOC_GlobalEvent* pEvent = new EOC_GlobalEvent(); if (pEvent) { pEvent->schedule(); dataindex=0; pdatacursor=(PCHAR)pdatabase; } else { dataindex--; pdatacursor--; } } pEOC_IRQ->sendPhysicalEOI(); } |
|
12楼#
发布于:2003-03-14 14:09
这是个VxD编程中的问题,各种资料上都说在事件处理函数中可以安全的调用各种服
务,我调用_SHELL_PostMessage向主程序窗口发送消息,可是会有页面错误,请问怎样 解决。 VOID MyGlobalEvent::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, PVOID refData) { Out_Debug_String(\"In Event handler\\n\"); ... ... if(_SHELL_PostMessage(msg->hWinhandle,msg->MessageID, (WORD)pos, (DWORD)0, 0, 0)) //这里产生页面错误, { Out_Debug_String(\"PostMessage OK!\\n\"); } else { Out_Debug_String(\"PostMessage Error!\\n\"); } } msg: struct msgbuf { HANDLE hWinhandle; //windows handle 存储从主程序传过来的窗口句柄 UINT MessageID; //Message ID } *msg; |
|
13楼#
发布于:2003-03-14 15:54
用DriverMonitor载入VxD后,启动,捕获中断一切正常,也能够发送消息(当然,此时的msg->hWinhandle,msg->MessageID的值都是没有意义的)
但是用主程序运行,载入VxD,启动正常,中断来了之后,在Event handle中 _SHELL_PostMessage出现页面错误,估计可能是msg->hWinhandle的值导致的,请问哪位知道正确的方法,怎样避免这个页面错误? msg->hWinhandle的值是主程序窗口的handle,我看到_SHELL_PostMessage的第一个参数是handle of a window,于是从主程序的this->hWnd将窗口handle传过来。 |
|
14楼#
发布于:2003-03-14 21:14
这种方式频率不能做很高,我以前也碰到过,后来频率降低就好了,晕
|
|
15楼#
发布于:2003-03-14 22:34
我现在做的VxD要相应的中断是200Hz的,请问这个频率是否很高?
据我想应该不会吧? 我现在只要能顺利运行就可以,无论什么方法。请帮忙看看到底是什么地方错了。多谢! |
|
16楼#
发布于:2003-03-24 22:23
受益匪浅!!
|
|
17楼#
发布于:2003-08-04 11:01
很受用,谢谢!!!
|
|
18楼#
发布于:2003-08-19 20:11
我以前也怀疑过ISA的中断频率问题,
但是我的卡要求2100Hz的中断. 在我经过无数次的思考,修改,测试后,做到了2100Hz,而且系统很稳定. |
|
|