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

📄 testfunc.cpp

📁 PCI的一个测试程序,可以测试PCI driver和BOARD的功能.
💻 CPP
字号:
#include "stdafx.h"
#include <winioctl.h>
#include <winsock.h>
#include "public.h"
#include "freq.h"
#include "testfunc.h"


#include "PCIEBoardTest.h"
#include "testfunc.h"
#include "PageDevice.h"
#include "PageTest.h"
#include "Pagedebug.h"
#include "PageChart.h"
#include "PCIEBoardTestDlg.h"

#define CHECK_DMA_RESULT

int		SKIP_APP_INTERRUPTED	= 0;
int		SKIP_APP_PARAM			= 10;


//double  PCI_FREQ = 1000.0 / 62.5;     // for 62.5 MHZ
double	PCI_FREQ = 16;		// for 62.5 MHZ


const int   DMA_BUFFER_SIZE = 16 * 1024 * 1024;
char *      pVirtualDMABuffer[2];

const int   RETRY_TIMES = 3;

void    Test_GetUserAddress2(HANDLE hDeviceHandle, ULONG UserAddress[4])
{
    pVirtualDMABuffer[0] = new char[DMA_BUFFER_SIZE];
    pVirtualDMABuffer[1] = new char[DMA_BUFFER_SIZE];

    UserAddress[0] = (ULONG)pVirtualDMABuffer[0];
    UserAddress[1] = DMA_BUFFER_SIZE;
    UserAddress[2] = (ULONG)pVirtualDMABuffer[1];
    UserAddress[3] = DMA_BUFFER_SIZE;
}

BOOL    Test_GetUserAddress(HANDLE hDeviceHandle, ULONG UserAddress[6])
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;

    GetDlg()->Log("Getting DMA Buffer mapping address.");
    status = DeviceIoControl(hDeviceHandle, IOCTL_GET_BUFFERADDRESS, InBuffer, sizeof(ULONG), OutBuffer, sizeof(ULONG) * 6, &ulBytes, NULL);

    if (status)
    {
        for(int i=0; i<6; ++i)
            UserAddress[i] = OutBuffer[i];

        GetDlg()->Log("DMA Buffer mapping address got.");
    }
    else
    {
        for(int i=0; i<6; ++i)
            UserAddress[i] = 0;

        GetDlg()->Log("Failed to get DMA Buffer mapping address.");
    }

    return status;
}

void    Test_FreeUserAddress2(HANDLE hDeviceHandle)
{
    if (pVirtualDMABuffer[0])
        delete[] pVirtualDMABuffer[0];
    if (pVirtualDMABuffer[1])
        delete[] pVirtualDMABuffer[1];

    pVirtualDMABuffer[0] = NULL;
    pVirtualDMABuffer[1] = NULL;
}

void    Test_FreeUserAddress(HANDLE hDeviceHandle)
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;

    GetDlg()->Log("Free DMA Buffer mapping buffer.");
    status = DeviceIoControl(hDeviceHandle, IOCTL_FREE_BUFFERADDRESS, InBuffer, sizeof(ULONG), OutBuffer, sizeof(ULONG) * 2, &ulBytes, NULL);
}

