zh_zh_y
驱动牛犊
驱动牛犊
  • 注册日期2001-10-19
  • 最后登录2005-03-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1149回复:0

各位大虾,大家帮我找问题(大量散分)

楼主#
更多 发布于:2002-06-21 10:30
硬件中断情况简单介绍:
该硬件,有两个ram缓冲区,一个用于发送,一个用于接收。
一旦发送ram为空,就会产生写中断,目的是通知驱动程序现在可以发送数据了。如果发送ram一直为空,这个写中断就会不停产生,即使我们清除了写中断标志位,它还是会产生,因此如果没有数据发送的时候,需要关闭写中断屏蔽位。
        一旦接受ram不为空,会产生读中断。通知驱动读取数据。

发送数据的设计思路:
       当有write irp产生时,进入write分发例程后,打开设备写中断,进入isr,判断是否是我们的写中断,如果是则关闭设备写中断,并调用dpc进行实际的处理。
        


上面我简单的介绍了硬件中断的情况.下面我再简单的介绍一下应用程序和驱动的IRP流程.

应用程序
1.应用程序使用WriteFile,并且使用的是同步方式,也就是需要这个irp返回后,才能够继续处理下一个irp.


驱动程序

   Write---isr-----dpc
   app与driver使用buffer io方式,driver中只有设备扩展使用了nonpage内存,其他没有分配。
   一个irp最大只有4k


1。首先进入JxwWrite写分发例程中:

        IoMarkIrpPending(Irp);
IoStartPacket(fdo,Irp,0,CancelWriteIrp);

//Open device write Interrupt
KeSynchronizeExecution(dx->InterruptObject,
(PKSYNCHRONIZE_ROUTINE)OpenDeviceWriteInterrupt,dx);
return STATUS_PENDING;

OpenDeviceWriteInterrup函数的作用是打开设备的写中断屏蔽,使设备能够产生写中断。


2.由于打开了设备中断,可能会出现两种情况:
     a.如果发送ram不为空,也就是发送ram中已经存在数据,那么不会产生写中断,也就不会进入Isr例程中;
     b.如果发送ram为空,也就是发送ram中已经没有需要发送的数据,那么会产生写中断,并且立刻进入isr;

    
    Isr例程主要步骤:
           //如果是我们的中断
  if(intRegister&IS_WRITE_INTERRUPT)
  {
                   //关闭设备写中断
  CloseDeviceWriteInterrupt(dx); //如果发送ram一直为空,这个写中断就会不停产生,即使我们清除了写中断标志位,//它还是会产生,所以在Isr中,我关闭了设备写中断
 
  //清除写中断标志位
  ClearWriteInterruptFlag(dx);
                  
                  
  IoRequestDpc( fdo, 0, NULL);
  }

3.Dpc
  
if(fdo->CurrentIrp!=NULL)
{
IoAcquireCancelSpinLock(&OldIrql);

if(fdo->CurrentIrp->Cancel)
{
IoReleaseCancelSpinLock(OldIrql);
return;
}
IoSetCancelRoutine(fdo->CurrentIrp, NULL);
IoReleaseCancelSpinLock(OldIrql);


//这个函数是实际处理设备的函数        
KeSynchronizeExecution(dx->InterruptObject,(PKSYNCHRONIZE_ROUTINE)WriteDevice,dx);

CompleteIrp(fdo->CurrentIrp,STATUS_SUCCESS,dx->WriteTotal);

dx->WriteTotal=0;
dx->WriteBuffer=NULL;
}

IoStartNextPacket(fdo,TRUE);

        //如果有irp,那么在打开一次写设备中断
        if(fdo->CurrentIrp!=NULL)
KeSynchronizeExecution(dx->InterruptObject,(PKSYNCHRONIZE_ROUTINE)OpenDeviceWriteInterrupt,dx);




测试情况分析:
测试机两台:1。piii 733,256m内存,win2k系统,测试中没有发现bug;
            2。pii 233,128m内存,win98,测试中出现问题,主要问题是运行某些程序(特别是msdn)时,会导致应用程序停止发送;当运行另一个发送程序时,停止发送的程序,又能够继续发送;

出现这种问题时,可能会是两种状况之一(当停止发送时,通过对命令寄存器的查看):
1。第一种情况,当出现停止发送时,发送ram不为空;
2。第二种情况,当出现停止发送时,发送中断被屏蔽;


我得分析:
出现这种情况,我暂时觉得可能是运行其他程序时,有可能导致中断打开与关闭没有匹配。
本来我希望:当有一个写irp时,打开一次设备写中断,然后在isr中关闭一次写设备中断,调用一次dpc进行一次发送处理。

但是运行某些其他程序时,由于系统是分时系统和irql级别高的程序占先运行,可能导致系统性能降低(对我的驱动来说)。
a。可能会出现在write分发例程中,当打开写设备中断时,但是由于发送ram不为空,系统不产生中断,导致中断丢失;




游客

返回顶部