Windriver驱动开发工具使用快速入门

平台:ise14.7,Win driver10.21,Visual Studio 2015

操作系统:Windows7

硬件设备:PCI板卡

最近在开发过程中,作为一个逻辑开发人员,在有的的情况下需要自己快速验证逻辑正确性。我使用WinDriver来作为驱动开发软件进行简单调试硬件设备。适合我们这种初学者使用,我们不需要设计复杂的驱动程序,就可以验真硬件的正确性。今天我们使用WinDriver来进行PCI的简单访问,在使用WinDriver生成简单的驱动代码,来对硬件进行连续读写访问。

这里省略FPGA关于PCI开发的部分。

我们在xilinx的PCI的IP核中定义PCI板卡信息。Vender ID,Device ID以及板卡的BAR空间。我们这里定义使用BAR0和BAR1空间。下载逻辑到PCI板卡后。打开WinDriver设备。

Windriver驱动开发工具使用快速入门_第1张图片

打开New host driver project。

Windriver驱动开发工具使用快速入门_第2张图片 

找到该设备。双击进入该设备。

Windriver驱动开发工具使用快速入门_第3张图片 

找到两个BAR空间。

读写BAR空间。

Windriver驱动开发工具使用快速入门_第4张图片

这里完成了简单的硬件读写测试。

下面我们使用WinDriver生成驱动。

Windriver驱动开发工具使用快速入门_第5张图片

Windriver驱动开发工具使用快速入门_第6张图片 

Windriver驱动开发工具使用快速入门_第7张图片 

保存后,进行进入WinDriver,点击project。生成代码。

Windriver驱动开发工具使用快速入门_第8张图片 

下一步生成代码,选择如下。

Windriver驱动开发工具使用快速入门_第9张图片 

继续选择。

 Windriver驱动开发工具使用快速入门_第10张图片

Windriver驱动开发工具使用快速入门_第11张图片 

生成的文件夹如下。x86里面就是生成的代码。

Windriver驱动开发工具使用快速入门_第12张图片 

下面我们为硬件设备安装驱动文件,生成的驱动就是你保存的文件下面的.inf文件。点击更新驱动文件。

 Windriver驱动开发工具使用快速入门_第13张图片

Windriver驱动开发工具使用快速入门_第14张图片 

Windriver驱动开发工具使用快速入门_第15张图片 

Windriver驱动开发工具使用快速入门_第16张图片 

Windriver驱动开发工具使用快速入门_第17张图片 

Windriver驱动开发工具使用快速入门_第18张图片 

接下来,我们打开工程。pci_driver_diag.c就是我们需要看的。在此里面添加简单的测试代码,来测试我们的硬件设备。

Windriver驱动开发工具使用快速入门_第19张图片 

打开工程后如下。

Windriver驱动开发工具使用快速入门_第20张图片 

下面是我添加部分的代码。

这里主要说明两个函数。

     WDC_ReadAddr32(hDev, dwAddrSpace, dwOffset, &u32Data) :
     WDC_WriteAddr32(hDev, dwAddrSpace, dwOffset, u32Data);

WDC_WriteAddr32:向目标设备写入值。

WDC_ReadAddr32:从目标设备读出值。

hDev

dwAddrSpace

dwOffset

u32Data

外部设备的句柄

外部设备上的BAR空间。

偏移地址

Write:写入值。

Read:读出值。

 这里我在源代码基础上添加了一个for循环来循环向一个地址写入和读出。判断两者是否相等。不相等就报错。说明pci写入或者读取失败。

