阅读:1543回复:1
怎么无法申请DMA缓冲区?
小弟正在做一块高速数据采集卡的论文,用的是ISA接口,DMA传输。我用VTOOLSD作了个驱动程序,但每次在装载时,当运行到保留一块DMA缓冲区(即调用VMDABuffer::reserve(...)时),系统就锁死不动。请问这是怎么回事,该如何解决。谢谢!
附程序如下: // WAH002.h - include file for VxD WAH002 #include <vtoolscp.h> #define DEVICE_CLASS Wah002Device #define WAH002_DeviceID UNDEFINED_DEVICE_ID #define WAH002_Init_Order UNDEFINED_INIT_ORDER #define WAH002_Major 1 #define WAH002_Minor 0 #define MY_IRQ 10 #define MY_DMA 6 class MyHwInt : public VHardwareInt { public: MyHwInt() : VHardwareInt(MY_IRQ,0,0,0){}; virtual VOID OnHardwareInt(VMHANDLE); }; class Wah002Device : public VDevice { public: virtual BOOL OnSysDynamicDeviceInit(); virtual BOOL OnSysDynamicDeviceExit(); virtual DWORD OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams); }; class MyDMAChannel : public VDMAChannel // VDMAChannel类定义 { public: MyDMAChannel() : VDMAChannel(6) {} virtual VOID handler(VMHANDLE hVM); }; class MyBuffer : public VDMABuffer // VDMABuffer类定义 { public: MyBuffer(PVOID regionAddress, DWORD regionSize) : VDMABuffer(regionAddress, regionSize){} }; // WAH002.cpp - main module for VxD WAH002 #define DEVICE_MAIN #include \"wah002.h\" Declare_Virtual_Device(WAH002) #undef DEVICE_MAIN #include \"apcx.h\" MyHwInt* pMyIRQ; PVOID CallBackApc = 0; THREADHANDLE TheThread = 0; MyDMAChannel* pMyDMA; MyBuffer* pMyBUF; DWORD errCode; PVOID region; DWORD size; DWORD MAX_TRANSFER_PAGES=4096; DWORD MAX_PHYS_ADDR=0x1000000; VOID MyHwInt::OnHardwareInt(VMHANDLE hVM) { _outp(0x304,0x00); sendPhysicalEOI(); VWIN32_QueueUserApc(CallBackApc, NULL, TheThread); } VOID MyDMAChannel::handler(VMHANDLE hVM) // 重载handler成员函数 { VDMAChannel::handler(hVM); // let VDMAD do all the work } BOOL Wah002Device::OnSysDynamicDeviceInit() { pMyIRQ = new MyHwInt(); if ((pMyIRQ==NULL) || !pMyIRQ->hook()) return FALSE; pMyDMA = new MyDMAChannel(); if ((pMyDMA==NULL) || !pMyDMA->hook()) return FALSE; VDMABuffer::reserve(MAX_TRANSFER_PAGES, (PVOID)MAX_PHYS_ADDR); return TRUE; } BOOL Wah002Device::OnSysDynamicDeviceExit() { if (pMyDMA) delete pMyDMA; if (pMyIRQ) delete pMyIRQ; return TRUE; } DWORD Wah002Device::OnW32DeviceIoControl(PIOCTLPARAMS pDIOCParams) { DWORD status; switch (pDIOCParams->dioc_IOCtlCode) { case DIOC_OPEN: _outp(0x303,0x00); status = 0; break; case DIOC_CLOSEHANDLE: if (pMyBUF) delete pMyBUF; status = 0; break; case REGISTER: CallBackApc = pDIOCParams->dioc_InBuf; TheThread = Get_Cur_Thread_Handle(); status = 0; break; case DMASET: //设置DMA通道 region = pDIOCParams->dioc_InBuf; size= pDIOCParams->dioc_cbInBuf; pMyBUF = new MyBuffer(NULL,size); if (pMyBUF->m_createError == 0) { pMyDMA->setRegion(pMyBUF, FALSE, NULL, size, pMyBUF->m_physAddress); pMyDMA->setPhysicalState(Get_Cur_VM_Handle(),DMA_type_write | DMA_block_mode); pMyDMA->physicalUnmask(Get_Cur_VM_Handle(),FALSE); pMyIRQ->physicalUnmask(); status = 0; } else status = -1; break; case READ: //把buffer的数据拷贝到region pMyBUF->copyFrom(region, size, 0, errCode); //重新设置DMA缓冲区 pMyDMA->setRegion(pMyBUF, FALSE, NULL, size, pMyBUF->m_physAddress); pMyDMA->setPhysicalState(Get_Cur_VM_Handle(),DMA_type_write|DMA_single_mode); pMyDMA->physicalUnmask(Get_Cur_VM_Handle(),FALSE); status = 0; break; default: status = -1; } return status; } //apcx.h #define REGISTER CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_NEITHER, FILE_ANY_ACCESS) #define DMASET CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_NEITHER, FILE_ANY_ACCESS) #define READ CTL_CODE(FILE_DEVICE_UNKNOWN, 3, METHOD_NEITHER, FILE_ANY_ACCESS) |
|
沙发#
发布于:2002-10-06 11:20
不需要VDMABuffer::reserve,直接用VDMABuffer即可。
|
|
|