⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testpdma.c

📁 dma驱动开发程序
💻 C
📖 第 1 页 / 共 3 页
字号:

#include <windows.h>
#include <stdio.h>

#define MAX_ERROR_BUFFER    256
#define MAX_DATA_BUFFER     128*1024
#define VALID_READ_SIZE     60*1024

#define FILL_MEMORY_BYTE    0x42

#define LARGE_BUFFER_SIZE       60*1024
#define MEDIUM_BUFFER_SIZE      30*1024
#define SMALL_BUFFER_SIZE       8*1024

#define MAX_CONCURRENT_IO   20
#define DEFAULT_IO_COUNT        10000

typedef struct _BUFFER_INFO {

    OVERLAPPED  Overlapped;     // The OVERLAPPED structure MUST be first in this
                                // structure or the completion port I/O will fail.

    LPVOID      DataBuffer;
    DWORD       Length;
    
} BUFFER_INFO, *PBUFFER_INFO;

#define     FLAG_VERBOSE_MODE   0x0001

#define     FLAG_TEST_SYNC      0x0010
#define     FLAG_TEST_ASYNC     0x0020
#define     FLAG_TESTS_ENABLED  0x00F0

#define     PCI_DEVICE_NAME     "pcidma"

#define     NOTHING

typedef struct _USER_PARMS {
    LONG        LoopCount;
    USHORT      Flags;
    UCHAR       DeviceNumber[MAX_PATH];
} USER_PARMS, *PUSER_PARMS;
      

DWORD
AsyncTests(
    IN LPCTSTR DeviceName,
    IN PUSER_PARMS UserParms
    );
    
VOID
DisplayUsage(
    IN PUCHAR ProgramName
    );
    
DWORD
DoAsyncIo(
    IN HANDLE FileHandle,
    IN PBUFFER_INFO BufferInfo,
    IN USHORT NumberOfBuffers,
    IN PUSER_PARMS UserParms
    );

DWORD
FillInDataStructures(
    IN PBUFFER_INFO BufferInfo,
    IN USHORT NumberOfBuffers,
    IN PUSER_PARMS UserParms
    );

DWORD
NonOverlappedTests(
    IN LPCTSTR DeviceName
    );

VOID
PrintError(
    IN DWORD ErrorCode
    );

DWORD
ReadTest(
    IN HANDLE FileHandle,
    IN LPVOID DataBuffer,
    IN DWORD BufferSize
    );

VOID
ReleaseBuffers(
    IN PBUFFER_INFO BufferInfo,
    IN USHORT NumberOfBuffers
    );

BOOLEAN
VerifyInputParameters(
    IN SHORT ArgC,
    IN PCHAR ArgV[],
    IN PUSER_PARMS UserParms
    );

                                 
DWORD
__cdecl
main(
    int argc,
    char *argv[]
    )
{
    DWORD errorCode;    

    UCHAR deviceName[MAX_PATH];

    USER_PARMS  userParms;
    
    ZeroMemory(&userParms, sizeof(USER_PARMS));
    
    //
    // Verify user input parameters.
    //

    if (!VerifyInputParameters((SHORT)argc,
                               argv,
                               &userParms
                               )) {
    
        return ERROR_INVALID_PARAMETER;    
    }
    
    //
    // Copy the device name into the name buffer.
    //

    strcpy(deviceName, "\\\\.\\");
    strcat(deviceName, PCI_DEVICE_NAME);
    strcat(deviceName, userParms.DeviceNumber);

    printf("Testing device: %s \n", deviceName);
    
    //
    // Process non-overlapped tests.
    //

    if (userParms.Flags & FLAG_TEST_SYNC) {
        
        printf("\n");
        printf("*********************\n");
        printf("* Synchronous tests *\n");
        printf("*********************\n");
        printf("\n");
        
        errorCode = NonOverlappedTests(deviceName);
    
        if (errorCode != NO_ERROR) {
        
            return errorCode;    
        }
    }

    //
    // Process overlapped tests.
    //

    if (userParms.Flags & FLAG_TEST_ASYNC) {
        
        printf("\n");
        printf("**********************\n");
        printf("* Asynchronous tests *\n");
        printf("**********************\n");
        printf("\n");
        
        errorCode = AsyncTests(deviceName,
                               &userParms
                               );
    
        //
        // Fall through...
        //
    }
    
    return errorCode;
        
}   // main



