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

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

这个系列的博客将首先用一个篇幅为不懂Windows 下PCI/PCIe驱动开发的介绍WDF和开发环境搭建,接下来几篇将直接讲述程序编写,

看完这几篇后,希望能够帮助读者了解如何通过500行左右的代码实现一个标准的PCIe接口卡驱动程序。

毕设题目的PCIe板卡是BAR0下映射两个5K的内存,偏移地址为0x20000和0x22000,源代码在文章结束后会考虑公布

1.1WDM与WDF

Windows平台下的设备驱动程序从Windows 2000开始都是以WDM ( Windows Driver Model) 框架为平台进行开发。以此模型开发,开发者需要一方面实现驱动程序与硬件的交互,另一方面要对操作系统内核进行操作,难度大。驱动程序容易出现问题,这也是Windows2000以来操作系统容易蓝屏的原因。

为了改善这种局面,降低驱动程序开发者的开发难度,提高系统稳定性,微软推出了新的驱动程序开发模型WDF。WDF对WDM进行了封装,将驱动程序中与操作系统交互的细节由框架实现。这样驱动程序就从内核中分离出来,开发者只需要专注处理与硬件的交互,简化了驱动程序的设计,提高了整个系统的可靠性和稳定性。WDM与WDF样例驱动程序对比如下表所示。通过该表可以看到基于WDF框架的驱动程序,代码量显著减少,开发起来更加容易。

WDF是UMDF(User Mode Driver Framework,用户模式驱动程序框架)和KMDF(Kernel Mode Driver Framework,内核模式驱动程序框架)的总和。由于本课题基于PCIe硬件设备进行驱动开发,涉及到内存读写等内核操作,所以使用KMDF框架来编写驱动程序。

1.2 Windows驱动程序

我们知道Windows是一个分层的操作系统,它的运行依赖于上层组件向下层组件的调用。一个简化的I/O流模型如下图:

1.3 WDF框架

通过参考《竹林蹊径 深入浅出Windows驱动开发》和《Developing_drivers_with_the_Microsoft_Windows_Driver_Foundation》,WDF抽象的框架如下图所示:

WDF已经把驱动程序开发做了很好的封装,开发者只需要定义框架对象和编写事件回调函数。WDF中也采用对象,但是它和C++这种编程语言中的对象不相同,毕竟WDF是C写的。如何解释WDF的对象我也做不到,我的一直把WDF中的对象看做一种数据结构,比如WDFDRIVER对象,其实就是一个与驱动程序相关的结构体。另外,WDF中也有例程这样的称呼,是对routine的翻译,可以理解为函数体。所以简单来说,对PCIe驱动程序来说,开发者需要定义一些结构体,编写几个函数就ok了,具体如何被调用,那就是WDF框架内部的事情了,我们只需要知道,当我们注册好编写好的回调例程之后,当事件发生(设备插入、设备打开、I/O操作等)时,WDF会自动帮我们调用相关的例程。

1.4 开发环境搭建

Windows 驱动程序开发工具包 (WDK) 与 Microsoft Visual Studio 和用于 Windows 驱动程序的调试工具相集成。该集成环境给开发者提供了开发、构建、打包、部署、测试和调试驱动程序时所需的工具。

本课题确定时,微软的最新驱动程序工具包为WDK8.1。WDK8.1 更新与 Microsoft Visual Studio2013 集成。开发者需要首先在微软的官方网站上下载并安装 Visual Studio 2013,然后安装WDK 8.1 更新。微软声明不再对WDK8.0提供支持,也不再对WDK 8.0做任何更新,WDK8.0也不支持Windows8.1的驱动程序开发。所以本课题选用WDK8.1作为开发工具包。然而新技术发展速度飞快,在本课题完成之际,微软打算极力推广的Windows 10操作系统还未正式公布,针对Windows 10的驱动程序开发工具包WDK 10已经推出。未来一定会推广使用WDK10来开发。

下载链接:https://msdn.microsoft.com/zh-cn/windows/hardware/hh852365,下载两个安装包,依次安装,非常简单。

1.5 PCIe简介

最后简要介绍一下PCIe。

PCIe协议采用分层结构,如下图所示,PCIe的结构主要由以下三个层次组成,它们分别是:传输层(Transaction Layer),数据链路层(Data Link Layer)以及物理层(Physical Layer)。其中物理层又可以分为两个子层:逻辑子层(Logical Sub-block)和电气子层(Electrical Sub-Block)。

TLP(Transaction Layer Packet)由传输层产生,通过使用存储器事务,I/O事务,配置事务和消息事务来进行信息数据的通信;DLLP(Data Link Layer Packet)由数据链路层产生,用来在该链路上两个直连设备之间传递信息,其内容主要包括功耗管理信息,流控制信息以及 TLP 的应答信息等。DLLP只开始在数据链路层,并止于数据链路层,不会上传到传输层。

以上是希望读者能够对PCIe有个初步的了解,但是对驱动程序的开发并没什么卵用。

对PCIe设备来说,它可以有三个相互独立的物理地址空间:设备存储器地址空间、I/O地址空间和配置空间。因为PCIe设备支持即插即用,所以并不占用固定的内存地址和I/O地址,而是在设备插入时由操作系统决定其映射的基址。配置空间对设备控制程序设计来说非常关键。PCIe设备支持基本的256字节PCI兼容配置空间。对PCI/PCIe设备来说,其基本的配置空间为前64字节,如下图所示。

