原文出处:http://www.cnblogs.com/jacklu/p/4646601.html

本科毕业设计是这方面的工作,所以想开几篇博客来介绍使用WDF开发PCI/PCIe接口卡的驱动程序方法。

在上一篇简要介绍了WDF和开发环境搭建后,本篇将讲述几个WDF中的概念,对开发者了解WDF非常有帮助,属于“内功部分”;

本篇文章结构将没那么清晰,当句句都是作者通过看书、看论文、看MSDN提炼出来的,希望对读者能够有所帮助。

如果你觉得这篇博客对你的项目有用,请引用以下论文:

Meng Shengwei, Lu Jianjie. Design of a PCIe Interface Card Control Software Based on WDF. Fifth International Conference on Instrumentation and Measurement, Computer, Communication and Control. IEEE, 2016:767-770.

 

1、WinDBG是唯一的内核驱动调试利器,但是开发PCIe的WDF驱动可以采用“黑盒”方式,所以windbg不是必须的;

2、WDF比WDM好,别再用WDM了;

3、驱动程序编译成的二进制文件是sys类型,和EXE一样都是Portable Executable File Format;DLL也是PE格式

4、微软提供的内核接口只有C/C++

5、驱动程序开发时,需要为每一个函数指定其是分页内存还是非分页内存

6、PAGE标识是指此函数能在驱动运行时被交换到磁盘上;如果不指定,编译器默认为非分页内存;一般情况下,我们不许要考虑这些问题。但有些特殊的情况,代码是不允许被交换到硬盘上的,否则导致操作系统蓝屏或者自动重启;

7、驱动开发一定要关注warnning!!!除非你对这个warnning带来的影响非常了解;

8、派遣函数又可称为回掉函数,提供给操作系统调用。这些派遣函数是我们的主要工作重点;

9、创建设备时要判断设备是否创建成功,比进行必要的失败处理。驱动程序中这样的处理对于驱动程序的健壮性起着不容忽视的作用;

10、驱动程序的设备名称对应用程序来说是透明的,只能应用于内核,这也是为什么要创建设备符号链接、GUID的原因;

 

 

为了不给读者带来疲劳,再从1开始计数吧~

 

 

1、用户模式应用程序的虚拟地址空间除了为专用空间以外,还会受到限制。在用户模式下运行的处理器无法访问为该操作系统保留的虚拟地址。限制用户模式应用程序的虚拟地址空间可防止应用程序更改并且可能损坏关键的操作系统数据;

2、在内核模式下运行的所有代码都共享单个虚拟地址空间。这表示内核模式驱动程序未从其他驱动程序和操作系统自身独立开来。如果内核模式驱动程序意外写入错误的虚拟地址,则属于操作系统或其他驱动程序的数据可能会受到损坏。如果内核模式驱动程序损坏,则整个操作系统会损坏;

3、最正式的设备堆栈的定义:设备堆栈为(设备对象、驱动程序)对的有序列表,设备堆栈中创建的第一个设备对象位于底部,创建并附加到设备堆栈的最后一个设备对象位于顶部;

4、安装设备驱动时,安装程序使用信息(INF)文件中的信息来确定哪个驱动程序为函数驱动程序、哪个驱动程序为筛选器。这样安装后,PnP管理器就能通过注册表来确定设备的函数驱动程序和筛选器驱动程序了;

5、发送到设备的请求大部分都打包在I/O数据请求包中(IRP),IRP结构体:http://msdn.microsoft.com/zh-cn/library/windows/hardware/ff550694%28v=vs.85%29.aspx;

6、IRP包含驱动程序处理I/O请求所需的全部信息;

7、驱动程序拆分为两个部分:一部分处理通用处理,另一部分处理特殊设备的处理,通用部分由Microsoft编写;特定部分由Microsoft或者硬件提供商编写;

8、通用部分称为“框架”,特定部分称为KMDF驱动程序;

9、”框架“可以处理I/O请求队列、线程同步以及很大一部分的电源管理任务;因此当某人将IRP发送到对时,IRP会转至框架。如果框架可以处理IRP,则不会涉及到KMDF驱动程序;如果框架处理不了就通过调用KMDF驱动程序来实现事件处理程序来获取帮助;

10、WDK中的头文件包含的条件语句指定编程元素仅在某些版本的Windows操作系统中才可用

 

 

好吧,还没有写完~

 

 

1、创建驱动程序时,可以指定Windows 7为基本的目标操作系统,在这种情况下,驱动程序会在Win7或更高的Windows上运行;

2、KMDF为驱动程序提供基于对象的接口,对象接口包括:
对象方法(驱动程序在对某个对象执行操作或者获取设置对象属性时可调用的函数)
对象事件回调函数(驱动程序提供的函数)
对象属性(属性是驱动程序可获取和设置的的存储在对象中的值)
对象句柄(基于框架的驱动程序)

3、每个基于框架的驱动程序都包括:一个DriverEntry例程,可在加载驱动程序时调用,一组事件回调函数,框架将在发生特定于对象的事件时调用这些函数;

4、基于 Windows 的驱动程序分为三种类型:总线驱动程序功能驱动程序筛选器驱动程序;

5、I/O 管理器通过创建 I/O 请求数据包 (IRP),将应用程序的 I/O 请求发送到驱动程序。IRP 可包含执行 I/O 操作(如读/写操作)的请求或执行 I/O 控制 (IOCTL) 操作(如返回状态)的请求。此外,PnP 管理器还会创建表示驱动程序必须执行的 PnP 和电源管理操作的 IRP,并将这些 IRP 发送到驱动程序;

6、I/O 管理器通常在用户应用程序请求读取或写入操作时创建读取或写入 IRP;

7、回调函数一定要返回STATUS_SUCCESS (如果操作成功)否则,回调函数将返回错误信息(定义在Ntstatus.h);

8、KMDF修订历史记录:http://msdn.microsoft.com/zh-cn/library/windows/hardware/ff544309(v=vs.85).aspx

9、驱动程序项目是生成驱动程序二进制文件(如 .sys 文件)以及可能驱动程序的 INF 文件的 Microsoft Visual Studio 项目。驱动程序是用于安装驱动程序的文件集合。驱动程序包中包含一个 INF 文件,以及由该 INF 引用的文件和二进制文件。如果使用驱动程序模板创建驱动程序解决方案,该模板应自动创建一个包含两个项目的解决方案。一个用于驱动程序,另一个用于驱动程序包;

10、内核模式下的驱动程序在从用户地址中读取或写入这些地址时必须非常小心!

1)用户应用程序发起设备读取请求,程序提供缓冲区的起始地址以接受数据;

2)内核驱动程序启动读取操作并将控制权返回到其调用程序;

3)设备中断当前运行的任何线程以显示读取操作完成。中断由此线程上运行的内核驱动程序进行处理;
4)驱动程序不得将数据写入用户应用程序在1)中提供的地址,此地址位于发起请求的进程的虚拟地址空间,该进程很大可能不同于当前进程。
 
 
好吧,先写到这里吧,想到后再补充,下一篇应该就会介绍WDF驱动程序中的几个重要的例程了。

  广告时间~本人博士赚外快,如需要完整的驱动程序源代码请联系合作email: 346457821@qq.com

posted on 2015-07-14 21:11  J博士  阅读(6963)  评论(0编辑  收藏  举报