用driverworks开发PCI驱动程序1

合集下载

一、如何编写LinuxPCI驱动程序

一、如何编写LinuxPCI驱动程序

⼀、如何编写LinuxPCI驱动程序PCI的世界是⼴阔的,充满了(⼤部分令⼈不快的)惊喜。

由于每个CPU体系结构实现不同的芯⽚集,并且PCI设备有不同的需求(“特性”),因此Linux内核中的PCI⽀持并不像⼈们希望的那么简单。

这篇简短的⽂章介绍⽤于PCI设备驱动程序的Linux APIs。

1.1 PCI驱动程序结构PCI驱动程序通过pci_register_driver()在系统中"发现"PCI设备。

事实上,恰恰相反。

当PCI通⽤代码发现⼀个新设备时,具有匹配“描述”的驱动程序将被通知。

详情如下。

pci_register_driver()将设备的⼤部分探测留给PCI层,并⽀持在线插⼊/删除设备[因此在单个驱动程序中⽀持热插拔PCI、CardBus和Express-Card]。

pci_register_driver()调⽤需要传⼊⼀个函数指针表,从⽽指⽰驱动程序的更⾼⼀级结构体。

⼀旦驱动程序知道了⼀个PCI设备并获得了所有权,驱动程序通常需要执⾏以下初始化:启⽤设备请求MMIO / IOP资源设置DMA掩码⼤⼩(⽤于⼀致性DMA和流式DMA)分配和初始化共享控制数据(pci_allocate_coherent())访问设备配置空间(如果需要)注册IRQ处理程序(request_irq())初始化non-PCI(即LAN/SCSI/等芯⽚部分)启⽤DMA /处理引擎当使⽤设备完成时,可能需要卸载模块,驱动程序需要采取以下步骤:禁⽌设备产⽣irq释放IRQ (free_irq())停⽌所有DMA活动释放DMA缓冲区(包括流式DMA和⼀致性DMA)从其他⼦系统注销(例如scsi或netdev)释放MMIO / IOP资源禁⽤该设备下⾯⼏节将介绍这些主题中的⼤部分。

其余部分请查看LDD3或<linux/pci.h>。

如果PCI⼦系统没有配置(没有设置CONFIG_PCI),下⾯描述的⼤多数PCI函数都被定义为内联函数,要么完全空,要么只是返回⼀个适当的错误代码,以避免在驱动程序中出现⼤量ifdefs。

基于Driver Studio的PCI设备WDM驱动程序的设计

基于Driver Studio的PCI设备WDM驱动程序的设计
EE l : 21 G C 7 0
基 于 D ie tdo的 P I 备 WD 驱 动 程序 的设 计 rvrSu i C 设 M
陈 宇 , 张小艳
/. 1 中科院长春光学精密机械与物理研究所 , 长春 10 3 . 303 、
\. 2中国科 学院研究 生院 , 北京 103 009
u igDr eW ok f r eS u i.T emanpo eso r e rg a a dt e e s u ha O,h n l s i r r so i r tdo h i r cs f i rpo rm n y c s / n v D v dv h k s I a de
Drv rS u o Ba e DM ie o ie t di s d W Drv r f rPCIBu v c sg sDe ieDe in
CH EN .ZHA NG i - n , Yu X ao ya
, . h n cu nt ue fO tc,Fie c a i n yis C a gh n10 3 , hn | 1C a g h nIsi t t o p is n Meh nc a dPh sc ,h n c u 30 3 C ia 、 s 的代码进行 了说 明, 并实现 了驱动程序 的安 装与调试 。最后对 实际中遇 到的问题及解 决方 法做了总结 , 实践证明该驱动程序调试通过 , 运行稳定 。
关键 词 :C 总线 ; M驱动程序; r e td ; PI WD D i r ui 驱动程序模型 vS o
中图分类 号 :N 0 T 62
文 献标识 码 : A
文章 编号 :O 599 (O8 O一o9o lO—4O 2O )3l6_4
P I 总线作为一种先进 的高性 能 3/4位 C[ 26 局部总线 , 非常适合计算机与外 围设备进行 高速数 据交 换 , 目前 P 是 C机 上 最 先 进 的 一 种 总 线 。 为 了 使计算机能获得数据并进行实时处理 , 软件的开发 是必不可少的环节。P I C 数据采集卡软件包括驱动 程序和应用程序 , 驱动程序负责与硬件的通信 , 应用

基于DDK的PCI总线数据交互驱动开发

基于DDK的PCI总线数据交互驱动开发

总线驱 动 已经 包含 在 Windows中,包括
与 PC问的数 据交互。
PCI、AGP、 串 口等 。总 线 驱 动 主 要 负 责 管 理
W indows上 开 发 驱 动 程 序 常 有 两 种 方 法 : 总线设备,例如当 PCI插槽上插入新硬件 ,开
(1) 使 用 微 软 提 供 的 DDK(Driver 启电脑并进入系统后总线驱动开始工作一一报
Windows下设备驱动程序的开发和调试 。
1驱 动 原理
在 窗 口概念 还 没 出现 的时代驱 动 就 已经 诞生 了。要 在操 作系统 中操作硬件 ,程序必须 通过 系统内核上的驱动来控制 ,这些驱动必须
将 驱动 程 序拷 贝 到 系 统 目录 并 通 过 写 入 注 册 表 建立服务 ,以便于驱动程序能在系统启动时被 加 载 。
执 行 效率 高 。
“即插 即 用 ”。功 能 驱 动 就 是 常 说 的 驱 动 程 序 。
Байду номын сангаас
(2) 通 过 使 用 Jungo公 司 的 WinDriver
驱 动 的工 作 流程 如 下 :
软件 生成驱动模板函数 ,根据 自己需求使用其
(1)创建设 备。在总线 驱动提示 发现新
提 供 的 API。此 法 可 以 不 需 了 解 内核 ,容 易入 硬 件 后 ,设 备 管 理 器 通 过 读 取 驱 动 程 序 inf文
发 驱动 程序 的 实现 方 式,着 重描 述 了开 发 过程 中的重要 步 骤, 实 现 了对 IO和 Memory的 读 写 及 DMA 方 式 进 行 PCI总 线 的 数 据 交 互 , 最 终 验 证 了驱 动 的通 信 功 能 。

Windows平台下PCI设备驱动程序的开发

Windows平台下PCI设备驱动程序的开发
Pc机总线大体可以分为三代,其代表分别是 ISA、PCI、PCI·E,速度越来越快,逐渐由并行向串行发 展。PCI总线特点是:可以进行突发式传输;总线操作 与处理器一存储器子系统操作并行;全自动配置与资 源分配,町实现即插即用;独屯于处理器,与CPU更新 换代无关,通用性好;PCI设备可以完全作为主控没备 控制总线;地址及数据奇偶校验系统更加可靠;中断是 电平触发,町以实现共享。
pDfiverO啦t一>MajorFunction[1RP_MJ_CLOSE]=
Dispatch_Close;
pDriverObject一>MajorFunction[IRP-MJ—READ]=
Dispatch—Read;
pDriverObject一>MajorFunction[IRP_MJ_WRITE]= Dispatch_Write;
万方数据
为广泛。 程序的人几函数DriverEntry中,主要的逻辑功能
是指定该驱动程序的各个功能函数的入【1:
pDriverObject一>DriverUnload=DriverUnload: pDriverObject一>MajorFunction[IRP_MJ_CREATE]=
Dispatch_Create;
户地址到PCI存储器地址的转换,这个映射在操作系 统中用一个内存描述表(MD!。)米表达,该农的内容如 图5所示‘2|。
用户模式虚拟地址 Vaddr a
物理地址 Paddr a

Vaddr n
Paddr n
图5 MDL的结构
这种情况下,应用程序访问PCI硬件地址对应的 虚拟地址时,操作系统通过访『nJ该MDL,把该虚拟地 址映射到相应的PCI存储器,达到直接访问的目的。 应川程序可以像访问系统的物理内存一样访问PCI的 硬件存储器。该过程町以这样总结:应用层虚拟地址 -+MDL映射_物理地址-+经过北桥_+对应PCI插槽 -+PcI桥芯片_【砒al地址_+板载RAM、FPGA。

利用WinDriver开发PCI设备驱动程序

利用WinDriver开发PCI设备驱动程序
95 接 E芯片做成的具有中断功能的数据采集卡的驱动程序开发 04 l 过程。在生成框架程序过程 中定义硬件设备为 P X 04 L g5 。
P) 04Mo E L N ) 195_ D — O G 【
EdI n f Px 0 4 R a L n = d t l9 5 ed o g aa
E d I n f E u nd S b
WD C rR gse0, ad e i r 负责选定设备 , t 且对该设备的项 目注册 和资源分配。具体完成三个功 能:1映射设备的物理 空间,使之 () 能够被杨 模 式的进程和用户模式的应用程序所访 问; ) ( 检查所 2 需存储器或 I O 资源先前是否被注册过 , / 以防设备冲突。 所有 操 作 结 束 后 , 关 闭 程 序 要 完 成 对 设 备 释 放 , 在
F nc i n P x9 5 Re dLo ( u to l 0 4 a ng hPi 9 5 As x 0 4
Px I - ND E,ad S aeA nee ,d fe sL n ) 】9 4 HA L d rp c s( P x 0 4完戚 ,其中调用 了下面两个 函数 l 9 5 一 o eh l 9 5 )
WD

_
对上述 函数稍加修改可完成对字节和单字的读写。 在程序中
通过me p 函数来访 问内存地址 , l9 5 _ e d i B ok mc y 在Px 04 R a Wr e lc t

C rUn ei e , WD— ad gs r0 相对应 ad rgs r0 与 t C rRei e t
删 除注册 的项 目并释放资源。
WD

C oe0 , WD OEn 0 相对应 , ls 与 _!  ̄ 删除驱动程序的

用DriverWorks开发PCI设备的WDM驱动程序

用DriverWorks开发PCI设备的WDM驱动程序

【 (X e一 B t R m ii (= ) i p fr> ye e a n ) =0 f s n g
p fr > e iae ; X e- T r n t0 m


/ 查传输 对象 中是否还有 要传输 的字节数 目 / 检
f/ , 如果所 有 的数 据传输 已完成 ,则 调用T r nt( e mia ) e 函数 ,终止 D 传输 ,释放适 配器 资源 MA
d )设 置D 传 输相关 的控制 寄存器 ,并 启动D A MA M 传输
v i odDMAD vc : trDMA( L G P d rs, L G NB ts e ie: at S U ON A d es U ON ye )
f, 面几条语 句设置 D 控 制寄存器 ,并启动 D 传 输 , 下 MA MA m IP r ag 0ot( o ot ne . dMWT ,) R u C0; / / 写传输 字节数 清零 ,MWT ( 控写传输 记数 寄存器 ) C主 m IP r a g0ot( T S , x < l) o ot ne . dI C R( l< 4) R u N 0 ; / 能写传输完 中断 ,I T S ( / 使 N C R 中断控 制状态 寄存器)
b )初始化该 D 传 输控 制对象 MA Iia 例程所做 的工作 就是创建 适配器 资源( 配器对象 、映射 寄存 器) nt t ie 适 ,初始化传输 记录 ,并调用 用户定义 的回调 函数启 动第一次 分割传输 。
s at =m t us

