摘要

WinDriver是Jungo公司出版的一个设备驱动程序开发组件,它可以大大加速PCI设备驱动程序的开发。作者在实际的项目中采用了WinDriver来开发设备驱动程序,取得了相当好的运行效果。从目前国内的资料上来看,大多数设计人员还是在用DDK、Wtools开发设备驱动程序,因而作者觉得有必要向大家介绍与推荐这个软件。
WinDriver是一套设备驱动程序开发组件,它的目的就是方便Windows程序员快速开发出PCI/ISA设备的Windows驱动程序(目前最新的版本V4.32还支持PCMCIA、USB设备的驱动程序的开发,并且除了支持Windows9X/NT系统外,还有支持Unix、Windows CE的版本推出)。利用WinDriver开发设备驱动程序,不需要熟悉操作系统的内核,整个驱动程序中的所有函数都是工作在用户态下的,通过与WinDriver的.Vxd或者.Sys文件交互来达到驱动硬件的目的。由于是一个用户态程序,效率的高低也就成了人们选择WinDriver时关心的一个问题。大量实践数据表明,WinDriver并没有通过牺牲系统性能来换取驱动程序的快速开发,的确是一个“像开发用户态程序那样简单,像核心态程序那样高效”[1]的开发工具。
图1是WinDriver的体系结构图。

1 WinDriver主要特征

·提供了从用户层访问硬件的简单方法;
·能够方便地将性能要求特别苛刻的部分通过Windriver提供的API插入到核心态模式运行,提高执行效率;
·对主流PCI接口芯片(AMCC、PLX、V3系列)提供了很好的支持;
·可以利用常见的软件开发平台(Visual C++、Borland C++、VB4、Java、Delphi);
·支持I/O、DMA、中断处理,支持PCI、ISA、EISA设备的开发;
·无需DDK以及核心态程序开发的经验。

2 开发步骤

a.根据WinDriver的文档,建议开发步骤如下:
·修改代码,加入定制功能;
·在用户态执行与调试代码;
·将性能苛刻部分插入到核心态;
b.我们在实际编写驱动程序的过程中发现,完全用WinDriver提供API来写驱动程序比在Wizard生成的框架代码上修改更为灵活。一般来说,PCI驱动程序分成3个部分:初始化部分,对硬件资源的访问函数库、具体调用部分。其中,后面两个部分对于不同的硬件都是基本一致的。比如说,我们先后开发的基于AMCC5933与PLX9052的PCI接口卡,对于他们的硬件资源访问,用的都是WinDriver下面相同的API;两者开发的不同只在于初始化时对于硬件资源的锁定。所以只要开发出了针对一种接口芯片的系统的驱动代码后,以后一般只要修改接口芯片的ID值及一些寄存器的偏移值,就能够移植了,比每次生成不同的框架代码再改动也许要更简便。

3 实例分析

整个驱动程序的结构大致如下:
·打开WinDriver设备;
·查找我们要访问的PCI设备;
·枚举该设备的资源(内存、I/O、中断);
·锁定该设备的资源只能为我们所用,不能被其他程序访问;
·访问板上的资源;
·解锁资源;
·关闭WinDriver设备。
以下为一段使用WinDriver开发的AMCC5933DMA的驱动代码,利用这个程序来演示WinDriver的程序结构。这个程序只要稍加修改,就可以用来作为其他PCI卡的驱动程序的一部分,例如PLX9050、9054。为了节省篇幅,省略了变量说明部分。程序中出现的变量大都由其名称可以反映含义,具体可以参见WinDriver的设计文档中的说明。
hWD=WD_Open(); //打开WinDriver设备,每次使用前必须调用;
pciScan.searched.dwVendorId=0x10e8; //AMCC公司供货号
pciScan.searched.dwDeviceId=0x4750; //AMCC5933的设备号
WD_PciScanCards (hWD,&pciSxcan); //枚举PCI槽上的设备
pciSlot =pciScan.cardSilt[0]; //假设只有我们一个设备得到设备槽的号码
pciCardInfo.pciSlot=pciSlot;
WD_PciGetCardInfo(hWD,&pciCardInfo); //得到该设备槽上的设备信息
Card=pciCardInfo.Card; //Card为一个反映PCI卡上资源的结构
cardReg.Card=Card;
WD_CardRegister(hWD,&cardReg); //向核心态登记,锁定卡上资源
Item=Card.Item[2]; //将卡上的号为2的资源赋给Item
if(Item.item==ITEM_MEMORY)
{
regAddr=Item.I.Mem.dwUserDirectAddr; //得到PCI卡上的内存映射到用户态的地址
}
Dma1.dwBytes=4*dwDWord;
Dma1.pUserAddr=pBuffer1;
Dma1.dwOptions=0;
WD_DMALock(hWD,&Dma1); //锁定用于DMA的内存资源
至此与PCI卡上的内存进行DMA传输的准备已经完成,下面只要写相应的控制字就可以启动DMA操作了。

