libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1553回复:15

大家看看我的代码有错误码?为什么偶尔蓝屏??

楼主#
更多 发布于:2004-02-25 16:40
下面是我用DS写的ISA卡的NT式的驱动的部分程序,运行在WIN2000上,中断方式获得数据,具体工作原理是:
在驱动的初始化例程(DDK里就是驱动入口点例程),驱动分配一个非分页内存Buf用来在中断延迟例程里存放从端口读到的数据,驱动程序通过一个DeviceIoCtl把该内存影射后的用户虚拟地址传递给应用层。
应用层分配一个事件对象通过DeviceIoCtl传递给驱动层,在中断延迟里驱动读完端口设置事件对象为有效,来通知应用, 可以操作这个缓冲里的数据了。
就是通过这样的方式达到硬件和驱动,驱动和应用通信。
我下面给出了四个例程,分别是:分配非分页内存的驱动初始化例程(部分);传递事件对象例程;中断延迟例程;中断例程。
各位看一看,中断和中断延迟调用部分的代码规范吗?我现在的问题是驱动运行的时候很不稳定,偶尔发生蓝屏的现象,
SOFTICE 弹出以下的提示:
   Break due to Page Fault(0Eh) Fault=0003
      MSR LastExceptionFromIp=00000000
       MSR LastExecptionToIp=00000000
另外我用DriverMonitor还看到这样一条提示:
An underrun error occured in memory block f9d6dc30.
这个没导致蓝屏,只是经常提示


////////////////////////////////////////////////////////////////////////
//  初始化函数,建立设备的资源请求对象,向系统申请资源
/////////////////////////////////////////////////////////////////////////
  
NTSTATUS  JiemaDevice::InitResources(void)
{
        ……………………
        ……………………
        //分配中断延迟调用例程里驱动要使用的缓冲
Buf=new(NonPagedPool)UCHAR(68);
        ……………………
        ……………………
}


//////////////////////////////////////////////////////////////////////////
////接收来自应用层发来的事件对象
////采用缓冲I/O方式
//////////////////////////////////////////////////////////////////////////

NTSTATUS JiemaDevice::EVENT_IOCTL_800_Handler(KIrp I)
{


t << "Entering JiemaDevice::EVENT_IOCTL_800_Handler, " << I << EOL;
DbgPrint("the irql is %x\n",KeGetCurrentIrql());

HANDLE hEvent=*(HANDLE*)I.IoctlBuffer();
m_pEvent=new(NonPagedPool)KEvent(hEvent);
        NTSTATUS status=(m_pEvent!=NULL)?STATUS_SUCCESS:STATUS_INSUFFICIENT_RESOURCES;
I.Information() =0;
        I.Status() = status;

return status;
}
///////////////////////////////////////////////////////////////////////
//  中断延迟处理程序
// 用事件对象来通知应用程序,中断到来,数据准备好,可以//  读数据了
////////////////////////////////////////////////////////////////////////

VOID JiemaDevice::DpcFor_Irq(PVOID Arg1, PVOID Arg2)
{
         m_IoPortRange1.inw(0);
        m_IoPortRange1.inw(2);

/////////////////////////////////////////////////////////////////////////
///////从端口对象1接收28路解码数据的第1-16路/////////////////////////////

for (ULONG i=4;i<32;i=i+2)
  {
 m_IoPortRange1.inw(i,(PUSHORT)Buf+i/2-2,1);
  }
////////////////////////////////////////////////////////////////////////
///////从端口对象2接收28路解码数据的第17-24路///////////////////////////
////////////////////////////////////////////////////////////////////////
   for(ULONG j=0;j<16;j=j+2)
   {
m_IoPortRange2.inw(j,(PUSHORT)Buf+14+j/2,1);
   }

////////////////////////////////////////////////////////////////////////
///////从端口对象3接收28路解码数据的第25-28路//////////////////////////
    for(ULONG l=0;l<7;l=l+2)
   {
m_IoPortRange3.inw(l,(PUSHORT)Buf+22+l/2,1);
   }
     m_IoPortRange3.inw(10,(PUSHORT)Buf+26,1);
m_IoPortRange3.inw(12,(PUSHORT)Buf+27,1);
 
////////////////////////////////////////////////////////////////////////
//////// 从端口对象4接收6个字的时码数据//////////////////////////////
 for(ULONG w=0;w<12;w=w+2)
 {
         m_IoPortRange4.inw(w,((PUSHORT)Buf)+28+w/2,1);
 }
//设置事件对象为有效,通知应用层可以读该缓冲区了
   m_pEvent->Set();
}
////////////////////////////////////////////////////////////////////////
//  中断处理程序
//  确认中断的发生,统计中断次数
////////////////////////////////////////////////////////////////////////
BOOLEAN JiemaDevice::Isr_Irq(void)
{
m_DpcFor_Irq.Request(NULL, NULL);
return TRUE;
}
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
xxiezhen
驱动牛犊
驱动牛犊
  • 注册日期2004-02-11
  • 最后登录2004-06-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-02-25 19:21