C r nT a se- I iaeI l ,rmDe ie o moyL n T ( D R a y) ur t rn fr > nt t( Md0 F o e i . vc T Me r,ik oOn ma e d ) ;

PCI网卡驱动程序分析

PCI网卡驱动程序分析

PCI网卡驱动程序分析驱动程序的架构通常包括以下几个模块:初始化模块、数据传输模块、中断处理模块和控制模块。

初始化模块负责识别和配置网卡,并进行必要的初始化操作。

数据传输模块负责处理数据的收发,包括数据的发送和接收。

中断处理模块用于处理网卡发出的中断信号,通知操作系统有数据可处理。

控制模块负责向网卡发送命令以及接收网卡的状态信息。

在操作系统启动时,PCI网卡驱动程序会加载到内核中,并通过操作系统提供的接口进行初始化。

驱动程序首先会进行设备识别,通过读取设备的PCI配置空间来获取设备的基本信息,如设备ID、厂商ID等。

然后驱动程序会检测设备的状态并进行必要的配置,如设置中断向量和启用设备。

初始化完成后,驱动程序会注册中断处理函数,以便在网卡有数据到达时能及时响应。

数据传输模块负责处理数据的收发。

在接收数据时,驱动程序会设置网卡的接收缓冲区,并等待中断信号。

当网卡接收到数据后,会触发一个中断信号,驱动程序会响应该中断并读取网卡的接收缓冲区来获取数据。

在发送数据时,驱动程序会设置网卡的发送缓冲区,并将数据写入该缓冲区。

然后驱动程序会发送一个命令给网卡,通知其开始发送数据。

发送完成后,网卡会触发一个中断信号,驱动程序会响应该中断并检查发送状态。

中断处理模块用于处理网卡发出的中断信号。

当网卡有数据到达或发送完成时,会触发一个中断信号。

驱动程序会通过中断控制器来识别该中断,并调用相应的中断处理函数。

中断处理函数会读取网卡的状态信息,如接收缓冲区中的数据长度、发送状态等,并进行相应的处理。

控制模块用于向网卡发送命令以及接收网卡的状态信息。

驱动程序会向网卡发送各种命令,如启动接收、停止接收、启动发送等。

同时,驱动程序也会定期检查网卡的状态信息,如发送缓冲区是否可用、接收缓冲区中是否有数据等。

在分析PCI网卡驱动程序时,还需要考虑一些其他的因素,如总线传输、内存管理、中断处理竞争等。

总线传输是指驱动程序通过PCI总线与网卡进行数据传输的过程,包括地址传输、数据传输等。

基于NI-VISA的PCI板卡驱动程序开发

基于NI-VISA的PCI板卡驱动程序开发

基于NI-VISA的PCI板卡驱动程序开发张艳华科0引言驱动程序是计算机与设备通讯的特殊程序,操作系统只有通过这个接口,才能控制硬件设备的工作并实时、准确的将信息传递给主机。

PCI总线是PC机广泛采用的外设总线架构,在构建基于PC的信息处理系统中,常常被选择为数据传输通道。

传统的PCI设备驱动程序开发平台有WDM、VC、Linux等,但在这种平台上进行驱动程序的开发,需要设计人员熟知操作系统的内核结构,且操作起来比较繁琐,对缺少驱动开发经验者显得比较困难。

本文介绍一种简单、快速的PCI接口驱动程序开发方法。

使用NI-VISA的Driver Wizard 向导可以方便的生成具有产生中断功能的驱动程序,在NI Labwindows/CVI环境下,可对中断事件进行检测和处理。

1基于NI-VISA的驱动程序1.1NI-VISA概述NI-VISA(Virtual Instrument Software Architecture,以下简称为"VISA")是美国国家仪器NI(National1nstrLlrnent)公司开发的一种用来与各种仪器总线进行通信的高级应用编程接口。

VISA总线I/0软件是一个综合软件包,它不受平台、总线和环境的限制,可用来对USB、GPIB、串口、VXI、PXI和以太网系统进行配置、编程和调试。

VISA是虚拟仪器系统I/O接口软件,基于自底向上结构模型的VISA创造了一个统一形式的I/O控制函数集,并且对于初学者来说这些函数集是简单易用的。

1.2基于VISA的驱动程序开发架构“驱动程序”通常是指安装于操作系统上,供应用程序调用以操作硬件设备的一组函数。

驱动程序提供面向应用程序的API接口函数,把应用程序对API函数的调用翻译成硬件可以理解的底层寄存器操作。

驱动程序封装了具体的硬件操作,软件设计者不需要了解具体的操作细节就可以开发基于硬件的应用程序。

基于VISA的驱动又称为“仪器驱动”,这是由于VISA广泛应用于虚拟仪器的开发。

超声相控阵系统数据传输的关键技术

超声相控阵系统数据传输的关键技术

超声相控阵系统数据传输的关键技术施成龙;师芳芳;张碧星【摘要】Ultrasonic phased array technology has a highsensitivity,resolution and signal to noise ratio,which makes it a hot research field of nondestructive testing.To improve the detection speed of ultrasonic phased array system,the key part of data transfer in ultrasonic phased array system is studied.The structure of self-developed ultrasonic phased array system is introduced.Three factors which include databus,hardware driver and data reading program that determine the data transfer rate of system are described.To develop the system,PCI bus is chosen to be the data bus,DriverStudio is used to develop the PCI bus driver,and multi-core technology is applied to improve the efficiency of the data reading program.Experimental results show that using PCI bus technology and multi-core programming technology to develop the data transfer module of the ultrasonic phased array system can increase the data transfer rate speed of the system.%超声相控阵检测技术有着较高的灵敏度、分辨率和信噪比,是目前无损检测领域的热点。

PCI 在WIN98NT 环境下驱动程序的开发

PCI 在WIN98NT 环境下驱动程序的开发

PCI在WIN98/NT环境下驱动程序的开发蔡 勇摘要: 本文简要介绍了编写PCI驱动程序的一般过程、Windows环境下驱动程序的种类和现在比较流行的几种PCI驱动程序的开发环境,并详细介绍了PCI在WIN98/NT环境下驱动程序的开发方法。

关键词:驱动程序 PCI VtoolsD DDK一.概述随着IT行业日新月异的飞速发展,PCI总线以其不可比拟的优势逐渐取代ISA总线成为占主导地位的总线类型,ISA总线逐渐会完成其历史使命而退出历史舞台。

在工业控制及军品测试领域中,市场上现有的PCI板卡类型还不能满足许多应用的要求。

例如ARINC-429总线MIL-1553B总线等的PCI板卡就要做硬件专门设计,而对应驱动程序的开发就成为使用这些板卡的关键之一。

本文简要介绍了编写PCI驱动程序的一般过程、Windows环境下驱动程序的种类和现在比较流行的几种PCI驱动程序的开发环境,并详细介绍了PCI在WIN98/NT环境下驱动程序的开发方法。

二.PCI驱动程序开发的一般过程从广义上来说,设备驱动程序就是控制硬件设备的一组函数。

PCI驱动程序的开发,就是取得PCI板卡所占用的各种资源(内存、端口、中断和DMA等),并提供给用户一条可以访问这些资源的途径。

对于所有的PCI板卡,基本上都可以用下面的方法来开发驱动程序。

2.1取得PCI板卡所占用的资源。

无论是ISA板卡还是PCI板卡,用户要使用它,就必须能访问它所占用的各种资源。

对于ISA板卡,它所占用的资源是定死的,可以直接访问;而PCI板卡是即插即用的,它占用的所有资源都是由系统分配的,要想访问这些资源,就必须先取得这些资源。

2.2建立起上层应用程序和底层驱动程序之间的映射关系。

因为在WIN98和NT等操作系统下,各种资源的访问对用户来讲是透明的,用户不能在上层应用程序里直接访问硬件资源,只能靠底层驱动程序来访问它。

因此用户要实现对板卡的控制,就必须在应用程序和底层驱动程序之间架起一座桥梁,来实现应用程序和驱动程序之间的联系。

核磁共振系统板卡驱动程序、软件安装及故障解决方法

核磁共振系统板卡驱动程序、软件安装及故障解决方法

上海纽迈电子科技有限公司核磁共振成像分析系统PCI板卡驱动程序安装方法说明:PCI板卡驱动程序在出厂时都已经安装好,如果在使用中系统出现严重故障,用GHOST一键恢复也不能使系统恢复正常工作,只能Windows XP系统重新安装时,可使用下列方法安装PCI板卡驱动程序。

一、安装PCI板卡前的准备工作先关机确认PCI板卡是否已经插好,再把WINDOWS XP系统安装好,再重启WINDOWS XP,安装PCI 板卡驱动程序。

二、安装PCI板卡的9050/9052驱动如果系统提示找到新硬件,如图一所示:图一选择“从列表或指定位置安装(高级)(S)”,然后点击“下一步”按钮,出现如图二所示,图二再点击图二中的“下一步”按钮,出现图三,把PCI板卡驱动光盘放入光驱中,在图三中点击”浏览”按钮,出现如图四所示图三在图四中。

点击查找范围框,选择光盘里的“Driver磁共振驱动\ PCIDrv \WIN2000_XP”文件夹目录,再点击“打开”按钮,出现如图五所示画面,再点击图五中的“确定”按钮,出现如图六所示画面,再点击图六中的“下一步”按钮,会出现图七所示画面,再点击图七中的“仍然继续”按钮,Windows会继续安装并出现图八所示画面,点击图八中的“完成”按钮,完成一个PCI板卡的驱动安装,按上述方法再重复安装两次,PCI板卡的一个驱动就安装好了。

这时打开设备管理器就发现在“其它设备”里多了三个“Custom (OEM) PCI 9050/9052 Board”项(如图九所示),这表示PCI板卡的9050/9052已经安装好了。

