数据采集卡驱动程序完成以下功能:应用程序控制数据采集卡工作方
式,向数据采集卡工作方式缓冲器发送工作方式控制字;应用程序查询数据采集卡
工作状态,从数据采集卡工作状缓冲器读取工作状态字;为了使应用程序能实时处
理数据采集卡上采集到的数据,SRAM 与主机内存之间要实现 DMA 方式的数据传
输。
采用 VC+DDK+Driverworks进行驱动程序开发,Driverworks 为驱动程序
开发提供向导,可以方便的建立一个驱动程序框架。下面分别说明控制命令和DMA
方式传输数据的实现方法。
1)主机发送数据采集卡控制命令实现
Driverworks 利用 KMemoryRange 和 KIoRange 实现内存和 I/O 映射空间的
读写,通过配置 EEPROM,将 PCI9054 的 Base2 空间设定为一个内存映射空间,局
部端 FPGA 上配置的 FIFO 地址空间映射到该内存空间,这样对 FIFO 的访问,就是
访问 Base2 空间。驱动程序中,创建对象 KMemoryRange m_MemoryRangeForB2,并
在 OnStartDevice(KIrp I)例程中对该对象初始化,使该对象与 Base2 空间关联,
初始化以后,驱动程序其他例程就可以使用对象
m_MemoryRangeForB2,调用 KMemoryRange 类的成员函数 ind、inw、inb、
outd、outw、outb 完成对 PCI9054 Base2 空间的双字、字、字节的输入输出操
作,也就是对数据采集卡 FPGA 里边 FIFO 双字、字、字节的输入输出操作。对 IO
端口的访问类似,只是使用的是 KIoRange 类来完成。
需要注意的是 PCI9054 Base0、Base1 固定设置为内存映射空间和 I/O 映
射空间,用于 PCI9054 内部寄存器的访问,Base2、Base3 用户自己根据 EEPROM 配
置来设定为内存映射空间或者 I/0 映射空间。在驱动程序设计过程中,经常需要设
置和查询 PCI9054 内部寄存器,访问 PCI9054 内部寄存器,要用到 Base0 或 Base1
空间,本设计中,对 PCI9054 内部寄存器访问利用 Base1,即 IO 映射空间,比
如:PCI9054 DMA 通道 0 传输字节数寄存器偏移为 0x8C,若要设定 DMA 通道 0 一次
传输的字节数,可以通过初始化了的 KIoRange 对象 m_IoRange0 的成员函数 outd
来实现。
下面以主机由驱动程序向数据采集卡发送工作方式控制字为例,说明
KMemoryRange 成员函数访问硬件的方法,代码中 m_MemoryRangeForB2为
KMemoryRange 对象,用于 Base2 空间的访问。
NTSTATUS DZDevice::DZDRIVER_IOCTL_Write_Handler (KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
PULONG pBuffer=(PULONG)I.IoctlBuffer();//输入参数
ULONG m_Offset=*pBuffer; //控制字寄存器在局部地址空间上的偏移
ULONG m_Data=*(pBuffer+2) ;//控制字
m_MemoryRangeForB2.outw(m_Offset,m_Data);//向寄存器写控制字
I.Information() = sizeof(ULONG); //本次操作传输的字节数
return status; }
驱动程序控制字写函数中,首先取得从应用程序传递的偏移地址和控制字
的指针,偏移地址和控制字存储在 IRP 的 AssociatedIrp 域中 SystemBuffer 指针
指向的缓冲区,驱动程序先取得指向该缓冲区的指针,然后分别取得偏移地址和控
制字,最后向该偏移地址写控制字,程序执行后,即向硬件上的寄存器写入了相应
的控制字。
2)DMA 方式读取 FPGA 上 FIFO 数据实现
DriverWorks 提供了 3 个类 KDmaAdapter、KDmaTransfer、
KCommonDmaBuffer 用于实现 DMA 操作,KDmaAdapter 类用于建立一个 DMA 适配器对
象,说明 DMA 通道特性和提供串行化访问的服务;KDmaTransfer 类用于启动,控
制 DMA 的传输以及 DMA 传输结束后数据由公用缓冲区拷贝靠应用程序数据缓冲区;
KCommonDmaBuffer 类用于申请系统提供的公用缓冲区。DriverWorks 中,实现 DMA
传输过程如图 3 所示。
首先在设备启动例程(OnStartDevice)中创建一个 KDmaAdapter 类实例且
在适配器对象描述表中正确描述适配器对象;创建一个 KCommonDmaBufer 类实例,
调用该类的成员函数 Initialize 初始化公用缓冲区大小;创建一个 KDmaTransfer
类实例,并初始化为使用公用缓冲区作为 DMA 数据区。然后编写 KDmaTransfer 回
调函数 OnDamReady,回调函数中,先调用成员函数 ByteRemaining(),判断数据是
否传输完成。若完成,则调用函数 Terminate()完成相应当 IRP;未完成,则调用
GetTransferDescripters(),获取当前传输数据的物理地址,传输字节数,然后进
入 StartDMA 例程设置 PCI9054 的 DMA 寄存器,开始真正数据传输。当前段传输完
成时,PCI9054 的 DMA 中断控制器产生一个 DMA 中断,进入中断服务例程
(ISR),中断服务例程中,首先判断是否为 DMA 通道的中断,然后禁止本次中
断,再清除本次中断,最后连接到延时过程调用(DPC)。延时过程调用(DPC)中,调
用 KDmaTransfer 类的 Continue()成员函数,继续下一个段传输,直到 DMA 数据传
输结束,完成该 IRP。
驱动程序设计实现
hhappy01234567892023-08-21 16:58
相关推荐
156082072195 小时前
JFMRFVU3P5G的bit正常,但烧录mcs程序后加载异常狂奔蜗牛(bradley)6 小时前
把 EtherCAT 初始化从 FPGA 搬到 ARM:命令通道的接口设计与11个坑女神下凡1 天前
芯参谋(37):EEPROM_电路设计指南szxinmai主板定制专家2 天前
工业视觉新思路:FPGA图像预处理+RK NPU推理,实现高速缺陷检测FPGA小徐2 天前
【硬件实战】立创 EDA 绘制 TF/SD 卡模块电路|SPI 模式原理图 + 阻抗匹配 + PCB 布局布线全教程狂奔蜗牛(bradley)2 天前
EtherCAT DC 分布式时钟同步的 ModelSim 仿真:从帧模板到从站行为建模ALINX技术博客3 天前
8 通道同步采样 ADC!AN706 波形显示实验 【FPGA黑金云课堂】szxinmai主板定制专家3 天前
RK3568+FPGA+CODESYS异构控制方案:赋能半导体设备与工业自动化升级辰丁电子3 天前
allegro入门教程-菜单栏LogicFPGA小徐4 天前
数字IC/FPGA设计基础_ILA原理与使用