基于PCI总线的数字卫星解调卡驱动程序开发
进行DMA传输需要用到三个DMA传输类,分别为KdmaAdapter、KCommonDmaBuffer和KdmaTransfer。
KdmaAdapter是DMA适配器对象,可用于表示需要进行DMA传输的设备资源。此对象对于Master设备和Slave设备都是适用的。驱动中,此类函数可在On Start Device中由成员函数Initialize初始化。
KconnonDmaBuffer是DMA通用缓冲区对象。驱动中,此类可在On Start Device中由成员函数Initialize初始化。通用缓冲区是外部设备和驱动程序之间的一段物理上连续的虚拟内存,这个内存是从系统中分配出来的,是非常珍贵的资源,任何时候都可以被他的设备和驱动程序存取。通用缓冲区包括缓冲区空间大小、虚拟地址、逻辑地址等信息。由于通用缓冲区是非常珍贵的资源,所以它的大小也受到限制。为此,驱动时应对每个DMA请求进行分段,并为每个段提供一个传输段描述符数组。而且,当设备不支持分散/集中时,这个数组中的描述符只能有一个。每个描述符包含一个物理地址和相应的字节数,其结构如下:
其中的物理地址即逻辑地址,字节数则是相应的逻辑地址范围的长度。
KdmaTransfer为DMA传输对象,用来管理内存和设备之间的数据传输,但此时的DMA适配器必须可用。适配器对象可用来通知传输数据的类型和使用的DMA通道等。驱动中,此类可在OnStart Device中由成员函数Initialize初始化。在DMA传输中,数据可直接传输到系统物理内存中。管理这些内存的方式有Common Buffer和Packet两种。第一种方式是在物理内存中预先开辟一段连续的内存空间,CPU和PCI都可以对其进行访问,且在一次DMA传输过程中,物理地址保持不变,该方式适合传输大量数据和连续的DMA传输;而在Packet方式中,由于其内存物理地址不确定,因此适合间断性的DMA传输。
(2)回调函数
由于DMA传输采用分段传输,所以,每当准备传输一个新段时,KDmaTransfer的对象将通知驱动程序调用回调例程。回调函数的原型由typedef DMAREADY_CALLBACK指定,使用宏DEVMEMBER_DMAREADY可声明回调函数基类的成员函数。通过判断成员函数Bytes Remaining可判断传输是否完成。若返回值为0,则调用成员函数Terminate以完成相应的IRP,否则,回调函数继续传输。
(3)中断服务
本驱动需要处理两种中断,第一种是本地中断,它是当FIFO输出半满信号时由FPGA通过LINT#信号发给PCI9054的中断信号;第二种中断是DMA传输结束时由DMA中断控制器产生的。这两种中断可以通过对DMA的中断控制寄存器的特定位处理来区分。判断是否是本地中断时,可以通过判断DMA中断控制寄存器的第15位是否为1来确定,如果INTCSR[15]=1,则为本地中断;判断是否是DMA中断则可通过判断DMA中断控制寄存器的第23位是否为1来确定,如果INTCSR[23]=1,则为DMA中断。不同的中断,其处理方式不同。
3.3 驱动程序的创建及安装文件的修改
为了正确的创建WDM驱动程序,首先要建立WDM编程环境,并创建自己的库文件。参考文件中提供了一种WDM编程环境的建立方法,但是,按照书中的方法经常不能成功的建立编程环境,为此,笔者根据自己的经验介绍一种简单易行的方法:
(1)首先安装DDK;
(2)在开始菜单中选择Compuware Driver Studio\Develop下的DDK Build Setting;
(3)在打开的对话框中的DDK Root Directory中设置DDK的根目录(如E:\WINDDK\2600),然后点击Launch Program,并打开Compuware DriverStudio的Driver Works文件夹中Source里的VdwLibs.dsw文件。
(4)选择Build菜单中的Set Active Project Configuration,并在弹出的对话框中选择合适的Project configurations。而对于现行的32位机,它不需要像Win32 AMD64 Free等这样的工程;
(5)选好一个工程后,点击OK,然后点击Build with BUILD.EXE即可生成所需的库。然后再根据自己的需要重新选择新的Project configurations,以进行库的创建。
笔者的这种方法在于使用DDK Build Setting的Launch Program打开VdwILibs.dsw,编译没有出现错误,书中的方法则是先打开VC++,然后打开VdwLibs.dsw,选择Batch Build下的Rebuild All创建库,但是笔者试了几次均不成功。
库文件生成之后,即可打开创建好的驱动程序,并在VC++的菜单中打开DDK Build Setting,再在DDK Root Directory中设置DDK的路径为实际安装的路径,之后点击Build图标,就可以生成BPSKDRIVER.sys文件了。另外,驱动的类型可以自己设定,Windows系统定义了一系列的设备类名和GUID,找到驱动工程文件中后缀名为.inf的安装文件,将其内容修改成与硬件信息一致就可以了。然后将此文件拷贝到工程中的i386文件夹中。至此,一个完整的驱动就创建成功了。
- PCI9656型64位PCI总线接口电路及其应用(01-18)
- PCI9054芯片接口设计中若干问题的深入研究(01-18)
- TM1300 PCI-XIO口的UART和USB接口设计(01-17)
- 什么是PCI总线?其接口芯片的应用(01-26)
- PCI总线数据输出板驱动程序的开发(05-16)
- 基于PCI9054和LTC4240的CPCI总线接口设计(05-13)