// TimeElapse: performace, time_done, time_int, time_app  in ns
BOOL    Test_Dev2Host(HANDLE hDeviceHandle, SIZE_T size, SIZE_T count, ULONG pattern, ULONG TimeElapse[3])
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;
    __int64 tscStart;
    __int64 tscEnd;
	int		i;
    int     j;

    

    for(j=0; j<RETRY_TIMES; ++j)
    {
        if (j)
        {
            GetDlg()->Log("Retrying...");
        }

        // Reset it at first.
        Test_Reset(hDeviceHandle);

        InBuffer[0] = (ULONG)size;
        InBuffer[1] = (ULONG)count;
        InBuffer[2] = (ULONG)pattern;

        GetDlg()->Log("TRIGGING DEVICE TO HOST DMA TRANSACTION.");

#ifdef	CHECK_DMA_RESULT
        ULONG *  pData = (PULONG)(GetDlg()->GetUserVirtualBuffer_d2h());
        char     szInfor[256];

        for(i=0; i<size*count; ++i)
            pData[i] = 0;
#endif


        GetCurrentTSC(tscStart);
        status = DeviceIoControl(hDeviceHandle, IOCTL_DMA_DEVICE_HOST, InBuffer, sizeof(ULONG) * 3, OutBuffer, sizeof(ULONG) * 2, &ulBytes, NULL);
        GetCurrentTSC(tscEnd);

        if (status && !(ulBytes == sizeof(ULONG) && OutBuffer[0] == (ULONG)-1))
        {
            TimeElapse[0] = (ULONG)(OutBuffer[0] * PCI_FREQ);		            // performace
            TimeElapse[1] = (ULONG)(OutBuffer[1] / (nCPUFreq / 1000.0));        // drv tsc, in ns
            TimeElapse[2] = (ULONG)((tscEnd - tscStart) / (nCPUFreq / 1000.0)); // ns in app

            GetDlg()->Log("DEVICE TO HOST DMA TRANSACTION succeeded.");

			if (SKIP_APP_INTERRUPTED && TimeElapse[2] > SKIP_APP_PARAM * TimeElapse[1])
			{
				GetDlg()->Log("Application is interrupted.");
				continue;
			}

#ifdef	CHECK_DMA_RESULT
            pData = (PULONG)(GetDlg()->GetUserVirtualBuffer_d2h());

            pattern = htonl(pattern);

            for( i=0; i<size*count; ++i)
            {
                if (pData[i] != pattern)
                {
                    sprintf(szInfor, "DATA[%d]: 0x%08X != 0x%08X", i, pData[i], pattern);
                    GetDlg()->Log(szInfor);
                }
            }
#endif
			break;
        }
        else
        {
            TimeElapse[0] = 0;
            TimeElapse[1] = 0;
            TimeElapse[2] = 0;

            GetDlg()->Log("DEVICE TO HOST DMA TRANSACTION failed.");
        }
    }

    return status;
}

// TimeElapse: performace, time_drv, time_app  in ns
BOOL    Test_Host2Dev(HANDLE hDeviceHandle, SIZE_T size, SIZE_T count, ULONG TimeElapse[3])
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;
    __int64 tscStart;
    __int64 tscEnd;
    int     j;


    for(j=0; j<RETRY_TIMES; ++j)
    {
        if (j)
        {
            GetDlg()->Log("Retrying...");
        }
        // Reset it at first.
        Test_Reset(hDeviceHandle);

        InBuffer[0] = (ULONG)size;
        InBuffer[1] = (ULONG)count;

        GetDlg()->Log("TRIGGING HOST TO DEVICE DMA TRANSACTION.");
        GetCurrentTSC(tscStart);
        status = DeviceIoControl(hDeviceHandle, IOCTL_DMA_HOST_DEVICE, InBuffer, sizeof(ULONG) * 2, OutBuffer, sizeof(ULONG) * 3, &ulBytes, NULL);
        GetCurrentTSC(tscEnd);

        if (status && !(ulBytes == sizeof(ULONG) && OutBuffer[0] == (ULONG)-1))
        {
            TimeElapse[0] = (ULONG)(OutBuffer[0] * PCI_FREQ);                     // performace
            TimeElapse[1] = (ULONG)(OutBuffer[1] / (nCPUFreq / 1000.0));          // drv tsc, in ns
            TimeElapse[2] = (ULONG)((tscEnd - tscStart) / (nCPUFreq / 1000.0));   // ns in app

			// OutBuffer[2] is deviceReadCompletionSize

            GetDlg()->Log("HOST TO DEVICE DMA TRANSACTION succeeded.");

			if (SKIP_APP_INTERRUPTED && TimeElapse[2] > SKIP_APP_PARAM * TimeElapse[1])
			{
				GetDlg()->Log("Application is interrupted.");
				continue;
			}

			break;
        }
        else
        {
            TimeElapse[0] = 0;
            TimeElapse[1] = 0;
            TimeElapse[2] = 0;

            GetDlg()->Log("HOST TO DEVICE DMA TRANSACTION failed.");
        }
    }

    return status;
}

