bestrafi
驱动牛犊
驱动牛犊
  • 注册日期2003-05-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:1273回复:6

我是一个新手,彷徨中..........

楼主#
更多 发布于:2003-07-08 17:26
在给一个基于PCI总线的数据采集卡写驱动,碰到了很多问题,希望大家不吝赐教

介绍一下这个卡的主要工作原理~先:

该卡的主要工作过程是:
AD9054把转换的数据经由CPLD存放在静态存储器里,
当静态存储器里的数据存满时,
CPLD发送一个中断给PCI9030,然后由计算机读取静态存储器里的数据,大约为4M字节。

下面是我写的中断服务程序,不知道对不对:



#include \"daq_Pci.h\"

///////////////////////////////////////////////////////////////////////////////
//
//  PciHandleInterrupt
//
//      When the Pci device generates an interrupt, this function is called.
//      Note that in our simple model of the world here, every transfer is
//      completed successfully.  We just don\'t bother with error detection
//      and handling.  If you wanted this to be a REAL driver, you\'d have to
//      do the appropriate error detection and handling.
//
//  INPUTS:
//
//      Interupt - Address of the KINTERRUPT Object for our device.
//  
//      ServiceContext - Address of our device extension.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      TRUE if our device is interrupting, FALSE otherwise.
//
//  IRQL:
//
//      This routine is called at IRQL == DIRQL.
//
//  NOTES:
//
//      As is true for all ISR\'s in NT, this routine is called with the
//      interrupt spin lock held.
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN PciHandleInterrupt(PKINTERRUPT Interupt, PVOID ServiceContext)
{
    BOOLEAN ourDeviceInterrupting = FALSE;
    PPci_DEVICE_EXT devExt = (PPci_DEVICE_EXT)ServiceContext;
    ULONG intRegister;
    ULONG csrRegister;

#if DBG
    DbgPrint(\"Daq_Pci: ISR entered\\n\");
#endif    
    
    //
    // Get the current interrupt CSR from our device
    //
    intRegister = READ_REGISTER_ULONG(devExt->BaseRegisterAddress0+ICSR_OFF);

#if DBG
    DbgPrint(\"*****************PCI INTCSR = 0x%0x\\n\",intRegister);
#endif


    //
    // Is our device presently interrupting?
    //
    if (intRegister & PCI_INT_INTERRUPTED)
    {
    
        //
        // Yes, it is!
        //
        ourDeviceInterrupting = TRUE;

#if DBG
        DbgPrint(\"\\tInterrupt is ours.\\n\");
#endif

        //
        // Store away some context so when we get to our DpcForIsr we\'ll know
        // what caused the interrupt.  Specifically, we accumulate bits in the
        // \"IntCsr\" field of our device extenstion indicating what interrupts
        // we\'ve seen from the device.  
        // N.B.  We guard these bits with the Interrupt Spin Lock.  The bits
        //       cannot be set or cleared unless holding that lock.
        //
        devExt->IntCsr = intRegister;
        
#if DBG
        DbgPrint(\"Requesting DPC\\n\");
#endif
        IoRequestDpc(devExt->FunctionalDeviceObject, 0, NULL);

        
    }

    return(ourDeviceInterrupting);
}
    

///////////////////////////////////////////////////////////////////////////////
//
//  PciDpcForIsr
//
//      This is the DPC for ISR function.  It is called as a result of a
//      call to IoRequestDpc() in the interrupt service routine.  
//
//  INPUTS:
//
//    Dpc - Address of our DPC Object.
//
//    Unused - Unused.
//
//    Context - Address of our device extension.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//    None.
//
//  IRQL:
//
//    This routine is called at IRQL == IRQL_DISPATCH_LEVEL
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
VOID
PciDpcForIsr(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Unused, PVOID Context)
{
    PPci_DEVICE_EXT devExt = (PPci_DEVICE_EXT) DeviceObject->DeviceExtension;
    PLIST_ENTRY entry;
    PIRP irp;
    ULONG count;

    PVOID readData;
    ULONG length = 1024 * 4 * 1000;
      
#if DBG
    DbgPrint(\"----------Daq_Pci DPC\\n\");
#endif
  
    PVOID readData = ExAllocatePool(NonPagedPoolCacheAligned, length);
    
    //在中断事件处理中先向偏移地址0x14h中写入任意数让采集卡的通道1进入读取数据状态。
    WRITE_REGISTER_ULONG(devExt->BaseRegisterAddress2+PREPAREREAD_A,0x00);

    //将静态存储器中的数据读出来
    for( count = 0; count < length; count++)
        
        readData[count] = READ_REGISTER_ULONG(devExt->BaseRegisterAddress2+READADDRESS);

    //复位中断控制状态寄存器
    WRITE_REGISTER_ULONG(devExt->BaseRegisterAddress0+ICSR_OFF,0x00);
  
    //同步内核事件  
    KeSetEvent(CompleteRead, 0, TRUE);
    
}
bestrafi
驱动牛犊
驱动牛犊
  • 注册日期2003-05-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-07-08 19:31
郁闷《《《《我怎么找不到自己的马甲呢? :cool:
bestrafi
驱动牛犊
驱动牛犊
  • 注册日期2003-05-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-07-10 15:00
怎么没有高手指导俺呢
其实我最主要想知道在驱动程序中有没有
for(;)
{
   读端口数据;
}
的用法。
xyyln
驱动老牛
驱动老牛
  • 注册日期2003-01-02
  • 最后登录2009-12-28
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望11点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-07-11 09:26
这个当然没问题,语法都是一样的
[img]http://www.jt99.com/zjbbs/UploadFile/2003113018513643830.gif[/img]
Dragon2008
驱动中牛
驱动中牛
  • 注册日期2002-04-01
  • 最后登录2006-03-13
  • 粉丝0
  • 关注0
  • 积分31分
  • 威望5点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-07-11 11:22
你还没说明你碰到了什么问题呢?
我姓龙,我属龙,我叫龙。。。
bestrafi
驱动牛犊
驱动牛犊
  • 注册日期2003-05-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-07-11 16:45
我知道了,其实DDK下有读端口数据至整个缓冲区的函数
READ_REGISETER_BUFFER_ULONG()
而不用
for()
{
   READ_REGISTER_ULONG()
}
唉,实在太笨了!谢谢两位的指导! :o
Gong_XG
驱动太牛
驱动太牛
  • 注册日期2002-10-01
  • 最后登录2010-11-25
  • 粉丝0
  • 关注0
  • 积分313分
  • 威望46点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-07-12 12:37
先编个框架,一点点加;一次编好,不可能.
游客

返回顶部