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

📄 pcietest.cpp

📁 基于xilinx vierex5得pci express dma设计实现。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (c) Microsoft Corporation

Module Name:

    plx.cpp

Abstract:

    This module implements the PCIE class which tests the DMA of PCIE devices.

    Example usage:
        plx.exe /wr /wb=100         # write-then-read once with a buffer of 100 bytes
        plx.exe /thread             # repeat write-then-read for default 5000 millisecs.
        plx.exe /thread /time=1000  # repeat write-then-read for 1000 millisecs.

    NOTE: The /quite option will suppress most non-error messages.
    NOTE: The options and parameters are case sensitive.

Environment:

    User Mode Win2k or Later

--*/

#define INITGUID

#include <windows.h>
#include <Winsvc.h>
#include <winioctl.h>

#include "pcietest.hpp"
#include "freq.h"


//
// Define the spin count to be used for critical sections. The value
// specified below is arbitrary. Change it based on your requirements.
//
#define SPIN_COUNT_FOR_CS       0x4000

int g_TimeUp =0;

DWORD WINAPI
ReadThreadProc(
    LPVOID lpParameter
    )
{
    ULONG bytes;
    PTHREAD_CONTEXT Context = (PTHREAD_CONTEXT)lpParameter;

    while(!g_TimeUp) {

        if(ReadFile(Context->hDevice,
                    Context->Buffer,
                    Context->BufferSize,
                    &bytes,
                    NULL)) {

            if (!Context->quite) {
                printf("Read sucessful.\n");
            }

        } else {

            printf("Read failed.\n");
            ExitProcess(1);
        }
    }
    ExitThread(0);
}

DWORD WINAPI
WriteThreadProc(
    LPVOID lpParameter
    )
{
    ULONG bytes;
    PTHREAD_CONTEXT Context = (PTHREAD_CONTEXT)lpParameter;

    while(!g_TimeUp) {

        if(WriteFile(Context->hDevice,
                     Context->Buffer,
                     Context->BufferSize,
                     &bytes,
                     NULL)) {

            if (!Context->quite) {
                printf("Write sucessful.\n");
            }

        } else {

            printf("Write failed.\n");
            ExitProcess(1);
        }
    }
    ExitThread(0);
}

int __cdecl
main(
    __in              int argc,
    __in_ecount(argc) char* argv[]
    )
{
    PCIE Pcie;
    BOOL status = TRUE;
    ULONG test = MENU_TEST;

    if (!Pcie.Initialize()) {
        printf("Failied to Initialize Test class.\n");
        printf("exit(%d)\n", Pcie.Status);
        exit(Pcie.Status);
    }

    if(argc > 1) {

        for(int i=1; (i < argc) && status; i++) {

            char delims[]   = "-/=";
            char delims2[]  = "=";
            char *command;
            char *data;

            data = NULL;

            command =  strtok(argv[i], delims );
            if(command == NULL) {
                status = FALSE;
                break;
            }

            if(strcmp(command, "rb") == 0) {

                data = strtok(NULL, delims2);

                if (!data && i < argc-1) {
                    data = argv[++i];
                }

                ULONG size = atol(data);
                if (size > 0) {
                    Pcie.SetReadBufferSize(size);
                } else {
                    status = FALSE;
                }

            } else if(strcmp(command, "wb") == 0) {

                ULONG size = 0;
                data = strtok(NULL, delims2);

                if (!data && i < argc-1) {
                    data = argv[++i];
                }
                if (data) {
                    size = atol(data);
                }

                if (size > 0) {
                    Pcie.SetWriteBufferSize(size);
                } else {
                    status = FALSE;
                }

            } else if (strcmp(command, "bs") == 0) {
                data = strtok(NULL, delims2);

                if (!data && i < argc-1) {
                    data = argv[++i];
                }

                ULONG size = atol(data);
                if(size > 0) {
                    Pcie.SetWriteBufferSize(size);
                } else {
                    status = FALSE;
                }

            } else if(strcmp(command, "wt") == 0) {

                test = WRITE_TEST;

            } else if(strcmp(command, "rt") == 0) {

                test = READ_TEST;

            } else if(strcmp(command, "quite") == 0) {

                Pcie.Quite = TRUE;

            } else if(strcmp(command, "thread") == 0) {

                test = THREAD_TEST;

            } else if (strcmp(command, "time") == 0) {

                data = strtok(NULL, delims);

                if(!data && i < argc-1) {
                    data = argv[++i];
                }
                ULONG size = atol(data);
                Pcie.SetThreadLifeTime(size);

            } else {
                status = FALSE;
            }

            if (!Pcie.Quite) {
                if (data) {
                    printf("Arg %d: Command: %s  Parameter: %s\n", i, command, data);
                } else {
                    printf("Arg %d: Command: %s\n", i, command);
                }
            }
        }
    }

    if (status) {

        switch (test) {
            case READ_TEST:
                Pcie.ReadTest();
                break;

            case WRITE_TEST:
                Pcie.WriteTest();
                break;

            case READ_WRITE_TEST:
                Pcie.ReadWriteTest();
                break;

            case THREAD_TEST:
                Pcie.ThreadedReadWriteTest();
                break;

            case MENU_TEST:
            default:
                Pcie.Menu();
        }

    } else {

        printf("Invalid command line parameter.\n");
        Pcie.Status = 1;
    }

    printf("exit(%d)\n", Pcie.Status);

    exit( Pcie.Status );
}