// TimeElapse: d2h_perf, d2h_drv, h2d_perf, h2d_drv, full_app
BOOL    Test_Full(HANDLE hDeviceHandle, SIZE_T d2h_size, SIZE_T d2h_count, ULONG d2h_pattern, SIZE_T h2d_size, SIZE_T h2d_count, ULONG TimeElapse[5])
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;
    __int64 tscStart;
    __int64 tscEnd;
    int     j;


    for(j=0; j<RETRY_TIMES; ++j)
    {
        if (j)
        {
            GetDlg()->Log("Retrying...");
        }

        // Reset it at first.
        Test_Reset(hDeviceHandle);

        // in : 
        //    for d2h write:  SIZE_T size, SIZE_T count, ULONG pattern
        //    for h2d read :  SIZE_T size, SIZE_T count
        // out: 
        //    for d2h write:  ULONG performance, ULONG tscCounter, ULONG deviceReadCompletionSize
        //    for h2d read :  ULONG performance, ULONG tscCounter 
        InBuffer[0] = (ULONG)h2d_size;
        InBuffer[1] = (ULONG)h2d_count;
        InBuffer[2] = (ULONG)d2h_size;
        InBuffer[3] = (ULONG)d2h_count;
        InBuffer[4] = (ULONG)d2h_pattern;

        GetDlg()->Log("TRIGGING DUAL DMA TRANSACTION.");
        GetCurrentTSC(tscStart);
        status = DeviceIoControl(hDeviceHandle, IOCTL_DMA_PCI_TEST, InBuffer, sizeof(ULONG) * 5, OutBuffer, sizeof(ULONG) * 5, &ulBytes, NULL);
        GetCurrentTSC(tscEnd);

        if (status && !(ulBytes == sizeof(ULONG) && OutBuffer[0] == (ULONG)-1))
        {
            TimeElapse[0] = (ULONG)(OutBuffer[0] * PCI_FREQ);               // h2d performace
            TimeElapse[1] = (ULONG)(OutBuffer[1] / (nCPUFreq / 1000.0));    // h2d drv tsc in ns
            TimeElapse[2] = (ULONG)(OutBuffer[3] * PCI_FREQ);               // d2h performace
            TimeElapse[3] = (ULONG)(OutBuffer[4] / (nCPUFreq / 1000.0));    // d2h drv tsc in ns
            TimeElapse[4] = (ULONG)((tscEnd - tscStart) / (nCPUFreq / 1000.0)); // ns in app

            GetDlg()->Log("DUAL DMA TRANSACTION succeeded.");

			if (SKIP_APP_INTERRUPTED && (TimeElapse[4] > SKIP_APP_PARAM * TimeElapse[1]) || (TimeElapse[4] > SKIP_APP_PARAM * TimeElapse[3]))
			{
				GetDlg()->Log("Application is interrupted.");
				continue;
			}

            break;
        }
        else
        {
            TimeElapse[0] = 0;
            TimeElapse[1] = 0;
            TimeElapse[2] = 0;
            TimeElapse[3] = 0;
            TimeElapse[4] = 0;

            GetDlg()->Log("DUAL DMA TRANSACTION failed.");
        }
    }

    return status;
}


BOOL    Test_ReadREG(HANDLE hDeviceHandle, ULONG uAddr, ULONG& uData, ULONG * pTimeElapse, ULONG uRepeatTimes)
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;

    InBuffer[0] = uAddr;
    InBuffer[1] = uRepeatTimes;

    status = DeviceIoControl(hDeviceHandle, IOCTL_READ_REG, InBuffer, sizeof(ULONG) * 2, OutBuffer, sizeof(ULONG) * 2, &ulBytes, NULL);

    if (status)
    {
        uData = OutBuffer[0];
        if (pTimeElapse)
            *pTimeElapse = (ULONG)(OutBuffer[1] / (nCPUFreq / 1000.0));    // ns
    }
    else
    {
        uData = 0;
    }

    return status;
}