/* Read/write memory or I/O space address menu */
static void MenuReadWriteAddr(WDC_DEVICE_HANDLE hDev)
{
    DWORD option;
    static DWORD dwAddrSpace = ACTIVE_ADDR_SPACE_NEEDS_INIT;
    static WDC_ADDR_MODE mode = WDC_MODE_32;
    static BOOL fBlock = FALSE;

	UINT32 u32Data = 0;

    /* Initialize active address space */
    if (ACTIVE_ADDR_SPACE_NEEDS_INIT == dwAddrSpace)
    {
        DWORD dwNumAddrSpaces = PXI_DRIVER_GetNumAddrSpaces(hDev);
        
        /* Find the first active address space */
        for (dwAddrSpace = 0; dwAddrSpace < dwNumAddrSpaces; dwAddrSpace++)
        {
            if (WDC_AddrSpaceIsActive(hDev, dwAddrSpace))
                break;
        }
        
        /* Sanity check */
        if (dwAddrSpace == dwNumAddrSpaces)
        {
            PXI_DRIVER_ERR("MenuReadWriteAddr: Error - no active address spaces found\n");
            dwAddrSpace = ACTIVE_ADDR_SPACE_NEEDS_INIT;
            return;
        }
    }

    do
    {
        printf("\n");
        printf("Read/write the device's memory and IO ranges\n");
        printf("---------------------------------------------\n");
        printf("%d. Change active address space for read/write "
            "(currently: BAR %ld)\n", MENU_RW_ADDR_SET_ADDR_SPACE, dwAddrSpace);
        printf("%d. Change active read/write mode (currently: %s)\n",
            MENU_RW_ADDR_SET_MODE,
            (WDC_MODE_8 == mode) ? "8 bit" : (WDC_MODE_16 == mode) ? "16 bit" :
            (WDC_MODE_32 == mode) ? "32 bit" : "64 bit");
        printf("%d. Toggle active transfer type (currently: %s)\n",
            MENU_RW_ADDR_SET_TRANS_TYPE,
            (fBlock ? "block transfers" : "non-block transfers"));
        printf("%d. Read from active address space\n", MENU_RW_ADDR_READ);
        printf("%d. Write to active address space\n", MENU_RW_ADDR_WRITE);
        printf("%d. Exit menu\n", MENU_RW_ADDR_EXIT);
        printf("\n");
        
        if (DIAG_INPUT_FAIL == DIAG_GetMenuOption(&option,
            MENU_RW_ADDR_WRITE))
        {
            continue;
        }
        
        switch (option)
        {
        case MENU_RW_ADDR_EXIT: /* Exit menu */
            break;
        case MENU_RW_ADDR_SET_ADDR_SPACE: /* Set active address space for read/write address requests */
        {
            SetAddrSpace(hDev, &dwAddrSpace);
            break;
        }
        case MENU_RW_ADDR_SET_MODE: /* Set active mode for read/write address requests */
            WDC_DIAG_SetMode(&mode);
            break;
        case MENU_RW_ADDR_SET_TRANS_TYPE: /* Toggle active transfer type */
            fBlock = !fBlock;
            break;
        case MENU_RW_ADDR_READ:  /* Read from a memory or I/O address */
        case MENU_RW_ADDR_WRITE: /* Write to a memory or I/O address */
        {
            WDC_DIRECTION direction =
                (MENU_RW_ADDR_READ == option) ? WDC_READ : WDC_WRITE;

            if (fBlock)
                WDC_DIAG_ReadWriteBlock(hDev, direction, dwAddrSpace);
            else
                WDC_DIAG_ReadWriteAddr(hDev, direction, dwAddrSpace, mode);

			for (int i = 0; i <= 10; i++)
			{
				WDC_WriteAddr32(hDev, dwAddrSpace, 0x00000000, 0x00005555);
				WDC_ReadAddr32(hDev, dwAddrSpace, 0x00000000, &u32Data);
				printf(" from = %i read bar0 0x00 =%x write data is  =%x\n", i, u32Data, 0x00005555);
				if (u32Data != 0x00005555)
					printf("diffenent from = %i read bar0 0x00 =%x write data is  =%x\n", i, u32Data, 0x00005555);
				WDC_WriteAddr32(hDev, dwAddrSpace, 0x00000000, 0x0000aaaa);
				WDC_ReadAddr32(hDev, dwAddrSpace, 0x00000000, &u32Data);
				if (u32Data != 0x0000aaaa)
					printf("diffenent from = %i read bar0 0x00 =%x write data is  =%x\n", i, u32Data, 0x0000aaaa);
			}
            
            break;
        }
        }
    } while (MENU_RW_ADDR_EXIT != option);
}

运行代码。

Windriver驱动开发工具使用快速入门_第21张图片

Windriver驱动开发工具使用快速入门_第22张图片 

这里我们输入3:Read/write memory and IO addresses on the device

Windriver驱动开发工具使用快速入门_第23张图片 

我们可以看到这里bar空间选择的为BAR0,读写方式选择的为32位读写。

我们选择:Read from active address space。

继续输入偏移地址:00。

Windriver驱动开发工具使用快速入门_第24张图片

我们看到没有报错,说明读写正常。 

 

你可能感兴趣的:(fpga开发,驱动开发)