4 常见问题的解答

(1)评估版本的功能限制及其解决
评估版本除了30天的限制外,与正式版本相比还有3个限制。其中影响最大的是所有的关闭函数(DMA锁定内存的解锁,资源的关闭…)都加了延时。这样我们在做数据采集卡的驱动程序时就要注意,最好只分配一次资源。比如说做DMA操作,不要反复地锁定内存,这样会在解锁时损失效率。一个折衷的方法是锁定DMA内存后,一旦这块内存写满后,就将其中数据拷到用户态程序分配的大内存中去。
(2)用WinDriver开的程序效率
在使用WinDriver或者VxdTools这类工具时,大家最关心的一个问题可能就是效率问题。从实践与分析来看,WinDriver生成的驱动代码的效率相当地高。比如PCI卡的高速数据采集涉及到DMA的应用,WinDriver提供相应的API来将卡上的内存映射到用户态程序所能直接访问的地址空间中,然后直接对这个映射后得到的地址进行DMA操作。也就是说,与用DDK来直接编写驱动程序的区别就在于地址映射的操作上,在这部分工作上面,用WinDriver的API肯定没有直接用DDK写的专门面向特定硬件优化的代码来得高效。但是这部分代码实际上属于初始化工作,这部分的效率高低事实上并不会影响总体上的效率。
实际中,用WinDriver编写的PCI驱动程序在赛扬466、64M内存的机器上,在8位模式下可以稳定地采集4~8Mbytes/s的数据。而且随着硬件设计的改变,肯定还有提高余地。
经过实际应用,发现WinDriver这个软件使用快速,无论是开发效率还是实际达到的性能指标都相当令人满意。特别对于硬件开发人员来说,可以不必了解繁琐的操作系统的内核知识,就可以快速地开发出驱动程序,对于调试硬件是一个很好的帮助工具。