BOOL    Test_WriteREG(HANDLE hDeviceHandle, ULONG uAddr, ULONG uData, ULONG * pTimeElapse, ULONG uRepeatTimes)
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;

    InBuffer[0] = uAddr;
    InBuffer[1] = uData;
    InBuffer[2] = uRepeatTimes;

    status = DeviceIoControl(hDeviceHandle, IOCTL_WRITE_REG, InBuffer, sizeof(ULONG)*3, OutBuffer, sizeof(ULONG), &ulBytes, NULL);

    if (status)
    {
        if (pTimeElapse)
            *pTimeElapse = (ULONG)(OutBuffer[0] / (nCPUFreq / 1000.0));    // ns
    }
    else
    {
        uData = 0;
    }

    return status;
}


void CalculateBPS(int BYTES, int ns, double& Bps, int& unit)
{
    if (BYTES > ns)
    {
        unit = 3;  // GBps
        Bps  = BYTES / (ns);
    }
    else if(BYTES > ns / 1000)
    {
        unit = 2;   // MBps
        Bps  = BYTES / (ns / 1000.0);
    }
    else if(BYTES > ns / 1000 / 1000)
    {
        unit = 1;   // KBps
        Bps  = BYTES / (ns  / 1000.0 / 1000.0);
    }
    else
    {
        unit = 0;   // Bps
        Bps  = BYTES / (ns / 1000.0 / 1000.0 / 1000.0);
    }
}

CString GetUnitStr(int unit, int unitType)
{
    char *szUnitBps[] = {"Bps", "KBps", "MBps", "GBps"};
    char *szUnitBytes[] = {"Bytes", "KBytes", "MBytes", "GBytes"};

    if (unitType == 0 && unit >= 0 && unit <sizeof(szUnitBps)/sizeof(szUnitBps[0]))
        return szUnitBps[unit];

    if (unitType == 1 && unit >= 0 && unit <sizeof(szUnitBytes)/sizeof(szUnitBytes[0]))
        return szUnitBytes[unit];

    return "";
}

void    Test_Reset(HANDLE hDeviceHandle)
{
    BOOL    status = TRUE;
    ULONG   ulBytes;

    GetDlg()->Log("Reset device.");

    status = DeviceIoControl(hDeviceHandle, IOCTL_DEVICE_RESET, NULL, 0, NULL, 0, &ulBytes, NULL);

    if (!status)
    {
        TRACE("RESET FAILED!\n");
    }
}

void CALC_BPS_UNIT(int a, double& b, int& c)
{
    if ((a) > 1000 * 1000 * 1000)
    {                                           
        (c) = 3;                                
        (b) = (a) / (1000.0 * 1000 * 1000);     
    }                                           
    else if((a) > 1000 * 1000)
    {                                           
        (c) = 2;                                
        (b) = (a) / (1000.0 * 1000);            
    }                                           
    else if((a) > 1000)
    {                                           
        (c) = 1;
        (b) = (a) / 1000.0;
    }
    else
    {
        (c) = 0;
        (b) = (a);
    }
}

BOOL    Test_GetRegAddress(HANDLE hDeviceHandle, ULONG uBuffer[3])
{
    BOOL    status = TRUE;
    ULONG   InBuffer[256];
    ULONG   OutBuffer[256];
    ULONG   ulBytes;

    GetDlg()->Log("Getting REG mapping address.");
    status = DeviceIoControl(hDeviceHandle, IOCTL_GET_REGADDRESS, InBuffer, sizeof(ULONG), OutBuffer, sizeof(ULONG)*3, &ulBytes, NULL);

    if (status)
    {
        uBuffer[0] = OutBuffer[0];
        uBuffer[1] = OutBuffer[1];
        uBuffer[2] = OutBuffer[2];

        GetDlg()->Log("REG mapping address got.");
    }
    else
    {
        GetDlg()->Log("Failed to get REG mapping address.");
    }

    return status;
}

⌨️ 快捷键说明

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