由于PCIe是基于PCI提出的,地址空间模型没有变化,所以PCI控制软件可以完全兼容PCIe设备。

下一篇博客将讲述PCIe的WDF驱动程序中几个非常重要的概念,对初学者了解WDF非常有用。

基于WDF的PCI/PCIe接口卡Windows驱动程序(1)-WDF概述及开发环境搭建的更多相关文章

  1. 基于WDF的PCI/PCIe接口卡Windows驱动程序(2)-开发者需要了解的WDF中的一些重要的概念

    原文出处:http://www.cnblogs.com/jacklu/p/4646601.html 本科毕业设计是这方面的工作,所以想开几篇博客来介绍使用WDF开发PCI/PCIe接口卡的驱动程序方法 ...

  2. 基于WDF的PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)

    原文出处:http://www.cnblogs.com/jacklu/p/4687325.html 本篇文章将对PCIe驱动程序的源文件代码作详细解释与说明.整个WDF驱动程序工程共包含4个头文件(已 ...

  3. 基于WDF的PCI/PCIe接口卡Windows驱动程序(5)-如何为硬件移植驱动程序

    原文地址:http://www.cnblogs.com/jacklu/p/6139347.html 正如前几篇博客所说,使用WDF开发PCIe驱动程序是我本科毕业设计的主要工作.在读研的两年,我也分别 ...

  4. 基于WDF的PCI/PCIe接口卡Windows驱动程序(3)- 驱动程序代码(头文件)

    原文出处:http://www.cnblogs.com/jacklu/p/4679304.html 在WDF的PCIe驱动程序中,共有四个.h文件(Public.h  Driver.h  Device ...

  5. windows平台CodeBlocks MinGW C++11开发环境搭建

    前言: 本文是以单独下载codeblock编辑器跟MinGW编译器这种方式进行安装,下载带MinGW编译器的codeblocks版本安装配置方式跟这个类似. 一: 下载并安装MinGW 这个参考我写的 ...

  6. Windows 7下Node.js Web开发环境搭建笔记

    Node.js是什么? 我们看看百科里怎么说的?JavaScript是一种运行在浏览器的脚本,它简单,轻巧,易于编辑,这种脚本通常用于浏览器的前端编程,但是一位开发者Ryan有一天发现这种前端式的脚本 ...

  7. windows下Qt5.2 for android开发环境搭建

    windows下Qt5.2 forAndroid开发环境配置 1.下载安装Qt 5.2.0 for Android (Windows 32-bit)   http://qt-project.org/d ...

  8. 【转】windows下vs2008/2010+opencv2.2开发环境搭建

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.下载安装Cmake 2.用cmake配置opencv2.2,然后编译,安装 3. 在vs2008中配置opencv2.2 4.Demo 1.下 ...

  9. 基于windows环境VsCode的ESP32开发环境搭建

    1. 基于windows环境VsCode的ESP32开发环境搭建,网上有各类教程,但是我实测却不行. 例如我在vscode内安装的乐鑫插件,扩展配置项是下图这样: 而百度的各类博文却都是这样: 经过网 ...

随机推荐

  1. Uri.AbsoluteUri 与 Uri.ToString() 的区别

    UriBuilder builder = new UriBuilder("http://somehost/somepath"); builder.Query = "som ...

  2. HDU 2177

    http://acm.hdu.edu.cn/showproblem.php?pid=2177 威佐夫博奕,面对奇异局势既bk=ak+k时是必败点,其中bk>=ak,k=bk-ak 别的处理和其他 ...

  3. windows dir改成ls

    习惯了linux下的ls命令,windows的dir用的很不习惯,又不想装cygwin, bash,就想把dir重命名为ls,发现dos下有个命令doskey可以完成该功能.在命令提示符下敲: > ...

  4. Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)

    前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...

  5. xmind的第七天笔记

  6. 移动开发框架,Hammer.js 移动设备触摸手势js库

    hammer.js是一个多点触摸手势库,能够为网页加入Tap.DoubleTap.Swipe.Hold.Pinch.Drag等多点触摸事件,免去自己监听底层touchstart.touchmove.t ...

  7. 2015GitWebRTC编译实录13

    2015.07.21 libboringssl.a 编译通过主要是生成路径,去除test文件比较啰嗦,后继测试需要重点跟进下 CC obj/third_party/boringssl/boringss ...

  8. 在Bootstrap中 强调相关的类

    .text-muted:提示,使用浅灰色(#999) .text-primary:主要,使用蓝色(#428bca) .text-success:成功,使用浅绿色(#3c763d) .text-info ...

  9. F1 分数

    F1 分数会同时考虑精确率和召回率,以便计算新的分数. 可将 F1 分数理解为精确率和召回率的加权平均值,其中 F1 分数的最佳值为 1.最差值为 0: F1 = 2 * (精确率 * 召回率) / ...

  10. 全面理解Javascript中Function对象的属性和方法

    http://www.cnblogs.com/liontone/p/3970420.html 函数是 JavaScript 中的基本数据类型,在函数这个对象上定义了一些属性和方法,下面我们逐一来介绍这 ...