利用WinDriver开发PCI设备驱动程序的更多相关文章

  1. 【DSP开发】【Linux开发】Linux下PCI设备驱动程序开发

    PCI是一种广泛采用的总线标准,它提供了许多优于其它总线标准(如EISA)的新特性,目前已经成为计算机系统中应用最为广泛,并且最为通用的总线标准.Linux的内核能较好地支持PCI总线,本文以Inte ...

  2. Linux下PCI设备驱动程序开发 --- PCI驱动程序实现(三)

    三.PCI驱动程序实现 1. 关键数据结构 PCI设备上有三种地址空间:PCI的I/O空间.PCI的存储空间和PCI的配置空间.CPU可以访问PCI设备上的所有地址空间,其中I/O空间和存储空间提供给 ...

  3. DriverStudio开发PCI设备DMA数据传输

    DriverWizard向导可以创建基本的wDM驱动程序框架,包括总线类型,地址空间,中断源,DMA资源,以及IOCTL(i/o控制代码)的定义等等.详细情况可参看DriverStudio的帮助文档, ...

  4. 【VS开发】【DSP开发】浅谈Linux PCI设备驱动(二)

    我们在 浅谈Linux PCI设备驱动(一)中(以下简称 浅谈(一) )介绍了PCI的配置寄存器组,而Linux PCI初始化就是使用了这些寄存器来进行的.后面我们会举个例子来说明Linux PCI设 ...

  5. 【VS开发】【DSP开发】浅谈Linux PCI设备驱动(一)

    要弄清楚Linux PCI设备驱动,首先要明白,所谓的Linux PCI设备驱动实际包括Linux PCI设备驱动和设备本身驱动两部分.不知道读者理不理解这句话,本人觉得这句话很重要,对于PCI.US ...

  6. linux设备驱动程序注冊过程具体解释

    Linux的驱动程序注冊过程,大致分为两个步骤: 模块初始化 驱动程序注冊 以下以内核提供的演示样例代码pci-skeleton.c,具体说明一个pci设备驱动程序的注冊过程.其它设备的驱动代码注冊过 ...

  7. WindowsNT设备驱动程序开发基础

    一.背景介绍 1.1WindowsNT操作系统的组成1.1.1用户模式(UserMode)与内核模式(KernelMode) 从Intel80386开始,出于安全性和稳定性的考虑,该系列的CPU可以运 ...

  8. 【DSP开发】【Linux开发】IIC设备驱动程序

    IIC设备是一种通过IIC总线连接的设备,由于其简单性,被广泛引用于电子系统中.在现代电子系统中,有很多的IIC设备需要进行相互之间通信 IIC总线是由PHILIPS公司开发的两线式串行总线,用于连接 ...

  9. Linux内核入门到放弃-设备驱动程序-《深入Linux内核架构》笔记

    I/O体系结构 总线系统 PCI(Peripheral Component Interconnect) ISA(Industrial Standard Architecture) SBus IEEE1 ...

随机推荐

  1. 破解之关键CALL与关键跳查找方法

    找关键CALL和关键跳 方法一: 输入假码注册程序,记录下错误提示信息. OD载入程序--> 右键-->查找-->所有参考文本字串-->(右键-->查找文本,注:不要区分 ...

  2. ArrayList与LinkedList实现比较

    1.ArrayList实现是基于数组来实现的,这可由ArrayList的源码看出: public class ArrayList<E> extends AbstractList<E& ...

  3. WAF

    http://netsecurity.51cto.com/art/201010/231124.htm http://wenku.baidu.com/link?url=elrFtxPRcwJ5FjlXE ...

  4. 【UVA1331】关于最优三角剖分

    最近在练习DP专题,学会了很多表示方法和转换方法,今天做最优三角剖分的时候发现脑子卡了,不会表示状态,于是写个博客记录一下. 最优三角剖分的一类题目都是差不多的.给你一个多边形,让你把它分割成若干个三 ...

  5. ANDROID_MARS学习笔记_S02重置版_001_Hander\Looper\Message\Thread\ThreadLocal

    一. * class LooperThread extends Thread { * public Handler mHandler; * * public void run() { * Looper ...

  6. 【Xamarin 跨平台机制原理剖析】

    原文:[Xamarin 跨平台机制原理剖析] [看了请推荐,推荐满100后,将发补丁地址] Xamarin项目从喊口号到现在,好几个年头了,在内地没有火起来,原因无非有三,1.授权费贵 2.贵 3.原 ...

  7. xmanager远程登录

  8. bzoj1486

    这里学了一个新知识叫分数规划这道题目是求∑w[i]/S最小首先二分答案k,然后如果某个环∑w[i]/S<=k即∑w[i]<=k*S-->∑w[i]-k*S<=0--->∑ ...

  9. VS2010引用项目dll,编译时报错

    截图出处:http://www.cnblogs.com/wuhuisheng/archive/2012/02/13/2349754.html

  10. 洛谷1377 M国王 (SCOI2005互不侵犯King)

    洛谷1377 M国王 (SCOI2005互不侵犯King) 本题地址:http://www.luogu.org/problem/show?pid=1377 题目描述 天天都是n皇后,多么无聊啊.我们来 ...