图四图五图六图七图八图九三、安装PCI板卡的IRQL驱动点击Windows的“开 ”,再点击 出打开“ 面板”(如图 所示),选择其中的“ 硬件”(如图 一所示), 点打开出现图 二画面,点击图 二的“下一步”按钮,出现图 三画面,如图 三,选择其中的“是, 已经 了 硬件”,图图 一图 二图 三再点击“下一步”按钮,出现图 四画面, 动 下 动 到 下面, 到“ 新的硬件设备” , 选中,再点击“下一步”按钮,出现图 五画面,选择图 五中的“安装 动从列表选择的硬件(高级)(M)”,再点击“下一步”按钮,出现图 六画面,再点击“下一步”按钮,出现图 七画面,点击“从磁盘安装”,出现图 八画面,再点击“浏览”按钮,出现图 九画面,再在查找范围中选择光盘中的“Driver磁共振驱动\IRQLDrv”文件夹目录,如图二 ,再点击“打开”按钮,出现图二 一画面,再点击“下一步”按钮,出现图二 二画面,再点击“下一步”按钮,安装程序并出现图二 三画面,再点击“完成”按钮,完成PCI板卡的IRQL驱动的安装。

PCIE开发流程

PCIE开发流程

PCIE开发流程前言:对于USB、PCIE设备这种挂接在总线上的设备而言,USB、PCI只是它们的”工作单位”,它们需要向”工作单位”注册(使用usb_driver,pci_driver),并接收”工作单位”的管理(被调入probe()、调出disconnect/remove()、放假suspend()/shutdown()、继续上班resume()等),但设备本身可能是一个工程师、一个前台或者一个经理,因此做好工程师,前台或者经理是其主题工作,这部分对应于字符设备驱动,tty设备驱动,网络设备驱动等。

第一节整体构成整个驱动程序的开发应该包括三个大的部分1.1驱动模块的加载与卸载xxx_init_module()注册pci_driver设备。

xxx_cleanup_module()注销pci_driver设备。

1.2pci_driver成员函数的初始化xxx_probe()完成PCI设备初始化,注册字符设备xxx_remove()完成PCI设备释放,注销字符设备1.3字符设备file_operations成员函数用于实现上层应用程序对下层驱动程序调用时的调用函数。

xxx_open()xxx_release()xxx_ioctl()xxx_read()xxx_write()第二节PCIE设备实现细节由于PCIE设备的驱动的开发都是按照一个统一规范的框架进行的。

因此以一个字符设备为例说明这个框架的实现机制。

在所有PCIE驱动开发的过程中2.1驱动程序的初始化和注销涉及的函数为module_init(xxx_init_module),并在init中完成的功能为注册PCIE设备,具体函数内容如下所示:注销涉及的函数为module_exit(xxx_cleanup_module)在exit中完成的功能为注销PCIE设备,具体函数内容如下所示:2.2PCIE设备的注册在模块的初始化过程中,首先是注册PCIE设备,使用函数为pci_register_driver(&xxx_pci_driver),输入变量指明了PCIE结构体,如下所示:#define XXX_MODULE_NAME "xxx_audio"static struct pci_driver xxx_pci_driver = {.name= XXX_MODULE_NAME,.id_table= xxx_pci_tbl,.probe= xxx_probe,.remove= __devexit_p(xxx_remove),#ifdef CONFIG_PM.suspend= xxx_pm_suspend,.resume= xxx_pm_resume,#endif /* CONFIG_PM */};结构体中name指明PCIE模块的名称,id_table指明了PCIE的设备驱动号也就是为哪个设备进行驱动等。

DriverWorks简明教程

DriverWorks简明教程

