zytzjx
驱动牛犊
驱动牛犊
  • 注册日期2001-12-24
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望41点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1995回复:0

WINDRIVER问题

楼主#
更多 发布于:2002-02-18 10:53
有一个问题是这样:
  就是我用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);

最新喜欢:

luozhangyuluozha...
Wecan
游客

返回顶部