PCIE::PCIE()
{
    ReadBuffer = WriteBuffer = NULL;
    hDevInfo = pDeviceInterfaceDetail = NULL;
    hDevice = INVALID_HANDLE_VALUE;
    console = TRUE;
    Contexts = NULL;
    Threads = NULL;
    ProcessorCount = 0;
    CSInitialized = FALSE;
    ThreadTimer = 5000;  // 5000 milliseconds (5 seconds)

    Quite = FALSE;
    Status = 0;
}

PCIE::~PCIE()
{

    if (CSInitialized) {
        DeleteCriticalSection(&CriticalSection);
    }
    if (hDevInfo) {
        SetupDiDestroyDeviceInfoList(hDevInfo);
    }

    if (pDeviceInterfaceDetail) {
        free(pDeviceInterfaceDetail);
    }

    if (Contexts) {
        for(int i = 0; i < ProcessorCount; i++) {
            if (Contexts[i].Buffer) {
                delete Contexts[i].Buffer;
            }
        }

        delete Contexts;
        Contexts = NULL;
    }

    if (hDevice != INVALID_HANDLE_VALUE) {
        CloseHandle(hDevice);
        hDevice = INVALID_HANDLE_VALUE;
    }
}

BOOL
PCIE::Initialize()
{
    BOOL retValue = TRUE;

    retValue = SetBufferSizes(DEFAULT_READ_BUFFER_SIZE);
    if (!retValue) {
        return retValue;
    }

    retValue = GetDevicePath();
    if (!retValue) {
        return retValue;
    }

    if (!CSInitialized) {
        retValue = InitializeCriticalSectionAndSpinCount(&CriticalSection, SPIN_COUNT_FOR_CS);
        if (!retValue) {
            printf("InitializeCritialSection failed.\n");
            Status = GetLastError();
            return retValue;
        }
        CSInitialized = TRUE;
    }

    return retValue;
}

void
PCIE::Menu()
{
    int menu = -1;

    while(menu != 0 && pDeviceInterfaceDetail) {
        printf("\n"
               " 1- Read from device\n"
               " 2- Write from device\n"
               " 3- Read/Write from device\n"
               " 4- Read/Write Thread Test\n"
               " 5- Select new device\n"
               " 6- Change Buffer Size\n"
               " 7- Compare Read/Write Buffers\n"
               " 8- Display Read/Write Buffers\n"
               " 9- Change Thread Lifetime\n"
               "10- Command Line Options\n"
               " 0- Quit\n");

        if (scanf_s("%d", &menu) == 0) {
            break;
        }

        switch(menu) {
            case READ_TEST:                             // 1
                ReadTest();
                break;

            case WRITE_TEST:                            // 2
                WriteTest();
                break;

            case READ_WRITE_TEST:                       // 3
                ReadWriteTest();
                break;

            case THREAD_TEST:                           // 4
                ThreadedReadWriteTest();
                break;

            case DEVICE_PATH:                           // 5
                GetDevicePath();
                break;

            case SET_SIZE:                              // 6
                ULONG size;
                printf("\nEnter new buffer size: ");
                if (scanf_s("%d", &size) != 0) {
                    SetBufferSizes(size);
                }
                break;

            case COMPARE_BUFFERS:                       // 7
                CompareReadWriteBuffers();
                break;

            case DISPLAY_BUFFERS:                       // 8
                DisplayReadWriteBuffers();
                break;

            case THREAD_TIME:                           // 9
                printf("\nEnter new Thread Lifetime (ms): ");
                if (scanf_s("%d", &ThreadTimer) == 0) {
                    break;
                }
                break;

            case COMMAND_LINE:                          // 10
                printf("Command Line Options\n"
                       " Set Read Buffer Size:           '/rb=xx'\n"
                       " Set Write Buffer Size:          '/wb=xx'\n"
                       " Set Both Buffer Sizes:          '/bs=xx'\n"
                       " Perform Write Test:             '/wt'\n"
                       " Perform Read Test:              '/rt'\n"
                       " Perform Read/Write Test:        '/wr'\n"
                       " Perform Read/Write Thread Test: '/thread'\n");
                break;

            default:
                break;
        }
    }
}

BOOL
PCIE::ThreadedReadWriteTest()
{
    BOOL status = TRUE;
    DWORD_PTR pAffinity, sAffinity;
    int i;

    HANDLE hThread;
    HANDLE hProcess = GetCurrentProcess();

    GetProcessAffinityMask(hProcess, &pAffinity, &sAffinity);
    ProcessorCount = 0;

    while(pAffinity) {
        ProcessorCount++;
        pAffinity = pAffinity >> 1;
    }

⌨️ 快捷键说明

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