DriverW orks简明教程1.学会使用向导很多人不喜欢向导,可是一个从应用开发转做驱动开发的人可能更容易接受这种方式,但在今天我不打算使用过多的向导,而是手工写驱动代码,只是使用了DriverW orks的包装类,使用MFC可以反过来使我的SDK技术长进不少,那同样的使用DriverW orks我相信同样可以使我们的DDK技术得到锻炼.首先使用DDK Build Settings启动V isual C++ 6.01.1 点击DriverStudio工具栏上的Launch DriverWizard按钮,选择New Project中的"Start a New Driver Project"1.2 向导会自动选中DDK Source/makefile和V isual Studio 6,在Project Name里输入"hello"后点下一步1.3 project type页中选择"Kernel Mode Service"点下一步1.4 IRP Handlers页中把所有自动勾上的请求都去掉,因为我们要手工写DriverW orks代码以加深印象.点下一步1.5 在Additional页里把自动勾上的Generate SoftICE NMS file in custom build step去掉.点下一步1.6 预览工程,并点击完成:Project Summary For kruglinskiProject Name = helloProject Location = D:\W orkspace\helloProject Type = NT1.8 空的工程框架就会生成完毕.此时直接编译会出错,也许是DriverStudio的一个Bug,只要把sources中的:TARGETLIBS=$(DDK_LIB_PA TH)\ntstrsafe.lib$(DDK_LIB_PA TH)\csq.lib这一行去掉就可以编译通过了,让我们编试一下,一定感觉很不错吧!2.拨开云雾见日出2.1 现在我们要做的是清理掉所有会让我们眼花的东东(一大堆向导生成的代码),只留下编译环境,我喜欢在V isual Studio里直接编译的感觉,很讨厌总是看到那个黑黑的Build Console.切换到FileV iew初图,把除了makefile和sources文件以外的其它文件全部删除,然后我们只复制hello.dsp,sources和makefile三个文件到一个单独的文件夹helloworld里.选择File-Close W orkspace关闭刚向导出来的工程,再把copy出来的hello.dsp拖到V isual Studio 6中打开(这时会自动生成一个hello.dsw).2.2 现在要正式开工了,按Ctrl+N在Files页选择C++ Source File,在File栏里输入hello.cpp在hello.cpp里首先要#include "vdw.h" ,因为我们要用的DriverW orks包装类的头文件都由该文件包括.这里需要注意的是在#include "vdw.h"前应该加入一句#define VDW_MAIN因为DriverW orks的帮助文件里这样说(懒得译了,将就着看吧!!)Symbol VDW_MAIN must be #define'd in exactly one source module of the driver, generally the module that implements the driver class. If, as is true for most drivers, there is more than one source module, do not #define VDW_MAIN in any other modules. The definition must precede #include . The purpose of this symbol is to control the inclusion of certain source files in the DriverW orks library. These source files must be compiled in the context of the driver being built.2.3 我们定义一个驱动对象类,它派生自KDriver,必须提供一个纯虚函数DriverEntry的实现:class MyDriver:public KDriver{SAFE_DESTRUCTORS;public:virtual NTSTA TUS DriverEntry(PUNICODE_STRING RegistryPath);};DECLARE_DRIVER_CLASS(MyDriver,NULL)NTSTA TUS MyDriver::DriverEntry(IN PUNICODE_STRING RegistryPath){DbgPrint("Hello KMD world!");return STA TUS_SUCCESS;}这里还有一个DECLARE_DRIVER_CLASS(MyDriver,NULL)要注意,再copy一段帮助文档上的内容:One module of the driver must invoke macro DECLARE_DRIVER_CLASS. This macro actually inserts a small function that the framework calls during initialization. The function creates an instance of the driver class.现在已经可以编译成sys,用我的小工具Driver Logicl Tester可以测试一下效果,可以看到输出了一行"hello KMD W orld!",我想需要解释一下KDriver,KDriver是驱动对象,按照DriverW orks对象模型里的观念,一个驱动程序里至少要包括一个驱动对象,这个驱动对象可以包括一个或多个设备对象,Ring3的应用程序可以通过设备对象来于驱动程序交互.后面我会做简单的演示.3.打开潘多拉魔盒上面演示的东东其实本上没有多大实际的用处,当然可以在riverEntry里添加一个调用门让Ring3的应用程序有机会使用调用门进入Ring0.所以我们必须要做到可以控制驱动程序执行指定的代码完成指定的任务.3.1 设备对象与KDevice在DriverW orks里KDevice和KPnpDeivce做为设备对象类的抽像,因为这里想演示的是KMD而不是WDM,所以我在这里只使用KDevice,KPnpDeivce以后有空再说.在#define VDW_MAIN后#include "vdw.h"前加上以下几行:#define DRIVER_FUNCTION_DEVICE_CONTROL#define DRIVER_FUNCTION_CREA TE#define DRIVER_FUNCTION_CLOSE#define DRIVER_FUNCTION_CLEANUP当需要覆盖设备或是驱动对象基类的某个函数时,需要在include 之前定义这些宏.原因不要问,文档上要求这样做那就这样做咯.具体的可以查看DriverW orks源代码,这四个是设备对象要用到的,可以对应看下面的代码.现在我们实现一个设备对象的派生类MyDevice,它将负责与上层的驱动测试工具做交互.class MyDevice : public KDevice{public:SAFE_DESTRUCTORS;MyDevice();~MyDevice();DEVMEMBER_DISPA TCHERS;};DriverW orks帮助文档里说到如果没有SAFE_DESTRUCTORS这个宏,Unload例将工作的不太正常,所以不用问那么照做就是.而DEVMEMBER_DISPA TCHERS宏的功能是自动的定义所有的派遣函数,如果Create,Close,Cleanup...等.然后分别实现前面#define的那几个派遣函数:NTSTA TUS MyDevice::Create(KIrp I)DbgPrint(__FUNCTION__":IRP %p\n", I);rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS MyDevice::Close(KIrp I){DbgPrint(__FUNCTION__":IRP %p\n", I);rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS MyDevice::DeviceControl(KIrp I){DbgPrint(__FUNCTION__":IRP %p,CodeCode=%d\n", I,I.IoctlCode());rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS MyDevice::CleanUp(KIrp I)DbgPrint(__FUNCTION__":IRP %p\n", I);rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}3.2 构造一个设备对象在DriverEntry里创建这个设备对象,其实非常简单,只是调用一个new运算符函数.NTSTA TUS MyDriver::DriverEntry(PUNICODE_STRING RegistryPath){NTSTA TUS status = STATUS_SUCCESS;DbgPrint(__FUNCTION__"RegistryPath:%S\n",RegistryPath->Buff er);MyDevice* pDevice = new (L"HelloDevice",FILE_DEVICE_UNKNOWN,L"HelloDevice",0,DO_DIRECT_IO)MyDevice();if (pDevice == NULL){status = STA TUS_INSUFFICIENT_RESOURCES;}else{status = pDevice->ConstructorStatus();//读取设备对象构造后的状态if (!NT_SUCCESS(status)){delete pDevice;}elseDbgPrint(__FUNCTION__"Created HelloDevice!\n");}return status;}我想需要解释一下这个new运算符,它是KDevice的重载动算符,我使用的原型是:void* __cdecl operator new(size_t n,PCWSTR DeviceName,DEVICE_TYPE Type,PCWSTR LinkName=NULL,ULONG Characteristics=0,ULONG DeviceFlags=DO_BUFFERED_IO);这个new运算符函数的comment说到:// This is the form of new that allocates the storage for the class instance in// the system device object extension.在设备对象扩展里分配并存储类实例,我看了一下它的源代码在kfilter.cpp中,它会调用一个叫__construct的函数,而__construct函数会调用IoCreateDevice创建一个驱动设备对象(注意不是DriverW orks设备对象类),并分配一个大小为n(在这里是n=sizeof(MyDevice))的设备扩展用来存储这个设备对象类(包括它的数据成员,感觉确实是很方便啊!),并调用IoCreateSymbolLink在\DosDevice\创建一个符号链接供Ring3程序使用,我想LinkName使用一个GUID字符串更合适一些.呵呵!其实不需要把代码跟到这里看,只不过了解一些底下的东东也好,但我很赞成潘爱民老师所说的,做应用开发尽可能不要去读软件开发商提供的类库源代码.只看参考手册能够用的很熟练很巧就行了.所以我只看D.j.Kruglinski的Inside VC++而从不去看什么深入浅出MFC,我的MFC照样用的很好,也可以理解那些MFC底层如何实现,其实深入浅出MFC里的东西,Inside VC++里只用了几页纸就讲的非常清楚了,呵呵!话扯远了.也许每个人学习的思想和方法不一样.再搬出我的小工具,测试一下.可以看到我们写的几个函数都被调用到了,每按一下"IoControl"按钮,DeviceControl函数就会被调用.4.输入与输出4.1 简单的KMD与上层应用同步方法我想有了前面的基础,做输出输出已经不是什么难事,可以在DeviceIoControl里做,也可以在Read和Write派遣函数里做,不过我想通常的做法是,驱动创建一个同步事件,使用DriverW orks的KEvent对象,并使用这个成员函数原型进行初使化:VOID Initalize(KUstring& Name,EVENT_TYPE type);第一个参数可以填以\BaseNamedObjects\为前缀的事件对象名,后一个参数可以是SynchronizationEvents(同步事件)或是NotificationEvents(通知事件),然后Ring3的程序可以用CreateEvent打开这个对象,W aitForSingleObject做同步.当有数据时上层的程序会在第一时间得到通知.一般设备对象会添加几个容器成员,像前面分析的,它们会被会配并存储在设备扩展里,当然容器要使用的堆内存会是从PagedPool 或是NonPagedPool里分配出来的,一些常用的容器如KList,KLockableFifo,KInterlockedList...等等.这样,数据的排队和存储解决后,就是在派遣函数中处理它们了,或是从上层收到并存入容器,或是从容器里摘除并返回到上层.4.2 IO控制代码一般使用一个叫做CTL_CODE的宏来定义IO控制代码,在每个派遣函数有一个KIrp类型的参数,它也IRP请求包的包装类,KIrp::IoctlCode函数返回控制代码的引用,也就是说我们可以读也可以改写控制代码.通常在DeviceIoControl里根据不同的控制代码做不同的动作.类似于这样:NTSTA TUS MyDevice::DeviceControl(KIrp I){switch (I.IoctlCode()){case CTRL_SETUP_HOOK:.............break;case CTRL_REMOVE_HOOK:.............break;default:status = STA TUS_INV ALID_DEVICE_REQUEST;break;}...}而输入输出缓冲及大小分别由,KIrp::IoctlBuffer,KIrp::IoctlInputBufferSize和KIrp::IoctlOutputBufferSize来获得.这只是Buffered IO方式,还有Direct IO方式有空再说!完整的程序代码,我更喜欢看面向对象的代码结构,呵呵!//hello.cpp:#define VDW_MAIN#define DRIVER_FUNCTION_DEVICE_CONTROL#define DRIVER_FUNCTION_CREA TE#define DRIVER_FUNCTION_CLOSE#define DRIVER_FUNCTION_CLEANUP#define DRIVER_FUNCTION_UNLOAD#include "vdw.h"class MyDriver : public KDriver{SAFE_DESTRUCTORSpublic:virtual NTSTA TUS DriverEntry(PUNICODE_STRING RegistryPath);virtual VOID Unload(VOID);};DECLARE_DRIVER_CLASS(MyDriver,NULL)class MyDevice : public KDevice{public:SAFE_DESTRUCTORS;MyDevice();~MyDevice();DEVMEMBER_DISPA TCHERS};MyDevice::~MyDevice(){}MyDevice::MyDevice() :KDevice(){if (!NT_SUCCESS(m_ConstructorStatus)){DbgPrint(__FUNCTION__": Failed to create device MyDevice"); return;}}NTSTA TUS MyDevice::Create(KIrp I){DbgPrint(__FUNCTION__":IRP %p\n", I);rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;NTSTA TUS MyDevice::Close(KIrp I){DbgPrint(__FUNCTION__":IRP %p\n", I);rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS MyDevice::DeviceControl(KIrp I){DbgPrint(__FUNCTION__":IRP %p,CodeCode=%d\n", I,I.IoctlCode());rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS MyDevice::CleanUp(KIrp I){DbgPrint(__FUNCTION__":IRP %p\n", I);rmation() = 0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;VOID MyDriver::Unload(VOID){KDriver::Unload();}NTSTA TUS MyDriver::DriverEntry(PUNICODE_STRING RegistryPath){NTSTA TUS status = STATUS_SUCCESS;DbgPrint(__FUNCTION__"RegistryPath:%S\n",RegistryPath->Buff er);MyDevice* pDevice = new (L"HelloDevice",FILE_DEVICE_UNKNOWN,L"HelloDevice",0,DO_DIRECT_IO)MyDevice();if (pDevice == NULL){status = STA TUS_INSUFFICIENT_RESOURCES;else{status = pDevice->ConstructorStatus();if (!NT_SUCCESS(status)){delete pDevice;}elseDbgPrint(__FUNCTION__"Created HelloDevice!\n");}return status;}到现在为止,如果你是已经可以很熟练的用DDK写驱动肯定觉得这一切会有点繁琐,但这仅仅是开始,驱动的工程越大,代码量越多时使用DriverW orks表现出的效率会越明显.可以类比像MFC 与SDK玩玩DriverW orks(二)-读写数据这两天怎么老想玩DriverW orks今天抽了一个小时写个小驱动练习一下KIrp和KMemory配合访问三种IO方式中的数据.KIrp是对IRP请求对象的包装,它有很多成员函数用于操作IRP结构.1.Buffered IO:在Buffered IO方式中IO管理器会分配一块堆内存然后把用户态缓冲区数据copy进来再传给驱动程序,而输出时IO管理器会把堆内存中的数据copy回用户态缓冲区.我们使用下面这样的代码来得到输入/输出缓冲区和大小KIrp I;....ULONG inputSize = I.IoctlInputBufferSize();ULONG outputSize = I.IoctlOutputBufferSize();PVOID inputBuffer = I.IoctlBuffer();PVOID outputBuffer = I.IoctlBuffer();一目了然吧!我想要介绍一下这几个函数,但你实际上可以跳过下面的一小段因为用DriverW orks根本用不着知道这些细节.IoctlBuffer,IoctlInputBufferSize,IoctlOutputBufferSize函数实现非常简单:inline PVOID& KIrp::IoctlBuffer(void){return m_Irp->AssociatedIrp.SystemBuffer;}inline ULONG& KIrp::IoctlOutputBufferSize(EStackLocation s) {V alidateStackLocation(s);if (s == CURRENT)return IoGetCurrentIrpStackLocation(m_Irp)->Parameters.DeviceIoControl.OutputBufferLength;elsereturn IoGetNextIrpStackLocation(m_Irp)->Parameters.DeviceIoControl.OutputBufferLength;}inline ULONG& KIrp::IoctlInputBufferSize(EStackLocation s) {V alidateStackLocation(s);if (s == CURRENT)return IoGetCurrentIrpStackLocation(m_Irp)->Parameters.DeviceIoControl.InputBufferLength;elsereturn IoGetNextIrpStackLocation(m_Irp)->Parameters.DeviceIoControl.InputBufferLength;}在IoctlOutputBufferSize和IoctlInputBufferSize中S有一个默认参数CURRENT,上面的代码就是这样调用它们的.可以看到其实是对IO_STACK_LOCATION结构直接的操作.2.Direct IO:Direct IO方式中IO管理器分将用户态缓冲区映射到核心态(地址不一样,但其实是一块内存),并锁定内存不要分页机制将内存交换到外存中.然后IO管理器将缓冲区在核心态的的地址传给驱动程序.Direct IO的分成METHOD_IN_DIRECT和METHOD_OUT_DIRECT2.1 在METHOD_IN_DIRECT中我们使用这样的代码来访问缓冲区及大小KIrp I;....KMemory Mem(I.Mdl());PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace(); ULONG writeSize = I.WriteSize();ULONG bytesSent = 0;2.2 在METHOD_OUT_DIRECT中要像这样来访问缓冲区及大小KIrp I;....KMemory Mem(I.Mdl());PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace(); ULONG readSize = I.ReadSize();ULONG bytesRead = 0;I.Mdl函数是这样实现的:inline PMDL& KIrp::Mdl(void){return m_Irp->MdlAddress;}它直接返回IRP结构的MdlAddress字段,而MapToSystemSpace 的实现代码是这样的:inline PVOID KMemory::MapToSystemSpace(void){return GetSystemAddressForMdl(m_pMdl);}它调用下面这个函数,这里我不太明白为什么不直接调用MmGetSystemAddressForMdlinline PVOID GetSystemAddressForMdl(PMDL pMdl){CSHORT canFail; // original fail flag in MDLif(!(pMdl->MdlFlags &(MDL_MAPPED_TO_SYSTEM_V A | MDL_SOURCE_IS_NONPAGED_POOL))) {// get the current fail flagcanFail = (CSHORT)(pMdl->MdlFlags & MDL_MAPPING_CAN_FAIL);// set 'mapping can fail' so we don't bugcheck// if MmMapLockedPages failspMdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;// try to map the bufferpMdl->MappedSystemV a =(PVOID)(((ULONG_PTR)MmMapLockedPages(pMdl, KernelMode)) |MmGetMdlByteOffset(pMdl));// set the original flag back in the MDLif(!canFail) {pMdl->MdlFlags &= ~MDL_MAPPING_CAN_FAIL;}}return pMdl->MappedSystemV a;}3 Neither IO:在Neither IO,IO管理器直接把用户态的缓冲区地址和大小传给驱动,不做任何处理.这是很危险的,通常情况下,我们需要写一些小的助手驱动以进入Ring0或是调用一些底层功能,如果可以肯定驱动的派遣函是运行在被动级并且在我们自己指定程序的进程上下文里,那么用用这种方式也无所谓.除此以外尽可能不用这样的IO方式.通常需要使用这样的代码来访问缓冲区和大小: KIrp I;....ULONG inputSize = I.IoctlInputBufferSize();ULONG outputSize = I.IoctlOutputBufferSize();PVOID inputBuffer = I.IoctlType3InputBuffer();PVOID outputBuffer = erBuffer();IoctlType3InputBuffer和UserBuffer的实现代码:inline PVOID& KIrp::IoctlType3InputBuffer(EStackLocation s) {V alidateStackLocation(s);if (s == CURRENT)return IoGetCurrentIrpStackLocation(m_Irp)->Parameters.DeviceIoControl.Type3InputBuffer;elsereturn IoGetNextIrpStackLocation(m_Irp)->Parameters.DeviceIoControl.Type3InputBuffer;}inline PVOID& KIrp::UserBuffer(void){return m_Irp->UserBuffer;}4. 现在可以总结一下,根据这些我们可以学到在DDK层面上应该怎么操作这些IO方式中的缓冲区:4.1 在驱动的派遣函数中可以使用IoGetCurrentIrpStackLocation 得到IO_STACK_LOCATION可以根据它的Control字段确定是什么派遣函数(因为可以将多个派遣函数地址指向一个派遣函数来处理多个请求).在Control等于IRP_MJ_DEVICE_CONTROL 时来要根据DeviceIoControl的子字段IoControlCode来确定是什么控制代码.4.2 对于Buffered IO和Neither IO可以使用它的DeviceIoControl 字段和三个子字段来访问缓冲区和大小参数:typedef struct _IO_STACK_LOCA TION {....union {...struct {ULONG OutputBufferLength;ULONG InputBufferLength;ULONG IoControlCode;PVOID Type3InputBuffer;} DeviceIoControl;...}....} IO_STACK_LOCA TION, *PIO_STACK_LOCA TION;4.3 对于Direct IO则要使用MmGetSystemAddressForMdl来将IRP结构的MdlAddress(内存描述表)字段映射到内核地址空间并锁定,得到一个内核空间地址才能进一步操作.Direct IO方式中的输入输出大小参数由IO_STACK_LOCA TION的Read.Length和Write.Length指示typedef struct _IO_STACK_LOCA TION {....union {...struct {ULONG Length;ULONG Key;LARGE_INTEGER ByteOffset;} Read;struct {ULONG Length;ULONG Key;LARGE_INTEGER ByteOffset;} Write;...}....} IO_STACK_LOCA TION, *PIO_STACK_LOCA TION;说不看库源代码的又忍不住开始分析,呵呵!其实可以把DriverW orks的对象类搞清楚怎么用就可以了.如果是想顺便把自己的DDK开发能力也提高一下的话,库的源代码也可以参考.有了昨天的DriverW orks基本介绍,我想下面的代码应该不是很难懂吧!//Interface.h#ifndef __INTERFACE_H__#define __INTERFACE_H__#define DEVICE_NAME L"IoDemoDevice"#define FILE_DEVICE_IODEMO 0x8000#define IOCTL_DO_BUFFERED_IO \CTL_CODE(FILE_DEVICE_IODEMO,0x800,METHOD_BUFFE RED,FILE_ANY_ACCESS)#define IOCTL_DO_DIRECT_IN \CTL_CODE(FILE_DEVICE_IODEMO,0x801,METHOD_IN_DIRECT,FILE_ANY_ACCESS)#define IOCTL_DO_DIRECT_OUT \CTL_CODE(FILE_DEVICE_IODEMO,0x802,METHOD_OUT_DI RECT,FILE_ANY_ACCESS)#define IOCTL_DO_NEITHER_IO \CTL_CODE(FILE_DEVICE_IODEMO,0x803,METHOD_NEITHE R,FILE_ANY_ACCESS)#endif//IODemo.cpp#define VDW_MAIN#define DRIVER_FUNCTION_UNLOAD#define DRIVER_FUNCTION_CREA TE#define DRIVER_FUNCTION_CLOSE#define DRIVER_FUNCTION_CLEANUP#define DRIVER_FUNCTION_DEVICE_CONTROL#include "vdw.h"#include "Interface.h"class IoDemoDriver:public KDriver{SAFE_DESTRUCTORS;public:virtual NTSTA TUS DriverEntry(IN PUNICODE_STRING RegistryPath);virtual VOID Unload();};DECLARE_DRIVER_CLASS(IoDemoDriver,NULL)class IoDemoDevice:public KDevice{SAFE_DESTRUCTORS;public:IoDemoDevice();DEVMEMBER_DISPA TCHERS;};IoDemoDevice::IoDemoDevice():KDevice(){if (!NT_SUCCESS(m_ConstructorStatus)){DbgPrint(__FUNCTION__": Failed to create device MyDevice"); return;}}NTSTA TUS IoDemoDevice::Create(KIrp I){DbgPrint(__FUNCTION__":IRP 0x%08X\n",I); rmation()=0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS IoDemoDevice::Close(KIrp I){DbgPrint(__FUNCTION__":IRP 0x%08X\n",I); rmation()=0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS IoDemoDevice::CleanUp(KIrp I) {DbgPrint(__FUNCTION__":IRP 0x%08X\n",I); rmation()=0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS IoDemoDevice::DeviceControl(KIrp I) {DbgPrint(__FUNCTION__":IRP 0x%08X\n",I);switch(I.IoctlCode()){case IOCTL_DO_BUFFERED_IO:{DbgPrint(__FUNCTION__":IOCTL_DO_BUFFERED_IO\n",I); ULONG inputSize = I.IoctlInputBufferSize();ULONG outputSize = I.IoctlOutputBufferSize();PVOID inputBuffer = I.IoctlBuffer();PVOID outputBuffer = I.IoctlBuffer();//显示出传进来的字符串if(inputSize)DbgPrint("inputBuffer:%s",(char*)inputBuffer);//返回一个字符串char chDoBufferedIO[]="DO_BUFFERED_IO";strncpy((char*)outputBuffer,chDoBufferedIO,outputSize);rmation()=strlen(chDoBufferedIO);}break;case IOCTL_DO_DIRECT_IN:{DbgPrint(__FUNCTION__":IOCTL_DO_DIRECT_IN\n",I);KMemory Mem(I.Mdl());PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace(); ULONG writeSize = I.WriteSize();ULONG bytesSent = 0;if(writeSize)DbgPrint("pBuffer:%s",(char*)pBuffer);rmation()=0;}break;case IOCTL_DO_DIRECT_OUT:{DbgPrint(__FUNCTION__":IOCTL_DO_DIRECT_OUT\n",I); KMemory Mem(I.Mdl());PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace(); ULONG readSize = I.ReadSize();ULONG bytesRead = 0;if(readSize){char chDirectOut[]="DO_DIRECT_OUT";strncpy((char*)pBuffer,chDirectOut,readSize);rmation()=strlen(chDirectOut);}}break;case IOCTL_DO_NEITHER_IO:{DbgPrint(__FUNCTION__":IOCTL_DO_NEITHER_IO\n",I); ULONG inputSize = I.IoctlInputBufferSize();ULONG outputSize = I.IoctlOutputBufferSize();PVOID inputBuffer = I.IoctlType3InputBuffer();PVOID outputBuffer = erBuffer();//显示出传进来的字符串if(inputSize)DbgPrint("inputBuffer:%s",(char*)inputBuffer);//返回一个字符串char chDoNeitherIo[]="DO_NEITHER_IO";strncpy((char*)outputBuffer,chDoNeitherIo,outputSize);rmation()=strlen(chDoNeitherIo);}break;default:rmation()=0;plete(STA TUS_INV ALID_DEVICE_REQUEST);return STA TUS_INV ALID_DEVICE_REQUEST;}plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS IoDemoDriver::DriverEntry(IN PUNICODE_STRING RegistryPath){NTSTA TUS status = STATUS_SUCCESS;DbgPrint(__FUNCTION__":RegistryPath:%S\n",RegistryPath->Buf fer);IoDemoDevice* pDevice = new (DEVICE_NAME,FILE_DEVICE_UNKNOWN,DEVICE_NAME,0,DO_DIRECT_IO)IoDemoDevice();if (pDevice == NULL){status = STA TUS_INSUFFICIENT_RESOURCES;}else{status = pDevice->ConstructorStatus();if (!NT_SUCCESS(status)){delete pDevice;}elseDbgPrint(__FUNCTION__":Created IoDemoDevice!\n"); }return status;}VOID IoDemoDriver::Unload(){DbgPrint(__FUNCTION__);KDriver::Unload();}最后可以用我的小工具测试一下,Load驱动后可以点Content 按钮编辑数据包,也可以查看驱动返回的数据,显示方式是十六进制,注意根据IO控制代码的定义选择不同的Method,DeviceId 和ControlCode组合方式.个人感觉这个小工具还是比较好用的,呵呵!玩玩DriverW orks(三)-串行化IO请求周末实在不太想写我的数据库程序,又花了一个小时练习了一下DriverW orks里的排队IO请求模型,其实这和DDK中的模型基本上是一样的,因为参考了Programming the Microsoft Windows Driver Model里的一些代码,并且少看了DriverW orks关于排队IO的一句话,我还得到了一个BSOD,不过这个BSOD让我注意到了帮助文档上我没有注意到的地方,呵呵!废话不多说,来一个段代码!#define VDW_MAIN#define DRIVER_FUNCTION_UNLOAD#define DRIVER_FUNCTION_CREA TE#define DRIVER_FUNCTION_CLEANUP#define DRIVER_FUNCTION_CLOSE#define DRIVER_FUNCTION_READ#define DRIVER_FUNCTION_WRITE#define DRIVER_FUNCTION_STARTIO#define DRIVER_FUNCTION_DEVICE_CONTROL#include "vdw.h"//Begin Device Code/////////////////////////////////////////////////////// class CQueueDevice:public KDevice{SAFE_DESTRUCTORS;public:CQueueDevice();NTSTA TUS ComplateIrp(KIrp I);DEVMEMBER_DISPA TCHERS;DEVMEMBER_CANCELIRP(CQueueDevice,CancelIo);NTSTA TUS SerialRead(KIrp I);NTSTA TUS SerialWrite(KIrp I);NTSTA TUS SerialIoControl(KIrp I);};CQueueDevice::CQueueDevice():KDevice(L"CQueueDevice",FILE _DEVICE_UNKNOWN,L"CQueueDevice",0,DO_DIRECT_IO) {if(!NT_SUCCESS(ConstructorStatus())){DbgPrint(__FUNCTION__":Failed to Create Device\n");}}NTSTA TUS CQueueDevice::ComplateIrp(KIrp I){rmation()=0;plete(STA TUS_SUCCESS);return STA TUS_SUCCESS;}NTSTA TUS CQueueDevice::Create(KIrp I) {DbgPrint(__FUNCTION__"\n");return ComplateIrp(I);}NTSTA TUS CQueueDevice::CleanUp(KIrp I) {DbgPrint(__FUNCTION__"\n");return ComplateIrp(I);}NTSTA TUS CQueueDevice::Close(KIrp I) {DbgPrint(__FUNCTION__"\n");return ComplateIrp(I);NTSTA TUS CQueueDevice::DeviceControl(KIrp I) {DbgPrint(__FUNCTION__"\n");//排队并设置取消例程return QueueIrp(I,LinkTo(CancelIo));}NTSTA TUS CQueueDevice::Read(KIrp I){DbgPrint(__FUNCTION__"\n");//排队并设置取消例程return QueueIrp(I,LinkTo(CancelIo));}NTSTA TUS CQueueDevice::Write(KIrp I){DbgPrint(__FUNCTION__"\n");。

基于WinDriver的多路串行设备驱动开发

基于WinDriver的多路串行设备驱动开发

5510.3969/j.issn.1000-0755.2014.05.0140 引言XR17D158是在工业控制计算机中被广泛使用的一种PCI 转8路UART 接口芯片。

本文首先介绍Window 操作系统驱动程序和开发工具WinDriver 软件,并通过该软件完成XR17D158在Windows 系统下驱动程序的开发。

并以此为基础,提出了一种利用WinDriver 工具开发PCI 总线设备驱动程序的软件架构。

1 Windows 操作系统驱动开发Windows 操作系统以其友好的用户图形界面和强大的功能在工业控制计算机领域广泛使用。

但是Windows 对系统底层操作进行了屏蔽,限制应用程序直接访问硬件资源,应用程序需要调用设备的驱动程序访问硬件资源,而开发Windows 环境下的驱动程序,需要对操作系统内核的运行机制有深入的了解。

美国Jungo 公司的WinDriver 驱动程序工具包使程序设计人员不需要掌握Windows 操作系统内核的相关内容,只需要调用WinDriver 提供的接口函数就可以直接访问系统硬件资源,减轻了设计人员的开发难度。

WinDriver 同时支持PCI/CardBus/ISA/ISA PnP/EISA/CompactPCI 和USB 等多种总线结构。

