平台:ise14.7,Win driver10.21,Visual Studio 2015,LabWindows CVI 2013
操作系统:Windows7
硬件设备:PCI板卡
最近在开发过程中,作为一个逻辑开发人员。需要在PCI总线上映射其他接口时序。在写入周期期间将PCI总线上的写入接入其他接口上,在读取期间将PCI总线上的读取时序接入其他接口上并添加初始化延迟16个周期。
在使用Windriver驱动开发,和CVI驱动开发测试硬件的读写时发现了一个现象。
在CVI中插入读写BAR1空间代码。
///初始化操作如下///
///
for(int i=0;i<10000;i++)
{
viOut32(*vi, RAM_SPACE, 0x00, 0xaaaa);
viIn32(*vi, RAM_SPACE, 0x00, &val32_1);
viOut32(*vi, RAM_SPACE, 0x00, 0xaaaa);
viIn32(*vi, RAM_SPACE, 0x00, &val32_1);
if(val32_1 != 0xaaaa)
printf("diffenent from = %i read bar0 0x00 =%x write data is =%x\n",i,val32_1,0xaaaa);
viOut32(*vi, RAM_SPACE, 0x00, 0x5555);
viIn32(*vi, RAM_SPACE, 0x00, &val32_1);
if(val32_1 != 0x5555)
printf("diffenent from = %i read bar0 0x00 =%x write data is =%x\n",i,val32_1,0x5555);
}
下面说明一下读写这两个函数。
viOut32(vi, SPACE, Offset, value);
viIn32(vi, SPACE, Offset, value);
viOut32:向接口中写入32位单位数据。
viIn32:从接口中读取32位单位数据。
vi | SPACE | Offset | value |
外部设备的句柄 | 外部设备上的BAR空间。 | 偏移地址 | Write:写入值。 Read:读出值。 |
测试启动CVI,安装CVI的驱动文件。我直接在INF文件中修改PCI相关的参数。Vender ID与Device ID。
如图中所示,这是CVI生成的驱动IN文件。这里我们之间查找替换,将设备ID替换为当前PCI设备ID号。
启动CVI读写后,并未出现读写不一致的情况(报错)
启动Windriver生成驱动文件,启动测试。
for (int i = 0; i < 10; i++)
{
//read/write bar0
/*
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);
*/
//read/write bar1
WDC_WriteAddr32(hDev, 0x00000001, 0x00000000, 0x00005555);
WDC_ReadAddr32(hDev, 0x00000001, 0x00000000, &u32Data);
WDC_WriteAddr32(hDev, 0x00000001, 0x00000000, 0x00005555);
WDC_ReadAddr32(hDev, 0x00000001, 0x00000000, &u32Data);
WDC_WriteAddr32(hDev, 0x00000001, 0x00000000, 0x00005555);
WDC_ReadAddr32(hDev, 0x00000001, 0x00000000, &u32Data);
//if (u32Data != 0x00005555)
//printf("diffenent from = %i read bar1 0x00 =%x write data is =%x\n", i, u32Data, 0x00005555);
WDC_WriteAddr32(hDev, 0x00000001, 0x00000000, 0x0000aaaa);
WDC_ReadAddr32(hDev, 0x00000001, 0x00000000, &u32Data);
if (u32Data != 0x0000aaaa)
printf("diffenent from = %i read bar1 0x00 =%x write data is =%x\n", i, u32Data, 0x0000aaaa);
}
这里关于如何使用已经在上一篇文章中。
(646条消息) Windriver驱动开发工具使用快速入门_hy_520520的博客-CSDN博客
启动后,运行代码发现出现了如下错误。
在ISE中添加chipscope采集。
发现了问题所在。即CVI执行:
viOut32(vi, SPACE, Offset, value);
viIn32(vi, SPACE, Offset, value);
读速度比wivdriver执行:
WDC_ReadAddr32(hDev, dwAddrSpace, dwOffset, &u32Data) :
WDC_WriteAddr32(hDev, dwAddrSpace, dwOffset, u32Data);
执行的速度要慢。
具体的信号采集情况如下。
首先是使用CVI执行viOut32,viIn32。可以看到波形在执行了一次写入后,在执行下一个读出的时候大概使用了200个周期左右。
下面是使用WinDriver使用VS2015读写的采集情况。代码中我们使用了四次读写,可以看到使用WinDriver驱动WDC_ReadAddr32,WDC_WriteAddr32的执行速度要比CVI的执行速度快很多。写入后读出的执行,在写入后五个周期就会进入读出阶段。在下一次写入读出之间间隔了100个周期左右。
分析可以知道,使用WinDriver生成的驱动代码执行速度更快,反应更接近硬件。而CVI的代码执行到硬件层后速度较慢。