DWORD
AsyncTests(
    IN LPCTSTR DeviceName,
    PUSER_PARMS UserParms
    )
{
    DWORD           errorCode;

    HANDLE          fileHandle;
        
    BUFFER_INFO     bufferInfo[MAX_CONCURRENT_IO];
    
    //
    // Open the device.
    //

    fileHandle = CreateFile(DeviceName,
                            GENERIC_READ,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_OVERLAPPED,
                            NULL
                            );

    if (fileHandle == INVALID_HANDLE_VALUE) {

        errorCode = GetLastError();
        
        printf("Unable to open device.  Error: %d \n", errorCode);

        PrintError(errorCode);
        
        return errorCode;
    }

    //
    // Fill in data structures.
    //
    
    errorCode = FillInDataStructures(bufferInfo,
                                     MAX_CONCURRENT_IO,
                                     UserParms
                                     );
    
    if (errorCode != NO_ERROR) {
        
        return errorCode;
    }

    //
    // Try some I/O.
    //

    DoAsyncIo(fileHandle,
              bufferInfo,
              MAX_CONCURRENT_IO, 
              UserParms
              );
              
    //
    // Close device handle.
    //

    CloseHandle(fileHandle);

    //
    // Release memory.
    //
    
    ReleaseBuffers(bufferInfo,
                   MAX_CONCURRENT_IO
                   );
                                        
    return NO_ERROR;
    
}   // AsyncTests



VOID
DisplayUsage(
    IN PUCHAR ProgramName
    )
{
    printf("\n");
    printf("Usage:  %s [-?] [[-a | -s] [-d##] [-t##] [-v]]  \n", ProgramName);
    printf("\n");
    printf("  Options: \n");
    printf("\n");
    printf("    -?    Displays this help screen \n");
    printf("    -a    Enable asynchronous tests \n");
    printf("    -d##  Device number, zero-based.  Zero is the default. \n");
    printf("    -s    Enable synchronous tests \n");
    printf("    -t##  Total number of Asynchronous I/Os to test (default = %d) \n",
             DEFAULT_IO_COUNT);
    printf("    -v    Verbose mode \n");
    printf("\n");
    printf("\n");
    printf("  All numbers are assumed decimal. \n");
    printf("\n");


}   // DisplayUsage



DWORD
DoAsyncIo(
    IN HANDLE FileHandle,
    IN PBUFFER_INFO BufferInfo,
    IN USHORT NumberOfBuffers,
    IN PUSER_PARMS UserParms
    )
{
    PBUFFER_INFO tempBufferInfo;
    
    HANDLE  completionPort;
    
    LONG    pendingCount = 0;
    LONG    totalCount = 0;
    
    DWORD   errorCode;
    DWORD   bytesReturned;
    DWORD   keyCompletion;
    
    LPOVERLAPPED  ovCompletion;
                                            
    USHORT i;
    
    BOOLEAN verboseMode;
    
    verboseMode = UserParms->Flags & FLAG_VERBOSE_MODE;
    
    //
    // Create the completion port.
    //
    
    completionPort = CreateIoCompletionPort(FileHandle,
                                            NULL,
                                            0,
                                            1
                                            );
                                    
    if (INVALID_HANDLE_VALUE == completionPort) {
        
        errorCode = GetLastError();
        
        printf("CreateIoCompletionPort failed %d \n", errorCode);
        
        PrintError(errorCode);
        
        return errorCode;
    }
    
    //
    // Fire off the first set of reads.
    //
    
    tempBufferInfo = BufferInfo;
    
    for (i = 0; i < NumberOfBuffers; i++) {
    
        if (!ReadFile(FileHandle,
                      tempBufferInfo->DataBuffer,
                      tempBufferInfo->Length,
                      &bytesReturned,
                      &tempBufferInfo->Overlapped
                      )) {
        
            errorCode = GetLastError();

            if (errorCode == ERROR_IO_PENDING) {
                
                if (verboseMode) {
                    printf("Pending I/O # %d \n", tempBufferInfo->Overlapped.Offset);
                }
                                
                pendingCount++;
                
            } else {
            
                printf("ReadFile for buffer %d failed \n", i);
            }
        
        } else {
        
            printf("ReadFile completed for buffer %d \n", i);
        }
    
        //
        // Point to next buffer.
        //
    
        tempBufferInfo++;
    }

    printf("Start: %d reads pending \n", pendingCount);
    
    //
    // Add the pending count to the total count.
    //
    
    totalCount = pendingCount;

    printf("Entering main pending loop... \n");

    if (UserParms->LoopCount < MAX_CONCURRENT_IO) {
        
        UserParms->LoopCount = DEFAULT_IO_COUNT;
    }
    
    while (totalCount < UserParms->LoopCount) {
        
        //
        // Wait for an I/O to complete.
        //
        
        if (!GetQueuedCompletionStatus(completionPort,
                                       &bytesReturned,
                                       &keyCompletion,
                                       &ovCompletion,
                                       INFINITE
                                       )) {
            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -