找回密码
 立即注册
首页 业界区 业界 PCI9x5x驱动移植支持PCI9054在win7下使用1

PCI9x5x驱动移植支持PCI9054在win7下使用1

粉押淫 2 小时前
本驱动最终目的是为了将北京中泰联创科技有限公司的一个数据采集卡老产品驱动升级成WDF框架的新驱动,老驱动使用Driver Studio开发,在64位操作系统下不够稳定,所以要升级成WDF框架。后续用老产品称呼实际硬件,老驱动称呼Driver Studio开发的驱动,新驱动称呼WDF框架驱动。
开始的时候想使用Qoder直接分析老驱动后自动生成一个WDF框架驱动,结果没有成功,看来它并不是万能,编程过程中直接让他帮忙给些提示还是可以的,大家想要尝试Qoder可以在官网下载,也可以通过下面链接注册下载:
Qoder下载链接
修改示例程序支持Windows7

在“属性-Driver Settings-Target OS version”设置成windows7后,编译报告不支持1.19错误,改成1.11才能支持
但是1.11下不支持WdfDmaTransactionSetSingleTransferRequirement函数,注释掉后才能正常编译,这个函数用于确定DMA是否需要单次传输完所有数据,在本驱动中,可以通过同步IO来解决这个问题,后面再说
在目标机器上搭建调试环境

首先在windows11上配置,后续再使用windows7。
支持实验签名

64位系统必须得有数字签名才能够安装驱动,VS2017+WDK的编译环境可以自动加测试签名,所以只要将目标机开启TestSigning即可,这部分可以自行百度,或者直接使用签名工具“Windows 64Signer V1.2.exe”,它除了给驱动签名,还能开启TestSigning。
支持内核信息输出

debugview是可以显示内核信息的,但是示例驱动中使用WPP(Windows Software Trace Preprocessor)方式跟踪代码流程,需要进行一定的转换才能显示在debugview中,所以暂时先不使用debugview显示。
在Windows11下比较简单就可以使用工具显示WPP的输出信息,直接将WDK安装目录的可执行文件夹复制到目标机器即可,我的目录是:
C:\Program Files (x86)\Windows Kits\10\Tools\x64
将x64目录整个复制到目标机,然后以管理员身份运行运行traceview.exe
初次运行需要File-"Create New Log Session"-"DB(Debug Information) File"
选择编译目录的Pci9x5x.pdb
然后就能看到在驱动中输出的信息了。
寄存器定义

PCI9656与PCI9054在基地址、中断以及DMA操作方面的定义完全一样,只有其它一些没用到的功能定义不同,所以稍加改动就可以使用示例程序中的寄存器头文件。
分配资源

PLxPrepareHardware函数中分配资源
对于PCI总线,驱动使用BAR这个概念来分配寄存器资源,BAR是"Base Address Register"的缩写,也就是基地址寄存器,32位PCI总线最多6个BAR,根据找到顺序的不同,从BAR0~BAR5。
老驱动中9054分配资源操作:

按照资源序号:

  • BAR3对应本地译码地址,读写操作FPGA

    • 应用层读写IO使用

  • BAR2对应本地译码地址,读写操作FPGA

    • 内核操作使用

  • BAR1对应PCI9054地址,读写操作9054
不知道为何老驱动使用了两个BAR来操作相同的本地总线,新驱动应该使用一个即可。
新驱动中资源分配操作:

下面是PCI9656开发板的资源分配:

  • 找到内存方式且长度对应0x200,则对应BAR0,地址映射给Regs,直接使用结构体内成员来操作寄存器。
  • 找到IO方式且长度大于或者等于0x100,则对应BAR1,后续并没有处理这个资源。
  • 第一次找到内存方式且长度对应0x20000,则对应BAR2,后面映射地址给SRAMBase,但是也没有用到这个地址。
  • 第二次找到内存方式且长度对应0x20000,则对应BAR3,实际上后面没有处理这个资源
对于老产品,总的资源数量有9个,分配情况如下

  • 0 内存资源,长度=256(BAR0)
  • 1 129号资源,设备私有资源,应该用不到
  • 2 IO资源,长度256,PCI9054地址(BAR1)
  • 3 129号资源,设备私有资源,应该用不到
  • 4 内存资源,长度131,072(0x20000),这个应该是最早9054开发板的资源分配信息,老产品保留了这个设置,实际应该对应本地地址,操作FPGA。(BAR2)
  • 5 129号资源,设备私有资源,应该用不到
  • 6 IO资源,长度256,本地地址,操作FPGA(BAR3)
  • 7 129号资源,设备私有资源,应该用不到
  • 8 中断资源,这个以后再处理。
    之前无法确定哪个资源对应本地IO,因此需要测试52地址是否能返回0x3100来判断,如果返回0x3100则说明是本地IO
    经过测试后,6号资源(BAR2)对应本地寄存器,2号资源(BAR1)对应PCI9054寄存器。他们都是IO资源,可以直接使用READ_PORT_ULONG和WRITE_PORT_ULONG进行读写操作。内存资源需要使用“LocalMmMapIoSpace”函数转换后,才能使用WRITE_REGISTER_ULONG和READ_REGISTER_ULONG操作。个人感觉IO资源操作更方便,所以所有寄存器操作均使用IO资源。
仿照示例驱动,先找到的IO资源是PCI9054地址,后找到的IO资源是本地资源。修改后的代码如下:
  1. case CmResourceTypePort:
  2. //分配IO资源
  3.   bar = NULL;
  4.   if (!foundLocalPort && !found9054Port &&
  5.       desc->u.Port.Length == 0x100) {
  6.         found9054Port = TRUE;
  7.         bar = "BAR1-9054";
  8.         DevExt->Regs = (PPCI9656_REGS)UlongToPtr(desc->u.Port.Start.QuadPart);
  9.         DevExt->RegsLength = regsLength;
  10.       }
  11.       else if (!foundLocalPort &&
  12.                 desc->u.Port.Length == 0x100) {
  13.         foundLocalPort = TRUE;
  14.         bar = "BAR3-FPGA";
  15.         DevExt->addrLocal = (PUCHAR)UlongToPtr(desc->u.Port.Start.QuadPart);
  16.         DevExt->localLength = desc->u.Port.Length;
  17.       }
  18.       TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,
  19.                   " - Port   Resource [%08I64X-%08I64X], %s, i:%d length:%d",
  20.                     desc->u.Port.Start.QuadPart,
  21.                     desc->u.Port.Start.QuadPart +
  22.                     desc->u.Port.Length,
  23.                     (bar) ? bar : "<unrecognized>",
  24.                     i,
  25.                     desc->u.Port.Length);
  26. break;
复制代码
至此,资源分配部分代码完成,后续要修改其它具体操作。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册