我想是中断的问题吧,在中断例程应该先判断一下是不是自己的硬件产生的中断
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-02-25 19:28
谢谢楼上大哥的回答,我想ISA卡的中断,是固定的,也就是独占的,我能成功申请到我的板卡使用的中断,那么当我的板卡中断到来的时候,就能自动进入我的中断服务例程,我想这个没什么问题吧,我觉得是内存的问题,但实在是找不到内存出错的地方!
真是着急!
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
xxiezhen
驱动牛犊
驱动牛犊
  • 注册日期2004-02-11
  • 最后登录2004-06-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-02-25 19:35
ISA的中断也是通过8259A中断控制寄存器控制的
所以它还是一个共享的中断

xxiezhen
驱动牛犊
驱动牛犊
  • 注册日期2004-02-11
  • 最后登录2004-06-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-02-25 19:40
我做PCI也是遇到和你一样的问题
就是判断了中断是不是自己的硬件产生的后才没再出现
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-02-25 19:42
但是我的主板上使用我板卡中断号的设备只有我自己设计的板卡,所以不存在共享的问题,所以也不需要判断。
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
xxiezhen
驱动牛犊
驱动牛犊
  • 注册日期2004-02-11
  • 最后登录2004-06-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-02-25 19:48
我也不明白,只是把我的体会说一下
像我的pci也是那样子的,你可以试试看

libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-02-25 19:52
我做PCI也是遇到和你一样的问题
就是判断了中断是不是自己的硬件产生的后才没再出现
 


我认为PCI 的中断资源是共享的,也就是同一个中断号可能被多个设备使用,但在一个时间点上只能被一个设备使用,所以需要判断是哪个设备发来的中断。
ISA的中断是独占的,我修改了主板的BIOS把我板卡需要的中断号IRQ5的设置成:
PnP/PCI configurations -> Resources controlled by -> manual -> IRQ -> IRQ5 assigned to -> legacy ISA

这样就不需要判断是不是我自己的设备来的中断了。
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-02-25 19:53
我也不明白,只是把我的体会说一下
像我的pci也是那样子的,你可以试试看

 


你能详细说说的你的PCI的驱动,在用SOFTICE调试的时候出现的是什么样的错误吗??
写出它的错误提示。
谢谢!
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-02-26 15:22
顶!
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
changjt
驱动牛犊
驱动牛犊
  • 注册日期2002-12-09
  • 最后登录2010-01-27
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-02-27 08:29
我也帮你顶顶,说不定会有人旁观者清。
但凡驱动引起的蓝屏,99%都是因为在驱动中访问了不存在的内存地址所致。
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-02-27 09:28
我也帮你顶顶,说不定会有人旁观者清。
但凡驱动引起的蓝屏,99%都是因为在驱动中访问了不存在的内存地址所致。


我也是这么认为的,但我的程序里中断例程和中断延迟调用里,对自己用NEW操作符在堆里分配的非分页内存Buf的操作,从语法上说没产生越界,那什么地方访问了不存在的内存地址呢?Buf的删除我放在了Shtudown例程里,也就是只有在系统关闭的时候,我才真正使这个内存无效。

我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
12楼#
发布于:2004-02-27 13:47
把Buf的地址打印看看是不是和riverMonitor显示underrun的地址一样
既然shutdown了无所谓释放内存了
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-02-27 14:12
把Buf的地址打印看看是不是和riverMonitor显示underrun的地址一样
既然shutdown了无所谓释放内存了


在中断延迟里读端口之前加上这个:
t<<"Buf address is:"<<(ULONG)Buf<<"\n";
这样做可以吧?
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
14楼#
发布于:2004-02-27 19:08
申请内存成功了就可以打印了,一次足矣
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-02-27 20:36
我刚才打印了申请到的Buf地址,是f9f84aa8,softice 显示的信息这次没有内存溢出。但在关机的时候,弹出错误:
Break Due to KeBugCheckEx(Unhandled kernel modle exception)
Error=c2(BAD POOL CALLER)
P1=7;P2=b8a;P3=f9f84ac0,P4=f9f84ac8


释放了已经释放的内存,f9f84ac0是被释放的内存池的头地址,我真的闹部明白,我的Buf申请到了68字节,f9f84ac0正是我申请的Buf内部的一个地址,在关闭之前我没释放过,为什么会提示我有这样的错误呢??
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
游客

返回顶部