基于WinDriver的多路串行设备驱动开发冯 毅(中航工业第631研究所,陕西 西安)摘 要:工业控制计算机中广泛使用串行接口UART 与外围设备进行通信,同时,Windows 操作系统以其友好的UI 界面被广泛采用。

文中阐述了UART 设备的工作原理,并利用Jungo 公司的WinDriver 软件实现了Windows 操作系统下一种PCI 转多路UART 设备的驱动开发。

关键词:WinDriver ;PCI 转UART ;驱动程序Development of Multi-channels UART Device Driver Based on WinDriverFeng Yi(Aeronautics Computing Technique Research Institute, A VIC, Xi'an, Shaanxi)Abstract: Universal Asynchronous Receiver and Transmitter (UART) device is widely used to carry out communications with peripheral device applied in industry control computers. Meanwhile, Windows operating system is widely used because of its friendly Use Interface (UI). This article introduces the working principle of UART device, and uses device, WinDriver software from Jungo to implement the driver development of a device which converts from PCI to UART..Key words: WinDriver; PCI to UART Device; driver programWinDriver 驱动程序的体系结构如图1所示。

Linux下PCI同步时钟卡的驱动程序设计

Linux下PCI同步时钟卡的驱动程序设计

Linux下PCI同步时钟卡的驱动程序设计陈梦桐;魏丰;杨兵见【摘要】In order to solve the faults in the power system recorder problem and can provide high accuracy synchronization to the whole electric power system standard to unify the time of whole system.For analysis when fault system fault location provide a strong basis put forward the design of the GPS synchronization clock.The clock card can receive the GPS or BeiDou satellite time information provided.The host computer interaction using PCI bus protocol and the data acquisition card clock.Peak voltage will be generated when the fault occurs in the power system as an interrupt signal when the interrupt signal arrives at read time information synchronization clock card in order to determine the fault location in Linux.The implementation details of the development and character of the device under Linux interrupt mechanism.Finally,under the Linux PCI driver software,through experiments in the interrupt signal arrival time information,the device can send or read the GPS or BeiDou satellite accurately and after multiple tests found no interruption loss.It proves the correctness and reliability of the driver.%为了解决在电力系统中存在的故障录波问题;能够向整个电力系统提供高精度的同步时标,统一整个系统的时间,为分析当系统发生故障后的故障发生地点提供有力的依据;为此设计了PCI同步时钟卡,该时钟卡可以接收GPS或者北斗卫星提供的时间信息;上位机采用PCI总线协议与时钟卡获取的数据进行交互;将电力系统发生行波故障时产生的峰值电压作为中断信号,在Linux下当中断信号到来时就读取同步时钟卡的时间信息以此判断故障发生的位置;为此详细介绍了Linux下字符设备开发与中断机制的实现;最后在Linux下编写PCI设备驱动程序,通过实验验证了在中断信号到来时,该设备能够准确的读取GPS或者北斗卫星发出的时间信息并且经过多次测试未发现中断丢失的情况,证明该驱动程序的正确性和可靠性.【期刊名称】《计算机测量与控制》【年(卷),期】2018(026)001【总页数】4页(P145-148)【关键词】Linux;字符驱动程序;PCI同步时钟卡;中断【作者】陈梦桐;魏丰;杨兵见【作者单位】华中科技大学自动化学院,武汉430074;华中科技大学自动化学院,武汉430074;华中科技大学自动化学院,武汉430074【正文语种】中文【中图分类】TP2120 引言随着社会生产力的发展,社会、科技等领域传递的信息量越来越大。

基于WDM模型PCI总线驱动的设计及实现

基于WDM模型PCI总线驱动的设计及实现

基于WDM模型PCI总线驱动的设计及实现胡辉;詹玉广【摘要】介绍了在Windows XP下WDM驱动程序的开发模型,分析了DriverStudio开发工具的特点,重点讨论了WDM 设备驱动程序设计中的重要问题以及利用它开发设备驱动程序的方法、步骤和注意事项,实现了对可编程的扩展I/O芯片8155的读写以及中断处理.【期刊名称】《河南工程学院学报(自然科学版)》【年(卷),期】2009(021)004【总页数】4页(P40-43)【关键词】PCI总线;设备驱动程序;WDM;PCI9052【作者】胡辉;詹玉广【作者单位】华东交通大学,信息工程学院,江西,南昌,330013;华东交通大学,信息工程学院,江西,南昌,330013【正文语种】中文【中图分类】TP273PCI (Peripheral Component Interconnect) 总线是为满足外设间以及外设与主机间高速数据传输而提出的一种高性能局部总线[1].主要在数字图形、图像和语音处理以及高速实时数据采集与处理等对数据传输率要求较高的场合使用.PCI总线有32位和64位两种,目前常用的是32位PCI总线,其最大数据传输率为133MB/s,远远高于ISA总线,支持即插即用(PnP)和中断共享,与CPU及时钟频率无关,是ISA总线的替代品,成为各种计算机最普遍使用的外设总线.在Windows 2000/XP环境中,不支持用户层应用程序对系统硬件资源的直接访问.因此,提出了设备驱动程序的概念,驱动程序是应用程序和硬件设备之间的桥梁,应用程序与驱动程序之间有明确的接口,应用程序通过与驱动程序交换信息,达到控制外设的目的.为了实现对PCI设备的操作,需开发相应的PCI设备驱动程序.WDM(Windows Driver Model)驱动模型为当前主流操作系统Windows 2000/XP下的设备驱动程序提供了一个参考框架模型,它规定了标准化的驱动模块,其主要目标是为了实现能够跨平台使用、更安全、更灵活、编制更简单的Windows设备驱动程序.本文将结合WDM驱动程序开发工具DriverStudio,分析Windows XP下PCI设备驱动程序的开发过程.1 WDM驱动程序模型与以往的Windows 95/98操作系统不同,Windows 2000/XP操作系统包括许多功能相互独立的内核模式组件,图1是从内核驱动程序设计者的角度看到的Windows 2000/XP操作系统结构,它重点突出了驱动程序开发者所关心的特征[2].图1 Windows 2000/XP操作系统Fig.1 Windows 2000/XP operation system 当用户模式应用程序需要和硬件设备通信时,它就调用用户模式下的Win32子系统组件的API函数,Win32子系统模块则通过调用平台相关的系统服务接口实现该API,平台相关的系统服务将调用内核模式中的服务例程,而服务例程就是WDM驱动程序的一部分,为应用程序请求提供服务,并以某种方式与硬件设备进行交互.因此,用户模式的应用程序要想操作系统底层的硬件设备,必须借助驱动程序.当应用程序通过API函数向系统发出I/O请求时,I/O管理器为每一个用户请求打包成一个IRP(I/O Request Pack),并将其发送至驱动程序,通常IRP首先被送到最上层驱动程序,然后逐层地被送到下面的驱动程序,不同位置的驱动程序负责不同的工作,驱动程序处理完后,将会返回相应的处理结果信息.WDM驱动程序模型支持即插即用、电源管理和Windows管理诊断(WMI)控件技术.在WDM驱动程序模型中,每个硬件设备至少有两个驱动程序,其中一个为功能驱动程序,就是通常所说的硬件设备驱动程序.它了解使硬件工作的所有细节,负责初始化I/O操作,处理I/O操作完成时所带来的中断事件,为用户提供一种设备适合的控制方式.另一个为总线驱动程序,它负责管理硬件与计算机的连接.例如,本文中的PCI总线驱动程序就会检测插入到PCI槽上的设备并确定设备的资源使用情况,还能控制设备所在PCI槽的电流开关.WDM驱动程序采用分层的结构模型,如图2所示.WDM引入了物理设备对象PDO (Physical Device Object)与功能设备对象FDO(Functional Device Object)来描述硬件,一个PDO对应一个真实的硬件.一个硬件只允许有一个PDO,却可以拥有多个FDO,在驱动程序中直接操作的不是硬件而是相应的PDO和FDO.如图2所示,在有些驱动程序中还有位于设备驱动程序和总线驱动程序之间的过滤器驱动程序,用于监视和修改IRP流.在对硬件访问的过程中,设备驱动程序只需与下层的总线驱动程序打交道,具体控制硬件的工作则交给总线驱动程序去完成.在PCI设备的WDM驱动程序开发中,一般是编写功能驱动程序,总线驱动程序则由操作系统实现.图2 WDM设备对象和驱动程序的层次结构Fig.2 The hierarchical structure of WDM device object and driver2 WDM驱动程序开发工具的选择本文要进行的是Windows XP下PCI设备驱动程序的开发及设计,即WDM驱动程序的设计,对于Windows XP下WDM驱动的开发通常有以下三种开发平台:Windows DDK、WinDriver和DriverStudio.Windows XP DDK(Device Driver Kit)是Miscrosoft公司提供的Windows XP 下KMD (Kernel Mode Driver)和WDM驱动程序的开发工具,由于DDK基于汇编语言的编程方式和内核模式的调用,所以,采用DDK开发需要对操作系统和驱动程序的结构有很好地理解和把握,开发难度相对较大.WinDriver提供了可与操作系统核心层交互的内核Windrvr.sys,驱动程序使用WinDriver提供的函数库来与内核建立连接,进而实现与Windows底层的通信.WinDriver只能开发硬件相关的驱动,并且用其开发出的驱动程序效率和工作频率都不是很高.因此,主要用来作为硬件开发者快速测试新硬件的工具. DriverStudio是NuMega公司为简化Windows设备驱动程序和应用程序的开发而推出的一套开发、编译和调试的软件工具包,主要包括VToolsD、SoftICE和DriverWorks等.其中,DriverWorks以面向对象的方式,将WDM和NT下的驱动程序编写所需的与内核访问及对硬件的访问封装成类,加上设计的驱动程序代码生成向导Driver Wizard,它能够快速自动生成WDM驱动程序框架,简化了驱动程序开发的难度,减少了工作量.同时,DriverWorks可嵌入到VC++中,方便了开发.因此,我们选择DriverStudio做为我们的开发工具,本文以下部分将给出用Visual C++6.0和DriverStudio 3.1开发PCI设备WDM驱动程序的过程和注意事项.3 系统硬件结构我们开发了基于PCI9052的PCI开发板,如图3所示,该PCI开发板主要由PCI9052、EEPROM和8155以及预留的扩展总线接口构成.其中,PCI9052为PLX公司生产的支持PCI2.1协议的目标从模式I/O适配器[3];EEPROM为PCI9052的配置芯片,用于存放PCI9052的全部配置信息,这些配置信息规定了局部端到PCI总线的映射方式以及局部端的工作特性,在PCI9052加电或复位时加载到PCI9052的配置寄存器中;8155采用插卡式设计,它内部包括1个256字节8位的RAM、3个并行I/O口以及1个14位的定时/计数器.因此,可以用来作为开发板硬件调试和驱动程序开发的测试端.基于此平台可以开发出实现局部端I/O口和存储器的访问,以及定时中断等功能的驱动程序和应用程序.下面我们将详细介绍用DriverStudio 3.1开发的PCI开发板的驱动程序和应用程序编写的关键部分.图3 PCI 开发板系统结构框图Fig.3 The system diagram of PCI development board4 驱动程序和应用程序的编写4.1 PCI配置空间的访问Driverworks的KpciConfiguration类封装了访问PCI设备配置空间的所有操作,驱动程序通过该类访问PCI设备的配置空间,并可以对配置信息进行修改.在我们的设计中,主要是对PCI配置寄存器的内容进行更改,从而设定选择8155的RAM还是并行I/O口,以及设置中断操作.首先初始化这个类的实例:KPciConfiguration PciConfig(m_Lower.TopOfStack());/*m_Lower是KpnpLowerDeviee类的对象,提供访问PDO的模型.Lower.TopOfStack()返回当前设备堆栈顶部的设备对象.*/然后在驱动程序中通过m_MemoryRange0.inb()和m_MemoryRange0.outb()访问PCI配置寄存器的相应单元,从而设置局部端为8155的RAM空间还是I/O 口,以及设置中断操作.4.2 内存和I/O映射空间的访问DriverStudio中KMemoryRange和KIoRange类分别实现了对内存映射空间和I/O映射空间的访问.这两个类除了其中的构造函数有不同之处外,其他的成员函数完全相同.以内存映射空间的访问为例,对PCI设备首先需要在函数OnStartDevice中取得内存资源,然后初始化.如下:status = m_MemoryRange0.Initialize(pResListTranslated, //转换后的资源列表指针pResListRaw, //原始的资源列表指针PciConfig.BaseAddressIndexToOrdinal(0)//0代表分配的存储器资源在PCI基地址的序数);在处理资源的代码中必须进行运行错误处理,否则就会在驱动程序的运行中,引起系统崩溃.在其他例程中,就可以调用类KMemoryRange的成员函数inX/outX 对PCI设备内存映射空间的读/写访问,而对I/O映射空间的操作类似.4.3 中断处理DriverStudio中KInterrupt类实现了硬件中断的处理,其成员函数包括中断的初始化以及将一个中断服务例程连接到一个中断和解除其连接等.在OnStartDevice 函数中,调用KInterrupt的成员函数InitializeAndConnect初始化中断变量和调用宏LinkTo连接中断例程.status =m_Irq.InitializeAndConnect(pResListTranslated, //转换后的资源列表指针LinkTo(Isr_Irq), //连接中断服务例程this );在初始化和连接中断之前,最好将PCI设备的中断源进行屏蔽,PCI设备一般会有中断管理寄存器,屏蔽其中断许可位.当中断连接成功后,再将中断位打开.并且,一定要加运行错误处理,防止驱动程序将系统崩溃.在中断服务例程中,首先必须根据PCI设备的中断管理寄存器的内容来判断该中断是否是自己的设备发出的.若不是,返回FALSE;若是,进行必要的处理,请求一个DPC,然后返回TRUE.4.4 驱动程序与应用程序之间的通信在Windows中,应用程序与驱动程序的通信过程是:用CreateFile打开设备,有GUID接口方式和符号链接名方式;然后用DeviceIoControl和驱动通信,包括从驱动读数据和写数据给驱动两种情况,也可以使用ReadFile从驱动读数据和用WriteFile写数据给驱动,而调用DeviceIoControl函数有同步和异步方式;当应用程序退出时,用CloseHandle关闭设备[4].当WDM捕获到特定事件(如中断)时,就应当与应用程序进行通信.驱动程序与应用程序的通信有DeviceIoControl异步完成和Win32 事件通知两种方法.对于DeviceIoControl异步完成,当应用程序调用DeviceIoControl时,驱动程序首先将此IRP保存,然后调用I.MarkPending(),设法返回STATUS_PENDING.在一个事件发生后,驱动程序完成该IRP.由于IRP是未决的,所以必须将此IRP保存,当应用程序退出时,若IRP仍未发生,必须取消该IRP.对于Win32 事件,由应用程序创建一个事件后,直接将该事件句柄传递给驱动程序,然后等待驱动程序发送事件通知.驱动程序通过类Kevent获取这个事件的一个对象指针后,在IRQL≤DISPATCH_L EVEL级别的例程中设置事件信号状态来触发应用程序.4.5 驱动程序的安装在利用向导生成WDM驱动程序框架时,DriverWorks的Driverwizard已经在所建工程的sys目录下生成了一个设备信息INF文件.只要将文件中双引号中的内容改为我们需要的内容即可生成我们自己的设备信息文件.如:[Strings]ProviderName=“ECJTU GPS Institute”//公司名称MfgName=“ECJTU GPS Institute”//硬件制造商名称DeviceDese=“WDM Driver”//设备描述DeviceClassName=“PCI9052采集卡”//设备类名称在Windows系统重启时会自动检测所有外设,当第一次检测到我们的设备时系统会提示用户指定新硬件的驱动程序,根据提示安装我们最终的.INF文件和.sys系统文件,就可完成新硬件驱动程序的安装.也可以用控制面板中的添加新硬件来搜索新硬件,并安装新硬件的驱动程序.用DriverStudio自带的安装卸载工具进行驱动的安装和卸载将十分方便.在安装完驱动后,通过设备管理器中选择硬件属性,就可以看到为硬件添加的驱动.5 结束语利用DriverStudio开发WDM设备驱动程序可以降低驱动程序开发的难度,缩短开发周期.其中,SoftICE调试工具也为驱动程序的开发带来很多方便,采用这种方法开发的设备驱动程序具有较强的通用性和可移植性.基于上述方法,我们开发了PCI9052采集器的设备驱动程序,并用8155芯片进行了验证,工作稳定正常.现在,本采集卡已在基于PCI总线的GPS接收机系统中得到了应用,并取得了良好的效果.参考文献:【相关文献】[1] 李贵山.PCI 局部总线开发者指南[M].西安:西安电子科技大学出版社,1997. 1-56.[2] CANT C著,孙义,马莉波译.Windows WDM设备驱动程序开发指南[M].北京:机械工业出版社, 2000. 138-195.[3] PLX Technology,In C.PCI 9052 Data Book,Version 2.0[M].USA:PLX Technology InC,2001.1-172.[4] 武安河,邰铭,于洪涛.Windows2000/ XP WDM 设备驱动程序开发(第2版)[M]. 北京:电子工业出版社,2005.23-116.。

Osprey PCI系列多媒体采集卡驱动程序发行说明说明书

Osprey PCI系列多媒体采集卡驱动程序发行说明说明书

June 2015Osprey® PCI Series Multimedia Capture DriverRelease NotesDriver Version 5.0.1.93V IDEO C APTURE C ARDOsprey 100, 210, 230, 440, & 530This driver has been tested on the following operating systems:•32-bit version of Windows 7•32-bit version of Windows 8/8.1•64-bit version of Windows 7•64-bit version of Windows 8/8.1•32-bit version of Windows 10•64-bit version of Windows 10•64-bit version of Windows Server 2008 R2 Enterprise•64-bit version of Windows Server 2012 StandardS ECTIONS IN T HIS FILEV IDEO C APTURE C ARDI NTRODUCTIONT ROUBLESHOOTINGT ESTING THE D RIVERM ANUALS AND H ELPL ATEST D RIVERS AND D OCUMENTATIONK NOWN I SSUESD RIVER I NSTALLATIONI NSTALL S CENARIOST ECHNICAL S UPPORTI NTRODUCTIONThis driver is the classes 1-4 AVStream video and audio capture driver for the Osprey Analog PCI Series video capture cards. This driver is built on Microsoft's AVStream / DirectShow® driver model.Check the Osprey website for updates or other operating system (OS) drivers.This driver works only with genuine Osprey video capture cards designed and marketed by Osprey Video, Inc of Carrollton, TX USA.T ROUBLESHOOTINGIf the installation program for this driver appears to hang, press Alt+Tab to ensure the installation screen is not hidden.The Digital Signature Not Found window may appear during the installation. Click Continue Anyway to dismiss this dialog.The diagnostic tab should only be used at the direction of an Osprey technical representative. Invoking tests or setting the wrong value could lock up the computer.T ESTING THE D RIVERThe driver is able to access the properties for the card through most major DirectShow applications such as Microsoft Windows Media Encoder or Flash Media Encoder. For detailed information on how to select the Osprey card and access the video properties, see the documentation with the third-party software.M ANUALS AND H ELPRefer to the Osprey Analog PCIe Series User Guide for detailed information about the Osprey driver.L ATEST D RIVERS AND D OCUMENTATIONBefore installing, check the Osprey website at for the latest drivers and documentation.If there is no newer driver at the time of your installation, periodically check the website for newer versions.K NOWN I SSUESThis release is not WHQL-certified.L ATEST InstallationThe examples provided are for Microsoft Windows 7, other OS versions may vary. Depending on your system setup, you will have multiple options for the installation of the Osprey Multimedia drivers.If you need to re-install this Osprey Analog PCI Series driver, you must uninstall any previous Osprey Analog PCI Series driver and reboot.I NSTALL S CENARIOSIn most cases, the most efficient and complete installation method is to install the Osprey driver before installing the card. The install program automates the Plug and Play steps required to install the drivers and ensures they are performed correctly.Following are the different scenarios and their methods of installation: Threemain situations may apply to you:Scenario 1: Osprey card(s) not physically installed in the PC. * RECOMMENDED METHOD*Scenario 2: Osprey card(s) physically installed, but Osprey software not installed. Scenario 3: Osprey card(s) physically installed, and previous Osprey software installed.•You must uninstall all previous installations of the Osprey Analog PCI Series driver before installing this version. You must also reboot your computer after uninstalling.•It is possible to install the Osprey Analog PCI Series driver using the Hardware Installation Wizard. Select Have disk and navigate to the Drivers directory located onthe installation disk to select the INF file. This advanced feature will not be supported by documentation or Customer Support. Use this method at your own risk.•The installer provides a Custom installation option, which allows selected installation.•Although the installer allows drivers to reside across mapped network drives, this method is not recommended because it will not allow a proper uninstall.Scenario 1: Osprey Card(s) Not Physically Installed in the PCThis scenario is called the Preinstall Scenario. After the install is run, as soon as an Osprey card is installed in the PC, it is detected and its drivers are started automatically. 1. Double-click the Microsoft Windows MSI installer file to start the installation.2. If you choose to do a custom install, select Destination Folders and Program Folders whenprompted.3. You will then be prompted to preinstall the drivers. Select Yes to continue.4. The Osprey software is now fully installed. It will be ready for use after you install the Ospreycard in your computer.5. When you are ready to install the card, shut down and install the Osprey card inside yourcomputer, then power up the computer. The OS will detect the newly present Osprey card, and begin to activate the pre-installed driver. The Osprey card will then be ready for use. Scenario 2: Osprey Analog PCI Series Card(s) Physically Installed, But Osprey Software Not InstalledRun the installation program:When you start the OS for the first time after the Osprey card is installed, the New Hardware Found wizard may appear one or more times. Cancel out of these wizards.After the OS has finished starting, do the following:1. Double-click the MSI installer file. This action will start the installation program.2. If you choose to do a custom install, select Destination Folders and Program Folders whenprompted.3. When the installation is finished, reboot the PC for the configuration changes to take effect. Scenario 3: Osprey Analog PCI Series Card(s) Physically Installed, and Previous Osprey Software InstalledThis scenario is for the case when the Osprey card is physically installed in the PC and there is a previous installation of the Osprey drivers.It is necessary to uninstall the old driver before installing the new driver. You must also reboot your computer after uninstalling.After restarting, the New Hardware Found wizard may appear one or more times. Cancel out of these wizards.Run the installation program:1. Double-click the MSI install file. This action will start the installation program.2. If you choose to do a custom install, select Destination Folders and Program Folders whenprompted.3. When the installation is finished, reboot the PC for the configuration changes to take effect. T ECHNICAL S UPPORTPhone: 972-488-7156Email:***********************Web: Product specifications and availability may change without notice.2017 Osprey Video, Inc. Osprey®, SimulStream® (and design) TM are registered trademarks Osprey Video or its subsidiaries. All other trademarks are the property of their respective owners.。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第一步DriverWorks开发环境的建立
我们用NuMega DriverStudio开发WDM驱动程序,它的环境建立步骤如下:
1、安装VC6.0;
2、安装相应操作系统的DDK(如2000DDK、98DDK等);
3、安装NuMega DriverStudio;
4、运行NuMega DriverStudio下Tools下的Setup DDK and Start MSVC 程序;或自己在VC IDE中手动设置BASEDIR和CPU等环境变量。

5、用VC6.0打开NuMegaDriver StudioDriverWorksSourceVdwLibs.dsw 工程;
6、设置VC6.0的CompileConfig的配置为WDM Free或Checked;
7、编译VdwLibs.dsw库建立DriverWork的库文件,对Free 和Checked 都要编译;
8、可以开始WDM驱动程序的开发了;
第二步用DriverWorks生成驱动程序框架
----以胜西S5933PCI卡为例
步骤1:
从程序组中选择或从VC6.0的主菜单DriverStudio中选择Driver Wizard菜单项,便会弹出DriverWorks NT/WDM驱动程序的基本框架生成向导,见下图:
图2—1步骤1
步骤2:
在Project下填入工程名,如SX5933。

在Location选择工程文件存放的目录,再点Next进入下一个对话框。

选择WDM方式,再点Next进入硬件总线选择对话框。

图2—2步骤2
步骤3:
在Select Hardware Bus单选框中选择PCI,并在下面的栏目中填入PCI Vendor ID(如10EB),PCI Device ID(如8376)。

这两项必须与你要访问的PCI设备的VID和DID一致。

PCI Sub system ID和PCI Revision ID可以不填。

如填,也须与设备的SVID和SDID一致辞。

如不填,须手动删除INF文件中的有关项。

否则向导生成的INF文件不能完成该设备驱动程序的正常安装。

图2—3步骤3
点击Next进入步骤4。

图2—4步骤4
步骤4:
在此处可以修改Driver类名和文件名,也可采用系统默认的。

点击Next进入步骤5。

图2—5步骤5
步骤5:
此例去掉Read、Write、Cleanup的选择,只选择Device Control。

当然用户可根据自己应用的需要来选择。

点Next进入步骤6。

图2—6步骤6
步骤6:
选择I/O串行化方式,此例选择了None。

点击Next进入步骤7。

图2—7步骤7
步骤7:
此对话框是用来在驱动程序开始时从寄存器加载参数用,此例未用,故可不做任何改动。

点击Next进入步骤8。

步骤8:设备类的定义和资源、接口、缓冲、电源的处理
根据你的硬件定义资源。

如I/O口,MEMORY,中断等。

SX5933 PCI卡的PCI区域0(BAR0)为S5933内部寄存器用,区域1(BAR1)为SXL-100实验箱的I/O空间,区域2(BAR2)为SXL-100的存储空间。

SX5933 PCI卡用到一个PCI中断。

以下三步是针对SX5933PCI卡上的两个I/O端口(BAR0和BAR1)和MEM 空间(BAR2)而定义的三个资源。

向导会在驱动程序中加入相应的变量并替你完成映射。

点击“Add IO Port(s)…”按钮,在Name和PCI Base Address编辑框中输入如图2-9所示变量名IO0和数值0。

其它地方可不做改动,或根据实际需要做相应变动。

这样,变量m_IO0(只须输入IO0,向导会自动加上m_)就与BAR0对应。

图2-9
再点击“Add IO Port(s)…”按钮,在Name和PCI Base Address编辑框中输入如图2-10所示变量名IO1和数值1。

其它地方法可不做改动,或根据实际需要做相应变动。

这样,变量m_IO1(只须输入IO1,向导会自动加上m_)就与BAR1对应。

图2-10
点击“Add Memory Range…”按钮,在Name和PCI Base Address编辑框中输入如图2-11所示变量名MEM0和数值2。

其它地方法可不做改动,或根据实际需要做相应变动。

这样,变量m_MEM0(只须输入MEM0,向导会自动加上m_)就与BAR2对应。

图2-11
点击“Add IRQ…”按钮,为设备驱动加入一个中断处理对象以及其ISR和DPC例程。

向导会自动添加它们的初始化、连接代码。

下面定义设备的接口。

可定义两种对外接口,应用程序通过这两个接口中之一方可打开设备。

这里选择用符号链接,且将符号链接名改成SX5933。

该步骤中关于缓冲策略以及电源管理的设置可不做改动,或根据实际需要做相应变动。

点击Next进入步骤9。

步骤9:
如要与应用程序或与其它驱动程序进行数据交换,须加必要的Device IO Control的控制代码。

图2-12
点击“Add …”按钮,在Parameter Name编辑框中输入如图2-13所示代码名称。

其它地方法可不做改动,或根据实际需要做相应变动。

然后点击OK。

图2-13
再点击“Add …”按钮,在Parameter Name编辑框中输入如图2-14所示代码名称。

其它地方法可不做改动,或根据实际需要做相应变动。

然后点击OK。

图2-14
类似地,加入名为IOCTL_IO_WRITE的控制代码。

向导会在SX5933ioctl.h 头文件中定义这些控制代码。

点击Next进入步骤10。

步骤10:
此步骤选择是否产生应用层的测试程序以及调试操作等。

此例采用的是默认方式。

点击Finish按钮,在接下来的提示框中点击OK。

接着向导会问你是否现在就要在VC中打开此工程。

如选择是,向导不但会直接在VC中打开该工程,而且还会替你将编译环境给你设置好。

接下来用户可以根据自己的需求添加相关内容了。

相关文档
最新文档