阅读:1995回复:0
WINDRIVER问题
有一个问题是这样:
就是我用WinDriver开发的一个PCI的DMA功能,将本身自带的例子改成一个DLL来用,可是一执行到调用时程序自动退出。 #include \"d:/windriver/include/windrvr.h\" #include <stdio.h> #include \"VXDmy_lib.h\" #include \"prndrv.h\" void IO_Open() { WD_VERSION ver; hWD = INVALID_HANDLE_VALUE; hWD = WD_Open(); // Check whether handle is valid and version OK if (hWD==INVALID_HANDLE_VALUE) { printf(\"Failed opening \" WD_PROD_NAME \" device\\n\"); exit(1); } BZERO(ver); WD_Version(hWD,&ver); if (ver.dwVer<WD_VER) { printf(\"Incorrect \" WD_PROD_NAME \" version\\n\"); WD_Close(hWD); exit(1); } G_cardReg.hCard = 0; } // IO_DetectCardElements() scans the card recourses (Interrupts, IO & memory mapped regions) // and sets IO_ResInterrupt & IO_ResMemory to point to the correct element number void IO_DetectCardElements() { DWORD i; G_resMemory = INVALID_RES; for (i=0; i<G_cardReg.Card.dwItems; i++) { switch(G_cardReg.Card.Item.item) { case ITEM_INTERRUPT: printf(\"error - Card has an Interrupt\\n\"); exit(1); break; case ITEM_MEMORY: if (G_resMemory==INVALID_RES) G_resMemory = i; else { printf(\"error - Card has more than one memory region\\n\"); exit(1); } break; case ITEM_IO: printf(\"error - Card has an IO ragne\\n\"); exit(1); break; } } if (G_resMemory==INVALID_RES) { printf(\"Memory region not found\\n\"); exit(1); } } // IO_DetectCard() scans the PCI bus & detect the card void IO_DetectCard() { WD_PCI_SCAN_CARDS pciScan; WD_PCI_CARD_INFO pciCardInfo; BZERO(pciScan); pciScan.searchId.dwVendorId = MY_VENDOR_ID; pciScan.searchId.dwDeviceId = MY_DEVICE_ID; WD_PciScanCards (hWD, &pciScan); if (pciScan.dwCards==0) // Found at least one card { printf(\"Could not find PCI card\\n\"); exit(1); } BZERO(pciCardInfo); pciCardInfo.pciSlot = pciScan.cardSlot[0]; WD_PciGetCardInfo (hWD, &pciCardInfo); // the info for Card comes from WD_PciGetCardInfo() // for PCI cards. for ISA cards the information has to be // set by the user (IO/memory address & interrupt number). BZERO(G_cardReg); G_cardReg.Card = pciCardInfo.Card; IO_DetectCardElements(); G_cardReg.fCheckLockOnly = FALSE; WD_CardRegister (hWD, &G_cardReg); if (G_cardReg.hCard==0) { printf (\"Failed locking device\\n\"); exit(1); } G_baseMemory = G_cardReg.Card.Item[G_resMemory].I.Mem.dwUserDirectAddr; G_baseMemoryTrns = G_cardReg.Card.Item[G_resMemory].I.Mem.dwTransAddr; } void IO_Close() { // unregister card if (G_cardReg.hCard) WD_CardUnregister(hWD, &G_cardReg); // close WinDriver WD_Close(hWD); } // performs a single 32 bit read from memory mapped range DWORD IO_Read32BitRegister(DWORD dwAddr) { PDWORD pDW = (PDWORD) (G_baseMemory + dwAddr); return *pDW; } // performs a single 32 bit write to memory mapped range void IO_Write32BitRegister(DWORD dwAddr, DWORD dwData) { PDWORD pDW = (PDWORD) (G_baseMemory + dwAddr); *pDW = dwData; } // transfer data to/from PCI card using bus-master DMA. // pBuffer if the data to transfer (or to receive data), dwBytes - size of data // fIsRead is TRUE for read (PCI card --> system memory), or FALSE for write ( memory --> PCI card) // addr local address on PCI card void IO_DMATransferBuffer(PVOID pBuffer, DWORD dwBytes, BOOL fIsRead, DWORD dwAddr) { WD_DMA dma; DWORD i; DWORD dwSumBytes; BZERO(dma); dma.pUserAddr = pBuffer; dma.dwBytes = dwBytes; dma.dwOptions = 0; // lock region in memory & get page list WD_DMALock(hWD,&dma); // program page transfer list on PCI bus master card dwSumBytes = 0; for (i=0; i<dma.dwPages; i++) { IO_Write32BitRegister(MY_REG_DMA_PAGES + i*12 + 0, (DWORD) dma.Page.pPhysicalAddr); IO_Write32BitRegister(MY_REG_DMA_PAGES + i*12 + 4, dwAddr + dwSumBytes); IO_Write32BitRegister(MY_REG_DMA_PAGES + i*12 + 8, dma.Page.dwBytes); dwSumBytes += dma.Page.dwBytes; } // write the number of pages to transfer and direction of transfer IO_Write32BitRegister(MY_REG_DMA_STATUS, dma.dwPages | (fIsRead ? 0x1000 : 0)); // wait for for status register to indicate transfer compleate here. // you can use the interrupt routine for non-busy wait (if the card enables interrupt // indication for end of transfer). WD_DMAUnlock(hWD,&dma); } // transfer data to/from PCI card NOT using DMA.364479 // pBuffer if the data to transfer (or to receive data), dwBytes - size of data // fIsRead is TRUE for read (PCI card --> system memory), or FALSE for write ( memory --> PCI card) // addr local address on PCI card void IO_TransferBuffer(PVOID pBuffer, DWORD dwBytes, BOOL fIsRead, DWORD dwAddr) { WD_TRANSFER trans; BZERO(trans); if (fIsRead) trans.cmdTrans = RM_SDWORD; // Read Memory String DWORD else trans.cmdTrans = WM_SDWORD; // Write Memory String DWORD trans.dwPort = G_baseMemoryTrns + dwAddr; trans.Data.pBuffer = pBuffer; trans.dwBytes = dwBytes; // if fAutoinc==TRUE then read/write will run through an address range on the card // if fAutoinc==FALSE then read/write will perform on the same address of the card // (usually used for FIFO where all reads/writes are to the same register) trans.fAutoinc = TRUE; trans.dwOptions = 0; WD_Transfer (hWD, &trans);// // this function could also be implemeted directly with memcpy(). // for example, to read a memory region: // memcpy (pBuffer, (PVOID) (dwAddr + G_baseMemory), dwBytes); } void RegisterWinDriver() { HANDLE hWD; WD_LICENSE lic; hWD = WD_Open(); if (hWD!=INVALID_HANDLE_VALUE) { // replace the following string with your license string strcpy(lic.cLicense, \"6A2BA669F1814714932DFDBA712F89A66B56.39687A0B\"); WD_License(hWD, &lic); WD_Close(hWD); } } void IO_doDMA(PVOID pBuffer, DWORD dwBytes, BOOL fIsRead, DWORD dwAddr)//这是动态库的出口函数。 { RegisterWinDriver(); IO_Open(); IO_DetectCard(); IO_DMATransferBuffer(pBuffer, dwBytes, fIsRead, dwAddr); IO_Close(); } //以下是调用 MyDMA d; // HANDLE hDll; CHAR Cr[1000]; hDll = LoadLibrary(\"pcidrv.dll\"); if (hDll != 0) { d = (MyDMA)GetProcAddress((HINSTANCE)hDll, \"IO_doDMA\"); if (d!=NULL) { d(Cr, 1000, false, 0x40000);//程序在这儿中断跳出 } // } FreeLibrary((HINSTANCE)hDll); CString st(Cr); MessageBox(st); |
|
最新喜欢:luozha...
|