WDM驱动程序入门1
WDM驱动
Windows驱动开发模型WDM学习笔记绪言 (4)1.WDM驱动程序开发基础知识 (5)1.1WDM简介:Win32 Driver Model Win32驱动程序模型 (5)1.2 Win32 API (5)1.3 WDM特性 (5)1.4 WDM工作原理 (6)1.5 WDM与其它驱动程序的比较 (6)2.WDM驱动程序开发环境DDK设备驱动程序开发包 (6)2.1■安装DDK (6)2.1.1.Windows 98 DDK的安装 (7)2.1.2.Windows 95 DDK的安装 (7)2.1.3.NT DDK的安装 (8)2.2 ■构造环境:建立WDM驱动程序构造环境的方法 (8)2.2.1. 用SETENV.bat来安装驱动程序构造环境 (9)2.2.2. 手工运行SETENV.bat (9)2.2.3. 构造WDM驱动程序 (9)2.2.4.构造驱动程序 (9)2.2.5.检查Windows 98 DDK的安装 (9)3.WDM驱动程序的设计与开发 (10)3.1■WDM 驱动程序的运作流程 (10)3.2■驱动程序设计 (10)3.3■驱动程序开发 (11)3.3.l.编写驱动程序框架 (11)3.3.2.测试驱动程序 (11)4.WDM驱动程序编译运行:编译和安装设备驱动程序的方法 (12)4.1■编译设备驱动程序的方法 (12)4.1.1.举例分析 (12)4.1.2.编译的基本步骤 (13)4.2■设备驱动程序的安装和启动 (13)4.2.1.添加注册表中的键值 (13)4.2.2.控制驱动程序的装入次序 (14)4.2.3.驱动程序的Start值 (14)4.2.4.修改注册表的方法 (15)4.2.5.启动设备驱动程序 (15)4.2.6.调试工具 (16)5.wdm驱动开发基础-一些需要注意的问题汇总 (16)5.1注册表的角色 (16)5.2.如何命名注册表键 (16)5.3从用户模式中访问设备键 (17)5.4 函数原型“IN”关键字 (17)5.5 注册设备接口 (18)5.6 初始化设备扩展 (18)5.7 注意侧效 (19)5.8 try-finally中的控制流程 (20)5.9 生成异常 (22)5.10 __Leave语句 (23)5.11 简化页大小 (24)5.12 页故障关于分页 (24)5.13 alloc_text的使用 (25)5.14 关于段布置 (26)5.15 服务函数描述 (26)5.16 ExAllocatePoolWithTag (28)5.17 ExAllocatePool的其它形式 (29)5.18 单链表 (30)5.19 lookaside链表的服务函数 (31)5.20 打开注册表键 (31)5.21 删除子键或键值 (32)5.22 枚举子键或键值 (33)5.23 IRQL限定 (35)5.24 IRQL的明确控制 (35)5.25 自旋锁 (36)6. wdm驱动开发基础代码分析解析 (36)绪言在Windows的不同版本上开发的驱动程序“模型”(模型这个词语应该来源于单词“Mode”。
WDM驱动开发之路(1)
WDM驱动开发之路(1)WDM开发之路(1)--驱动开发网WDM教程WDM驱动开发之路写在前面:在专栏的前几期中,我们一起初步学习了vxd的开发技术。
Vxd技术是很深奥的,不是一篇两篇文章能讲清楚,但你已经入了门,剩下的就要看你的修行了。
多看书,多泡论坛(当然是上咱们的驱动开发网论坛了:->),多写程序…我的手不够用了。
功到自然成嘛。
不过话又说回来,vxd只是权宜之计,WDM才符合当今的潮流(程序员都是时髦人士,君不见先是VB、VC然后是asp、JSP、PHP,数也数不过来呀),Win9x寿终正寝时也就是vxd的末日,你不想随它而去吧(开个玩笑),那就随我来。
按笔者的想法,这篇文章写成连载形式,一次讲一个主题,并且必要时带着例子,让大伙step by step地把WDM驱动弄个透底,不想让大家觉得稀里糊涂,也不想让大家觉得白买杂志了。
今天我们一起讨论第一部分,了解篇。
(一)了解篇WDM模型(Windows Driver Model)是微软公司为当前主流操作系统Windows98和Windows 2000的驱动程序设计的一种构架。
它和传统的win3.x和win95使用的vxd的驱动是完全不同的体系结构。
不过对于最终用户来说,WDM驱动程序在Windows98和Windows2000下的表现很相似。
作为驱动开发人员来说,它在两者中有很多的不同。
并且Windows98中的WDM只能算是Windowss2000中的WDM的一个了集。
在Windows98中有一些驱动程序只能使用VXD来实现,如串行通讯驱动等。
要写驱动程序,首先要了解操作系统的结构。
在WDM体系中,windows2000操作系统中是最标准的实现方式,Windows98则是部分兼容WDM结构。
照微软的说法,Windows98和Windows2000 X86(Intel 架构)版本实现二进制码兼容(参见98DDK),Windows2000 x86版本与其它CPU平台版本实现源码级兼容(因为Windows 2000是基本NT相似的结构,最底层是硬件抽象层HAL,所有我们相信它们之间能源码级兼容)。
关于Windows WDM设备驱动程序
关于Windows WDM设备驱动程序
描述:
1 WDM支持哪些操作系统(起码要求说明是否支持WIN XP系列
2 WDM可以实现哪些方面的功能
3 使用WDM是否可以实现全局控制WINDOWS
4 WDM和VXD的区别
5 WDM程序的载体的存在方式(即DLL、EXE、DRV、VXD等)
6 WDM程序的开发工具(如用VC++应创建哪类工程)
3.Oh, you mistake the architecture of the WDM in OS.Your driver in WDM mode is only ONE part in the large operation system.You could say "affect" not "control" system kernel, because it has ring0 privilege.
"NT System Drivers" are used by Windows NT, Windows 2000 and to a degree by Windows 98 (in a slightly newer form known as "Windows Driver Model"drivers). They execute at kernel mode and, like VxDs, use an entirely different API that user mode application code. They consist entirely of 32-bit code. The documentation included with the Windows NT, 2000 and 98 DDKs describes the API calls used by NT system and WDM drivers. "Dynamic Link Libraries", or DLLs, are basically normal application code packaged into a dynamically-loadable module. They execute at user mode and consist entirely either of 16- or 32-bit code and use the normal Windows API (they *can* call CreateWindow(), etc.). They are loaded by applications or other DLLs and export functions (usually by name) that can be called directly.
WDM驱动程序简介
设;避免在代码中直接引用硬件
可抢先性和可中断性 多处理器安全 基于对象 数据包驱动 异步
Windows XP 系统结构
WDM驱动程序模型
WDM模型主要包含以下内容:
1、描述了设备驱动程序的标准结构和应该完成的主 要功能。
一个应用程序打开了设备因此系统发送给驱动另一个irp处理函数进行了少量的操作之后返回???操作系统与驱动的交互过程?应用程序尝试读取或者写入一些数据因此系统发送一个irp处理例程将irp放入一个队列之后返回
设备驱动程序设计
第二讲
WDM驱动程序简介
Windows XP 驱动程序分类
内核模式驱动程序的属性
迷你驱动:包含在类驱动中,用于管理设备实例的厂商专有
特征例程。类驱动和迷你驱动合在一起才构成一个完整的 功能驱动程序。
IRP包
WDM驱动的层次结构
上层过滤器驱动程序 功能驱动程序
下层过滤器驱动程序 总线驱动程序
驱动程序如何工作
驱动程序是一个收集让操作系统调用的用来执行各 种涉及到硬件操作的子程序的容器。
某些I/O操作引发设备中断,中断服务例程做一些 很少的操作,然后请求一个DPC,之后返回。
DPC例程运行了,它可能要读回数据,或者继续下 一次的写操作等,然后开始下一个排在队列中的 IRP,之后DPC例程返回系统。
随着时间变化,在这期间系统会发送各种IRP给驱 动程序,驱动程序进行相应的处理。
操作系统与驱动的交互过程
系统运行时设备插入或者系统重新启动发现了某个 设备,系统就会装载可执行的驱动程序到内存中, 并且调用其DriverEntry例程。DriveEntry做了一些 初始化操作之后返回。
如何安装WDM驱动
为了让这个驱动被系统加载,必须创建一个 inf 文件。
由于是使用现成的例子,因此这一步也可以省下来。
直接右键点击例子中的 inf 文件,在弹出的菜单中选择 “安装 ”即可。
这里要注意的是, inf 中的 StartType 参数,它可以控制驱动被加载 的方式:因为是测试,我使用 SERVICE_DEMAND_START ,即由手动加载 驱动。
例子是 miniFilter 驱动,因此可以在命令提示行中用 “fltmcload 驱动名称 ”来加载,相应的卸载是 “fltmc unload ”。
如果是其它驱动,则 用"net start 驱动名称"来加载,相应的卸载是"net stop 驱动名称”。
注 意驱动名称不是文件名, 而是inf 中[Settings ]的ServiceName 值。
驱动 要发布时,也可以通过 CreateService & StartService API 来动态安 Inf 文件的写法,可以参考例子,或者拿现成的改一改。
下面的是摘 自驱动开发网的XiangXiangRen 整理的 Inf 文件, 改起来比较方便, 谢谢 XiangXiangR en 。
文件过滤驱动安装 inf 文件简易获得法不少同仁获得 inf 文件都是直接修改 sfilter.inf, 这个修改很需要耐性, 不小心 敲错 又不能编译调试,改错难度不小。
有些同仁不加修改,结果 sfilter 满天飞:)。
我修改了一下 sfilter 的安装文件,这样你只要修改最后的字符 串列表,就可以 轻松得到自己的安装文件了。
可以用于任何打算静态加载的文件过滤驱动, 内容 如下:SERVICE_AUTO_START (2)SERVICE_BOOT_START (0) 会自动加载SERVICE_DEMAND_START(3) 安全模式下不会自动加载 在系统安全模式下启动时 驱动也则驱动不会自动加载[Version]signature = "$Windows NT$"Class = "ActivityMonitor" ;This is determined by the work this filter driver doesClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2} ;This value is determined by the ClassProvider = %MyName%DriverVer = 08/28/2005,1.0.0.1CatalogFile = Mycat.cat ; A CatalogFile entry is required for a WHQL sign ature.; The actual catalog file will be provided by WHQL. The; catalog file for this sample is not provided for use. [DestinationDirs]DefaultDestDir My.DriverFiles = 12= 12 ;%windir%\system32\drivers[SourceDisksNames]1 = %MyDisk%[SourceDisksFiles]%MySysFileName% = 1[DefaultInstall]OptionDesc = %MyServiceDesc%CopyFiles = My.DriverFiles[DefaultInstall.Services]AddService = %MyServiceName%,,My.Service AddReg = My.AddRegistry[DefaultUninstall]DelFiles = My.DriverFilesDelReg = My.DelRegistry[DefaultUninstall.Services]DelService = %MyServiceName%,0x200 [My.Service]DisplayName Description ServiceBinary= %MyServiceName%= %MyServiceDesc%= %12%\%MySysFileName%;%windir%\system32\drivers\JwFvfs.sysServiceType = 2 ;SERVICE_FILE_SYSTEM_DRIVERStartType = 0 ;SERVICE_BOOT_STARTErrorControl = 1 ;SERVICE_ERROR_NORMALLoadOrderGroup = "FSFilter Activity Monitor" ;"filter" if install to 2k.AddReg = My.AddRegistry[My.AddRegistry][My.DelRegistry][My.DriverFiles]%MySysFileName%[Strings]MyName = "Tan Wen"MyServiceDesc = "Tan Wen's File System Filter."MyServiceName = "TanWenFsF"MyRegistry = "system\currentcontrolset\services\TanWenFsF"MyDisk = "Tan Wen Source Media"MySysFileName = "TanWen.sys"修改的时候只要修改最后的字符串列表,依次是开发者名,服务描述,服务名,注册表位置,磁盘标签,驱动文件名。
wdm设备驱动程序入门共39页文档
应用程序对设备对象的操作过程
操作接口:设备驱动程序的Win32 API函数,或重载的设备驱动程序的 Win32 API回调函数。 操作参数:设备句柄、操作类型及其它信息。 例:DeviceIoControl(hDevice, DIOC_MY_IO, NULL, 0,
NULL, 0, NULL,NULL); Win32子系统处理:将I/O操作转换后交I/O管理器处理, I/O管理器创建 一个I/O请求包(IRP)后,送到设备对象栈的最上层设备对象对应的驱动 程序。
已装 入?
执行DriverEntry(),设置各例程 的入口地址,将对象指针装入I/O 管理器中
PnP管理器装入最底层过滤驱动程序,调用其 AddDevice函数,该函数创建一个FiDO,实现FiDO与 同级驱动程序的连接
AddDevice函数把PDO连接到FiDO上 PnP管理器依次装入各级驱动程序,完成整个设备对象栈
PnP管理器根据需要给设备发送各种PnP IRP PnP管理器给设备发送“启动设备”PnP IRP,驱动程序将分 配的资源信息向下传送到设备配置头区域中,并启动设备
驱动程序处于等待状态,等待IRP的到来
WDM驱动程序的结构
WDM驱动程序包含许多例程,操作系统调用这些例程来执
行对IRP的各种操作。
Hale Waihona Puke 基本驱动程序例程取得厂商、设备类型、版本、资源需求等信息
PnP管理器就创建PDO,在注册表中添加某些项
N
所有硬件检测完毕?
Y PnP管理器决定分配哪些资源给各个设备
设备驱动程序的装入过程
PnP管理器查找注册表中与该PDO相吻合的各级驱 动程序
找到? N
Y
读INF文件,按INF文 件指令安装各级驱动
PCI传输卡的WDM驱动程序设计.
PCI传输卡的WDM驱动程序设计2008-01-20摘要:介绍了在Windows2000操作系统下,使用DriverStudio软件编写符合WDM模式的PCI数据传输卡驱动程序,并详细分析了一个应用实例。
关键词:PCI总线设备驱动程序 WDM模式 DriverStudioPCI总线规范是为提高微机总线的数据传输速度而制定的一种局部总线标准。
在设计自行开发的基于PCI总线的数据传输设备时,需要开发相应的`设备驱动程序。
通常开发PCI设备驱动程序有多种模式,在Windows2000环境下,主要采用WDM模式。
本文针对自行开发的基于PCI总线的CCD视频信号传输控制卡,编写了符合WDM模式的驱动程序。
1WDM模式驱动程序1.1WDM模式(WindowsDriverModel)Windows2000对驱动程序的编写不再基于以往的Win3.x和Win9x下的VxD(虚拟设备驱动程序)结构,而是基于一种新的驱动模型――WDM(WindowsDriverModel)。
WDM为Windows98/2000/XP操作系统的设备驱动程序的设计提供了统一的框架。
WDM来源于WindowsNT的分层32位设备驱动程序模型(layered32-bitdevicedrivermodel)。
它支持更多的特性,如即插即用(PnP)、电源管理、WMI和NT事件。
1.2设备驱动程序设备驱动程序是操作系统的一个组成部分,它由I/O管理器(I/OManager)管理和调动。
Windows2000操作系统下的I/O管理器功能描述如图1所示。
I/O管理器每收到一个来自用户应用程序的请求就创建一个I/O请求包(IRP)的数据结构,并将其作为参数传递给驱动程序。
驱动程序通过识别IRP中的物理设备对象(PDO)来区别是发送给哪一个设备。
IRP结构中存放请求的类型、用户缓冲区的首地址、用户请求数据的长度等信息。
驱动程序处理完这个请求后,在该结构中填入处理结果的有关信息,调用IoCompleteRequest将其返回给I/O管理器,用户应用程序的请求随即返回。
WDM驱动程序开发之驱动框架篇:KDriver类
KDriver类:一、OverviewKDriver类提供了一个设备驱动程序的框架。
这个类的职责包括初始化驱动程序,把I/ O请求传递给它们的目标设备对象。
KDriver是一个抽象类,驱动编写人员必须写一个新的类来继承它。
新的子类必须重写DriverEntry函数,这是当系统载入驱动程序时框架要调用的函数。
这个派生类会有一个构造函数,但是构造函数不允许有参数。
一般来说,最好不要写这么一个构造函数。
把一切的初始化工作放在DriverEntry函数里来进行。
对于任何给定的驱动,只能有一个KDriver 类的实例存在,而且这个实例是框架自动创建的。
任何调用者可以通过调用DriverInstan ce静态函数来获得一个指向这个唯一实例的指针。
驱动编写人员必须做的另一件事情是通知框架:哪个类作为驱动框架来提供服务。
框架提供了定义了一个宏定义DECLARE_DRIVER_CLASS来实现这个事情。
任何一个驱动程序里都必须调用一次且只能调用一次这个宏,一般是在拥有DriverEntry函数的组件里。
这个宏必须放在任何函数之外,因为它事实上声明一个可以被框架调用的函数。
宏的参数应该是继承了KDriver类的那个类的名字。
除了DriverEntry,KDriver还有其他两个成员函数来做初始化的工作:RequestRei nitialization() 和Reinitialize()。
一个驱动程序在DriverEntry函数里调用RequestRe initialization()函数来指示系统调用Reinitialize()函数,作为第二级初始化。
而Reiniti alize()函数是一个可被重写的虚函数。
如果想要系统具有卸载(Unload)驱动的功能,就要在function.h文件里做一个声明:#define DRIVER_FUNCTION_UNLOAD。
这是虚函数Unload()的得到声明。
这个函数在基类中的实现代码调用了DeleteDevices() 函数来为这个驱动程序创建的每个设备调用析构函数。
Dell WDM使用手册
Dell WDM使用手册一、客户端设备发现设置1.1配置WDM发现管理客户端方式点击Configuration Manager-Preference-Device Manager Preference根据网络部署情况有几种发现方式,选择自动发现方式,一般选择第二、第四项,DNS SRV记录和手动在WDM上查找,下面失败次数选择3次。
1.2 DNS服务器上建立WDM的SRV服务位置记录信息(建议)在DNS服务器上点击正向查找区域,右键点击作用域-其他新记录选择服务位置(SRV),点击创建记录按下图输入相应信息,其中提供此服务的主机可以为WDM服务器的完整域名或IP地址。
1.3 WDM新建管理网段建立WDM管理网段,把需要管理的网段建立,WDM可以在管理网段搜索客户端。
1.4搜索管理网段的客户端右键点击Device Manager,选择FindDevices选择刚才建立的管理网段,进行网段内客户端的搜索1.5在客户端上添加WDM服务器的地址根据不同型号的客户端,添加的方法也不同1.WES系统的客户端,如C90,Z90,D90等,如果添加了DNS SRV,一般哦情况下,新版本系统可以自动从DNS服务器得到WDM信息,无需手动添加,如果旧版本或其他原因无法自动获得,需要在控制面板-WDM中手动添加2.ThinOS零系统的客户端,如C10,T10等,可以在wnos.ini中指定WDM服务器地址或者采用自动发现的方式。
在wnos.ini中加入以下几行WDMServer=WDM IP DHCPinform=no DNSLookup=no如果DNS设置了SRV或DNS创建了WDMServer的主机记录,则添加WDMFQDN=如 DHCPinform=no DNSLookup=yes添加域名和DNS发现的优势是如果更换WDM服务器,或WDM服务器故障,新建WDM服务器只需配置域名即可,客户端会自动发现。
如果手动添加,在ThinOS上点击Central Configuration集中配置,选择WDM,在WDM Servers中输入WDM IP地址或域名,选择DNS发现方式和失败发现次数。
WDM驱动程序
建立驱动开发环境建立驱动开发环境,所需的软件为DriverStudio3.2 + DDK2003 + VC。
DDK建议使用最新的DDK2003,因为可以减少很多麻烦。
使用DDK2600的话,很多人反映会碰到一个编译出错的问题。
这是我使用DDK2600时碰到的同样的问题,然后在EDNchina网站上发的贴:--------------我在用DriverStudio开发驱动时,碰到了这样的问题:--------------------Configuration: KFileWrite - Win32Free--------------------d:\DESIGN~1\DRIVER~1\DRIVER~4\include\kcsq.h(35): Could not find the file csq.h.d:\DESIGN~1\DRIVER~1\DRIVER~4\include\kcsq.h(35): Could not find the file csq.h.Linking with DDK linker...LINK : fatal error LNK1181: cannot open input file 'ntstrsafe.lib' Error executing link.exe.KFileWrite.sys - 1 error(s), 0 warning(s)关键是这个ntstrsafe.lib.我在网上一搜,碰到这种问题的人还不少呢,虽然解决方法是很多,但都差不了几个字,要么从DDK2003那拷一个,或者是在project-->setting-->link下去掉对ntstrsafe.lib的链接,也不知他们自己到底有没有试,我在project-->setting-->link下压根就没看到ntstrsafe.lib几个字...很郁闷啊--------------网上所说的解决方法是对的,但没有说清楚,使人无法一时明白。
WDM驱动程序设计
IRP_MN_START_DEVICE 处理函数
NTSTATUS HandleStartDevice(PDEVICE_OBJECT fdo, PIRP Irp) { NTSTATUS status = ForwardAndWait(fdo, Irp); ……… PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PCM_PARTIAL_RESOURCE_LIST raw, translated;
translated->PartialDescriptors; ULONG nres = translated->Count; for (ULONG i = 0; i < nres; ++i, ++resource) {
switch (resource->Type) { case CmResourceTypePort: // 配置硬件,用局部变量记录资源分配结果 case CmResourceTypeInterrupt: case CmResourceTypeMemory: case CmResourceTypeDma:
✓ 开发人员不用关心这些细节,只须用READ_PORT_XXX函数 或WRITE_PORT_XXX访问该寄存器就可以了。
UCHAR READ_PORT_UCHAR(IN PUCHAR Port); ULONG READ_PORT_ULONG(IN PULONG Port); USHORT READ_PORT_USHORT(IN PUSHORT Port); VOID WRITE_PORT_UCHAR( IN PUCHAR Port,
DWDM技术培训[1](2024版)
合波/分波单元
n 烽火通信DWDM系统采用AWG器件实现合波/分 波
n 单盘可提供32/40波合/分波
n 插损小,隔离度高
合
分
n 降低首级EDFA的增益要求,减小噪声引入
n 一个DWDM系统好比一条高速公路,分为正反向双车道,就好比通信系统用的两条双纤一样,所有的车辆只 允许单向行进,就是所谓的(双纤双向或单纤单向)系统。
n 一个高速公路设计之初就用规划所使用的车道的数量8λ16λ32λ、……设 道1计 数60波 量λ n 每个高速公路都有规定的最高时设速计,单1波20道km/h,180km/h,对应起来就好比DWDM系统的每个波道的最高速率一
光信躁比
放大器的自发辐射噪声 系统的噪音积累
非线性效应
自相位调制(SPM) 交叉相位调制(XPM) 四波混频(FWM) SBS SRS
➢ G.652:普通单模光纤,1550nm窗口具有 低衰耗值,大有效面积和大色散分布,是大 多数已经敷设的光纤。
➢ G.653:零色散位移光纤, 1550nm窗口具 有低衰耗值,小有效面积和零色散。
PPT文档演模板
DWDM技术培训[1]
网络设计仿真软件模拟真实系统
利用设计仿真软件模拟光路的建立、帮助设计人员准确无误进行系统设计。 简单、方便、快捷、准确。 将网络的实际参数以导入到网络仿真软件; 网络仿真软件模拟各个光复用段和放大段的功耗以及光信噪比( OSNR )。
PPT文档演模板
DWDM技术培训[1]
PPT文档演模板
DWDM技术培训[1]
DWDM系统需考虑的问题(色散)
一. 光纤色散:模间色散、色度色散、偏振模色散 二. 色度色散
色散系数D():指光源谱宽和单位长度光纤的色度色散,其单位是 ps/(nm.km)。
WDM软件使用方法
(1)根据所给折射率计算出相关有效折射率参数按照下列步骤,打开一个新文件①在File菜单中,单击New。
在此步中计算参数的计算已经开始,将会出现如下图所示的Device Parameter Setup 对话框,在里面设置波导的宽度以及中心波长,以及波导模式②定义所定义的参数选择Edit Layers,出现如图所示Layer Structure对话框,根据所给波导及波导芯的宽度和厚度、上下包层及波导芯的折射率对下图各个数据进行修改③计算仿真结果点击Calculate按钮,即可计算出有效折射率,计算结果如下图所示=3.361014,晶片的有效如上图所示,可以看出整个AWG波导的有效折射率为nc折射率为3.327347点击Close,即可出现下面的图示,其中Effective Index选项具有上述计算所确定,即为默认值,在Initial Data 对话框里,可以修改Wafer栏中晶片的长度以及宽度,以使其达到我们所设计的要求,在本项目中,选择其长度为15000,宽度为10000(2) 利用Device Wizard根据所确定的AWG相关参数建立AWG模型点击上图的OK按钮,即可得到AWG的设计界面,如下图所示①在Design菜单下选择Device Wizard,出现如下图所示图形②在上图中,Polarization栏中选择TM,这是因为有效指数的计算(在横向平面)是TE偏振而阵列波导的仿真在外延平面,因此,方向颠倒,偏振发生相反的变化。
Waveguide Width栏应和初始化时应保持一致。
通过对Maximum Crosstalk Level (dB)的修改可以确定下图中的Minimum I/O waveguide separation(输入/输出波导间距)、Minimum array waveguide separation (相邻阵列波导间距)的大小,但是一般情况下均设置为-35,点击下一步即出现如下图所示图形③在上图中,可以通过对于FPR Effective index(自由光谱区有效参数,理论上确定的数值)、Nonuniform ity(均匀性,一般默认为0.5) 、Output(所需要的输出通道)进行设置,使其达到我们所要求的结果,其中在我们确定好输出通道的同时,修改Nonuniformity,可以改变下图中的自由光谱区的长度。
windows设备驱动程序WDF开发(1)
windows设备驱动程序WDF开发(1)武安河另外讲WDM的书是《windows 2000/xp wdm设备驱动开发》KDMF 构建在WDM之上,内核级,sys⽂件UDMF ⽤户级,dll⽂件第1章 Windows 2000和WDM驱动程序1.中断优先级(IRQL): 32个中断级别,可打断0 : PASSIVE_LEVEL, 常规线程1:APC_LEVEL, 异步调⽤过程2:DISPATCH_LEVEL, 延迟过程调⽤3~26: DIRQL, 硬件中断2. 在DISPATCH_LEVEL 运⾏代码时,访问⾮分页内存是⼀个根本原则第2章 KMDF驱动程序框架1. 环境变量结构_DEVICE_CONTEXT{}pDeviceContext = GetDeviceContext(Device);2. 创建对象的⽅法KMDF控制的对象⽣命周期:WDFDRIVER, WDFDEVICE, WDFFILEOBJECT, WDFREQUEST (IRP)3. KMDF结构1)DriverEntry:设置 EvtDeviceAdd (安装时调),WdfDriverCreate 创建驱动对象2) EvtDriverDeviceAdd: 新设备被枚举时会调⽤,职责:创建设备对象,I/O队列,GUID接⼝,事件回调例程,WdfDeviceCreate, WdfDeviceCreateDeviceInterface, WdfDeviceInitSetExclusive(DeviceInit,TRUE); // 独占,只允许⼀个应⽤打开WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchSequential); // IO为串⾏ WdfIoQueueCreate // io队列WdfDeviceCreateDeviceInterface // guid接⼝3)I/O处理例程WDF_FILEOBJECT_CONFIG_INIT(&FileConfig,EvtDeviceFileCreate, EvtFileClose, EvtFileCleanup);ioQueueConfig.EvtIoDeviceControl = PCI9056WDF_EvtIoDeviceControl; // DeviceIoControl 调⽤ioQueueConfig.EvtIoRead = PCI9056WDF_EvtIoRead; // ReadFileioQueueConfig.EvtIoWrite = PCI9056WDF_EvtIoWrite; // WriteFile第3章基本对象1. WDFREQUEST: I/O请求,即IRPWdfRequestComplete :完成请求WdfRequestCompleteWithInformation :完成请求,完成的传输字节数WdfRequestRetrieveInputBuffer: 获取输⼊缓冲器地址WdfRequestRetrieveInputMemory: 获取输⼊缓冲器地址,形式为WDFMEMORYWdfRequestRetrieveInputWdmMdl: 获取输⼊缓冲器地址,形式为MDLWdfRequestGetIoQueue:返回队列对象WdfRequestGetFileObject: 返回⽂件对象WdfRequestGetInformation: 完成的传输字节数WdfRequestCreate: 创建IO请求2. IO请求(IRP)基本操作取消IO请求:编写取消例程向下传递IO请求3. WDFQUEUE 队列, WdfIoQueueDispatchSequential 串⾏初始化默认队列 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUEWdfIoQueueCreateWdfIoQueueStart : 启动接收和分发IRPWdfIoQueueStop:暂停分发,但还接收WdfIoQueueDrain: 停⽌接收,但分发WdfIoQueuePurge: 停⽌接收,取消队列中的IRP4. WDFTIMER, WDFDPC, WDFWORKITEM, WDFMEMORY5. 数据同步1)⾃旋锁运⾏在DISPATCH_LEVEL(⾃动提升),因此不能访问分页内存WdfSpinLockCreate, WdfSpinLockAcquire, WdfSpinLockRelease2)WDFWAITLOCK 运⾏在PASSIVE_LEVEL, 同步锁WdfWaitLockCreate, WdfWaitLockAcquire, WdfWaitLockRelease6. 字符串CHAR, WCHAR, STRING, UNICODE_STRINGWDFSTRING: WdfStringCreate串处理函数:strlen之类7. 队列编程 QueueSample// 因为取消例程等要⽤环境变量,所以⽤⼀个设备对象范围同步(重要)deviceAttr.SynchronizationScope = WdfSynchronizationScopeDevice;调⽤例程,取消例程,定时器回调例程,都⽤了设备对象范围同步,所以运⾏在DISPATCH_LEVEL,不能⽤分页内存。
WDM软件使用方法
(1)根据所给折射率计算出相关有效折射率参数按照下列步骤,打开一个新文件①在File菜单中,单击New。
在此步中计算参数的计算已经开始,将会出现如下图所示的Device Parameter Setup 对话框,在里面设置波导的宽度以及中心波长,以及波导模式②定义所定义的参数选择Edit Layers,出现如图所示Layer Structure对话框,根据所给波导及波导芯的宽度和厚度、上下包层及波导芯的折射率对下图各个数据进行修改③计算仿真结果点击Calculate按钮,即可计算出有效折射率,计算结果如下图所示=3.361014,晶片的有效如上图所示,可以看出整个AWG波导的有效折射率为nc折射率为3.327347点击Close,即可出现下面的图示,其中Effective Index选项具有上述计算所确定,即为默认值,在Initial Data 对话框里,可以修改Wafer栏中晶片的长度以及宽度,以使其达到我们所设计的要求,在本项目中,选择其长度为15000,宽度为10000(2) 利用Device Wizard根据所确定的AWG相关参数建立AWG模型点击上图的OK按钮,即可得到AWG的设计界面,如下图所示①在Design菜单下选择Device Wizard,出现如下图所示图形②在上图中,Polarization栏中选择TM,这是因为有效指数的计算(在横向平面)是TE偏振而阵列波导的仿真在外延平面,因此,方向颠倒,偏振发生相反的变化。
Waveguide Width栏应和初始化时应保持一致。
通过对Maximum Crosstalk Level (dB)的修改可以确定下图中的Minimum I/O waveguide separation(输入/输出波导间距)、Minimum array waveguide separation (相邻阵列波导间距)的大小,但是一般情况下均设置为-35,点击下一步即出现如下图所示图形③在上图中,可以通过对于FPR Effective index(自由光谱区有效参数,理论上确定的数值)、Nonuniform ity(均匀性,一般默认为0.5) 、Output(所需要的输出通道)进行设置,使其达到我们所要求的结果,其中在我们确定好输出通道的同时,修改Nonuniformity,可以改变下图中的自由光谱区的长度。
WDM入门教程
WDM入门教程学习和编写WDM 驱动程序对谁而言都是一件具有挑战的事情,需要恒心和毅力。
当你入门后你会发现这是一件多么令人兴奋的事情。
但是如何使用WDM的编译环境从而开始WDM学习的旅程?对一个初学者来说这个门槛可不低。
安装完DDK后,可以用[开始]->[Development kit]->[Windows XX DDK]->[check/free Build Environment]来启动编译环境,由于DDK没用提供IDE环境(当然你可以使用配置后的VC或DriverStudio这另当别论),对于我们这些孕育在Xp时代的程序员来说这无疑是件难事。
为什么?因为编译一个WDM程序除了.cpp .h 源文件外至少还需要:makefile文件sources 文件这两个文件本应该由IDE自动帮我们生成,如VC就为我们的所有工程生成了makefile,sources,xx.rc文件,平时我们根本不需要了解他们就可以编译我们的工程。
可DDK没有工具为我们生成这两个文件,但DDK编译程序的时候又需要他们,俗话说得好“我不如地狱谁入地狱”,我们就来编写这两个文件:一.makefile (没有扩展名,它名字就叫makefile),内容如下:# DO NOT EDIT THIS FILE Edit .\sources. if you want to add a new source# file to this component. This file merely indirects to the real make file# that is shared by all the components of NT.#!INCLUDE $(NTMAKEENV)\makefile.def值得高兴的是,WDM程序使用的所有makefile都这样写,我们只需写一个,编译时把它拷贝到工作目录下就行了二.sources文件就需要我们根据不同的场合修改了,不过基本模板如下:TARGETNAME=驱动程序名// 告诉编译器连接生成的文件名为“驱动程序名”(不含扩展名)TARGETPATH=obj // 固定不变TARGETTYPE=DRIVER // 固定不变(表明,连接成*.sys <驱动程序>文件)DRIVERTYPE=WDM // 为 Win32 Driver Model 驱动INCLUDES=$(BASEDIR)\inc\ddk;$(BASEDIR)\inc // 源程序可能使用的DDK头文件所在的目录// 多个目录用“;” 隔开SOURCES=aa.cpp bb.cpp // 将编译的源文件(不写*.h), 资源文件(*.rc)// 多个文件用空格隔开其中“$(BASEDIR)”指DDK当前的安装目录,例如当前DDK安装在D:上,则$(BASEDIR) 就是“D:\DDK”,所以上面的INCLUDES可以翻译成D:\DDK\inc\ddk; D:\DDK\inc三.不得不注意的3个讨厌问题:1. 编译时必须保证 makefile,sources和源程序在同一目录下2. 编写sources文件时,其中的”=”两边不能有空格3. 如果上面的问题还不够讨厌,那么下面这个问题可以讨厌的让人放弃学习DDK,工程的工作目录的绝对路径中不能出现空格,如“C:\Documents and Settings\MyProgramme\”将不能被DDK编译器编译,而且表面上看来DDK好像是完成的编译,实际上它什么都没做!1:首先安装好WDK,然后进入"开始"->"所有程序"->"Windows Driver Kits"->"WDK XXXX.XXXX.X" ->"Windows XP"->"x86 Checked Build Environment"在弹出来的命令行窗口中输入"Build",让它自动生成所需要的库,等待它执行完2:打开VS2005,在菜单上选择"工具"->"选项"弹出"选项"窗口,选择"项目和解决方案"->"VC++目录","显示以下内容的目录""可执行文件"中添加"F:\WinDDK\7600.16385.0\bin\x86\x86" "F:\WinDDK\7600.16385.0\bin\x86" "F:\WinDDK\7600.16385.0\tools\pfd\bin\bin\x86""包含文件"中添加"F:\WinDDK\7600.16385.0\inc\api" "F:\WinDDK\7600.16385.0\inc\crt" "F:\WinDDK\7600.16385.0\inc\ddk""引用文件"中添加"F:\WinDDK\7600.16385.0\lib\wxp\i386""库文件"中添加"F:\WinDDK\7600.16385.0\lib" "F:\WinDDK\7600.16385.0\lib\wxp\i386""源文件"中添加"F:\WinDDK\7600.16385.0\src"以上添加完毕直接按"确定"关闭"选项"对话框如果编译出现C2144错误的时候,请把以上添加的文件向前移动(就是点击"选项"对话框中的向上的箭头按钮)3:新建工程后配置管理器:新建:Checked4:工程属性:c++:预处理器:_X86_调用约定:__stdcallLINK:输出文件:后缀为sys $(OutDir)\$(ProjectName)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
WDM驱动程序入门(1)——HelloWDMWDM驱动程序是一种很新的东西,相信很多人都跟我一样,对它很感兴趣,但是又找不到学习的切入点。
究其原因,还是因为WDM是一种非常“死板板”的程序,它一运行就是工作在系统的底层RING 0处,提供各种接口给应用程序调用。
也正因为如此,它不像普通的应用程序一样,可以很快地上手——更多的时候,你是在阅读它的技术资料和各种接口信息,你还要非常地熟悉系统底层的工作原理,否则一个不小心,就“蓝屏”了,呵呵——话说回来,写驱动程序的时候,死机是家常便饭。
因此很多人都对WDM望而生畏了。
回想一下,我刚开始学WDM的情形还历历在目——看书看了整整3天,但是看完之后好像跟没看也差不了多少,还是不知道怎么入门,甚至连怎么写一个“Hello World”都不知道——后来才知道其实WDM 是没有所谓的“Hello World”程序的,唉,真是痛苦啊,这主要还是因为网络上的WDM资料太少造成的。
为了不让大家重蹈我的覆辙并对WDM有个感性的认识,在此我给出一个最简单的完整的WDM框架,并附有注释,姑且可以算是一个入门的“Hello World”吧。
废话少说,让我们马上开始研究,要求读者已安装DDK 2000。
(在Win98中我还没有测试过,不清楚是否能正常运行)/***************************************************************程序名称:Hello World for WDM文件名称:HelloWDM.cpp作者:罗聪日期:2002-8-16***************************************************************///一定要的头文件,声明了函数模块和变量:#include"HelloWDM.h"/***************************************************************函数名称:DriverEntry()功能描述:WDM程序入口***************************************************************///extern "C"是必须的,表示“用C链接”。
如果你的文件名是HelloWDM.c的话,这句可以省略。
extern"C"NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath){//指定“添加设备”消息由函数“HelloWDMAddDevice()”来处理:DriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;//指定“即插即用”消息由函数“HelloWDMPnp()”来处理:DriverObject->MajorFunction[IRP_MJ_PNP]= HelloWDMPnp;//返回一个NTSTATUS值STATUS_SUCCESS。
几乎所有的驱动程序例程都必须返回一个NTSTATUS值,这些值在NTSTATUS.H DDK头文件中有详细的定义。
return STATUS_SUCCESS;}/***************************************************************函数名称:HelloWDMAddDevice()功能描述:处理“添加设备”消息***************************************************************/ NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject){//定义一个NTSTATUS类型的返回值:NTSTATUS status;//定义一个功能设备对象(Functional Device Object):PDEVICE_OBJECT fdo;//创建我们的功能设备对象,并储存到fdo中:status = IoCreateDevice(DriverObject,//驱动程序对象sizeof(DEVICE_EXTENSION),//要求的设备扩展的大小NULL,//设备名称,这里为NULLFILE_DEVICE_UNKNOWN,//设备的类型,在标准头文件WDM.H 或NTDDK.H中列出的FILE_DEVICE_xxx值之一0,//各种常量用OR组合在一起,指示可删除介质、只读等。
FALSE,//如果一次只有一个线程可以访问该设备,为TRUE,否则为FALSE&fdo);//返回的设备对象//NT_SUCCESS宏用于测试IoCreateDevice内核是否成功完成。
不要忘记检查对内核的所有调用是否成功。
NT_ERROR宏不等同于!NT_SUCCESS,最好使用!NT_SUCCESS,因为除了错误外,它还截获警告信息。
if(!NT_SUCCESS(status))return status;//创建一个设备扩展对象dx,用于存储指向fdo的指针:PDEVICE_EXTENSION dx =(PDEVICE_EXTENSION)fdo->DeviceExtension; dx->fdo = fdo;//用IoAttachDeviceToDeviceStack函数把HelloWDM设备挂接到设备栈: dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);//设置fdo的flags。
有两个“位”是必须改变的,一个是必须清除DO_DEVICE_INITIALIZING标志,如果在DriverEntry例程中调用IoCreateDevice(),就不需要清除这个标志位。
还有一个是必须设置DO_BUFFER_IO标志位:fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;fdo->Flags &=~DO_DEVICE_INITIALIZING;//返回值:return STATUS_SUCCESS;}/***************************************************************函数名称:HelloWDMPnp()功能描述:处理“即插即用”消息***************************************************************/ NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,IN PIRP Irp){//创建一个设备扩展对象dx,用于存储指向fdo的指针:PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;//首先要通过函数IoGetCurrentIrpStackLocation()得到当前的IRP,并由此得到Minor Function:PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); ULONG MinorFunction = IrpStack->MinorFunction;//然后把这个Minor Function传递给下一个设备栈:IoSkipCurrentIrpStackLocation(Irp);NTSTATUS status = IoCallDriver( dx->NextStackDevice, Irp);//处理“即插即用”次功能代码://当Minor Function等于IRP_MN_REMOVE_DEVICE时,说明有设备被拔出或卸下,这时要取消资源分配并删除设备:if( MinorFunction==IRP_MN_REMOVE_DEVICE){//取消设备接口:IoSetDeviceInterfaceState(&dx->ifSymLinkName, FALSE);RtlFreeUnicodeString(&dx->ifSymLinkName);//调用IoDetachDevice()把fdo从设备栈中脱开:if(dx->NextStackDevice)IoDetachDevice(dx->NextStackDevice);//删除fdo:IoDeleteDevice(fdo);}//返回值:return status;}/***************************************************************程序名称:Hello World for WDM文件名称:HelloWDM.h作者:罗聪日期:2002-8-16***************************************************************///头文件,只是声明一些函数和变量,比较简单就不多说了,请读者自行研究:#ifdef __cplusplusextern"C"{#endif#include"ntddk.h"#ifdef __cplusplus}#endiftypedef struct _DEVICE_EXTENSION{PDEVICE_OBJECT fdo;PDEVICE_OBJECT NextStackDevice;UNICODE_STRING ifSymLinkName;} DEVICE_EXTENSION,*PDEVICE_EXTENSION;NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject);NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,IN PIRP Irp);好了,第一个WDM版的“Hello World”就介绍到这里,虽然实际上它什么都没有做,但是由于它包含了完整的框架,所以对于初学者来说还是很有参考价值的。