驱动开发历程-驱动入门详解
- 格式:doc
- 大小:1022.44 KB
- 文档页数:80
linux驱动开发(⼀)1:驱动开发环境要进⾏linux驱动开发我们⾸先要有linux内核的源码树,并且这个linux内核的源码树要和开发板中的内核源码树要⼀直;⽐如说我们开发板中⽤的是linux kernel内核版本为2.6.35.7,在我们ubuntu虚拟机上必须要有同样版本的源码树,我们再编译好驱动的的时候,使⽤modinfo XXX命令会打印出⼀个版本号,这个版本号是与使⽤的源码树版本有关,如果开发板中源码树中版本与modinfo的版本信息不⼀致使⽆法安装驱动的;我们开发板必须设置好nfs挂载;这些在根⽂件系统⼀章有详细的介绍;2:开发驱动常⽤的⼏个命令lsmod :list moduel 把我们机器上所有的驱动打印出来,insmod:安装驱动rmmod:删除驱动modinfo:打印驱动信息3:写linux驱动⽂件和裸机程序有很⼤的不同,虽然都是操作硬件设备,但是由于写裸机程序的时候是我们直接写代码操作硬件设备,这只有⼀个层次;⽽我们写驱动程序⾸先要让linux内核通过⼀定的接⼝对接,并且要在linux内核注册,应⽤程序还要通过内核跟应⽤程序的接⼝相关api来对接;4:驱动的编译模式是固定的,以后编译驱动的就是就按照这个模式来套即可,下⾯我们来分下⼀下驱动的编译规则:#ubuntu的内核源码树,如果要编译在ubuntu中安装的模块就打开这2个#KERN_VER = $(shell uname -r)#KERN_DIR = /lib/modules/$(KERN_VER)/build# 开发板的linux内核的源码树⽬录KERN_DIR = /root/driver/kernelobj-m += module_test.oall:make -C $(KERN_DIR) M=`pwd` modulescp:cp *.ko /root/porting_x210/rootfs/rootfs/driver_test.PHONY: cleanclean:make -C $(KERN_DIR) M=`pwd` modules cleanmake -C $(KERN_DIR) M=`PWD` modules这句话代码的作⽤就是到 KERN_DIR这个⽂件夹中 make modules把当前⽬录赋值给M,M作为参数传到主⽬录的Makefile中,实际上是主⽬录的makefile中有⽬标modules,下⾯有⼀定的规则来编译驱动;#KERN_VER = $(shell uname -r)#KERN_DIR = /lib/modules/$(KERN_VER)/build我们在ubuntu中编译内核的时候⽤这两句代码,因为在ubuntu中为我们保留了⼀份linux内核的源码树,我们编译的时候直接调⽤那个源码树的主Makefile以及⼀些头⽂件、内核函数等;了解规则以后,我们设置好KERN_DIR、obj-m这两个变量以后直接make就可以了;经过编译会得到下⾯⼀些⽂件:下⾯我们可以使⽤lsmod命令来看⼀下我们ubuntu机器现有的⼀些驱动可以看到有很多的驱动,下⾯我们使⽤insmod XXX命令来安装驱动,在使⽤lsmod命令看⼀下实验现象可以看到我们刚才安装的驱动放在了第⼀个位置;使⽤modinfo来打印⼀下驱动信息modinfo xxx.ko这⾥注意vermagic 这个的1.8.0-41是你⽤的linux内核源码树的版本号,只有这个编译的版本号与运⾏的linux内核版本⼀致的时候,驱动程序才会被安装注意license:GPL linux内核开元项⽬的许可证⼀般都是GPL这⾥尽量设置为GPL,否则有些情况下会出现错误;下⾯使⽤rmmod xxx删除驱动;-------------------------------------------------------------------------------------5:下⾯我们分析⼀下驱动。
软件开发中的测试驱动开发介绍随着互联网的快速发展,软件开发行业也得到了前所未有的发展。
越来越多的软件开发团队加入到了这个行业中,他们不断地开发新的应用程序和软件程序,用以满足客户的需求。
然而,软件开发过程中的测试是一个关键的环节,其质量直接关系到软件开发项目的成败。
因此,测试驱动开发(TDD)被广泛应用于软件开发过程中。
什么是测试驱动开发?测试驱动开发(TDD)是软件开发中的一种实践,其核心思想是在编写代码之前编写测试代码,然后根据测试代码的要求来编写代码。
这种方法可以让开发人员更好地掌握软件的代码逻辑,将软件的功能分解成更小更简单的单元,每个单元都有一个功能性测试。
通过这种方式,开发人员可以更快地发现和修复错误,提高代码质量和软件的可靠性。
测试驱动开发的优势测试驱动开发的优势主要体现在以下方面:1.能够快速发现错误由于测试代码在编写代码之前就存在了,因此可以有效减少代码错误的数量。
通过测试代码,开发人员可以确定其代码的正确性,并快速发现潜在的问题或错误。
2.提高代码质量测试驱动开发可以确保代码具有很高的质量。
编写测试代码可以帮助开发人员更好地理解代码的逻辑,从而更容易编写出高质量、易于维护的代码。
3.加速开发过程测试驱动开发可以让开发人员更快地进行开发。
由于开发人员能够在每个单元测试通过之后再进行下一步的开发,因此可以有效减少代码错误的数量,从而加快开发进程。
4.提高软件的可靠性通过测试驱动开发,软件的可靠性可以得到极大的提高。
由于经过测试的代码已经过其功能性和稳定性测试,因此在生产环境中运行时可以更加可靠和稳定。
测试驱动开发的步骤测试驱动开发可以分为以下几个步骤:1.编写测试代码开发人员首先需要编写测试代码。
测试代码应该覆盖程序的各个部分,用于检测程序中可能存在的任何错误或异常情况。
2. 运行测试代码在编写测试代码后,开发人员需要运行测试代码,以确保代码运行正确。
如果测试代码出现错误或异常情况,则需要重新修改测试代码,直到测试代码可以正确运行。
驱动开发流程驱动开发是指为了使硬件与软件能够良好地配合工作而开发的一种软件。
在计算机系统中,驱动程序是一种控制程序,它能够使操作系统或其他计算机控制程序能够与硬件设备进行通讯。
驱动程序通常由硬件制造商提供,以便让设备能够在特定的操作系统中运行。
在这篇文档中,我们将介绍驱动开发的流程,以帮助开发人员更好地理解并掌握驱动开发的方法和技巧。
第一步,需求分析。
在进行驱动开发之前,首先需要对需求进行分析。
这包括了解硬件设备的特性和功能,以及确定驱动程序需要实现的功能和性能要求。
在需求分析阶段,开发人员需要与硬件工程师和系统设计师进行充分的沟通和交流,确保对需求有清晰的认识和理解。
第二步,架构设计。
在完成需求分析之后,接下来是进行驱动程序的架构设计。
在这个阶段,开发人员需要确定驱动程序的整体结构和模块划分,以及各个模块之间的接口和交互关系。
同时,还需要考虑到驱动程序的可扩展性和可维护性,确保在后续的开发和维护过程中能够更加方便和高效地进行工作。
第三步,编码实现。
在完成架构设计之后,接下来是进行驱动程序的编码实现。
在这个阶段,开发人员需要根据需求和设计文档,编写相应的代码并进行调试和测试。
在编码实现过程中,需要遵循相关的编码规范和标准,确保代码的质量和可靠性。
第四步,测试验证。
完成编码实现之后,接下来是进行驱动程序的测试验证。
在这个阶段,开发人员需要进行单元测试、集成测试和系统测试,确保驱动程序能够正常地工作并满足需求。
同时,还需要进行性能测试和稳定性测试,确保驱动程序能够在各种不同的环境和条件下都能够正常运行。
第五步,文档编写。
在完成测试验证之后,接下来是进行驱动程序的文档编写。
在这个阶段,开发人员需要编写相关的技术文档和用户手册,以便让其他开发人员和用户能够更好地理解和使用驱动程序。
同时,还需要编写相应的维护文档和更新日志,以便在后续的维护和更新过程中能够更加方便和高效地进行工作。
总结。
驱动开发是一项复杂而又重要的工作,它直接关系到硬件与软件之间的配合和协作。
一、android驱动的开发流程1:写LINUX驱动2:写LINUX应用测试程序3:写JNI接口,用来包装第二步写的应用(要用NDK来编译)生成一个.SO文件,相当于CE下的DLL4:写JAVA程序,专门写一个类包含.SO文件,然后在JAVA里调用.SO里的函数。
例子,可以看NDK里面的Sample文件夹,里面有一些例子二、需要安装的环境编译Android的LINUX交叉编译工具编译LINUX驱动的交叉编译工具(4.3.1)编译JNI的工具包:NDK(在LINUX下)编译JAVA程序:esclips+ADT+SDK三、NDK安装1、下载NDK包,下载地址:/android/ndk/android-ndk-r4b-linux-x86.zip2、解压到/home/workspace/目录3、编辑环境变量sudo gedit /etc/profile在末行加入#set NDK envNDKROOT=/home/workspace/android-ndk-r4bexport PATH=$NDKROOT:$PATH更新修改source /etc/profile此时,系统就能识别ndk-build命令了4、编译例子进入sampleshello-jni 目录,编译cd samples/hello-jniaulyp@ubuntu:/home/workspace/android-ndk-r4b/samples/hello-jni$ ndk-build就能看到编译信息了,如果编译成功,会在该目录多生成2个子目录libs,obj目录四、安装JDK到Sun官方网站下载JDK6,选择JDK 6 Update 20下载页面地址: /technetwork/java/javase/downloads/index.html INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET INCLUDEPICTURE "/images/Android/android2.jpg" /* MERGEFORMATINET下载完后,双击进行安装安装成功,在cmd下输入java –version,会有JAVA的版本信息出来C:/Users/Aulyp>java -versionjava version "1.6.0_21"Java(TM) SE Runtime Environment (build 1.6.0_21-b07)Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)五、Esclips安装Linux:官方下载:/downloads/到Eclipse官方网站下载Ecplise For Java EE的最新版本我选择下载的是eclipse-java-helios-SR1-linux-gtk.tar解压到指定目录:/optaulyp@ubuntu:/opt$ sudo tar zxvf eclipse-java-helios-SR1-linux-gtk.tar.gz得到eclipse文件夹在桌面上创建启动图标;在桌面(右键单击桌面->创建启动器);然后选择名称:Eclipse命令:eclipse (点Browse 进去选择)图标:/opt/eclipse/icon.xpm(Ubuntu 10.04 上面有个图标,点击之后,选择路径)在桌面得到一个图标,这样可以双击该图标,打开Eclipse。
特征驱动开发方法特征驱动开发(Feature-driven development,简称FDD)是一种软件开发方法,它强调以特征为驱动的开发过程,通过明确定义和管理软件系统的特征,从而提高开发效率和质量。
本文将介绍特征驱动开发方法的基本原理、步骤和优势。
一、特征驱动开发的基本原理特征驱动开发的核心思想是将软件系统划分为一系列独立的特征,每个特征都代表了系统的一个功能或需求。
通过明确定义和管理这些特征,开发团队可以更好地理解和控制系统的需求,并将其转化为可执行的开发任务。
特征驱动开发方法的基本原理包括以下几点:1. 特征优先:在特征驱动开发中,特征是开发的核心,开发团队首先关注的是系统的特征,而不是具体的实现细节。
通过将系统需求分解为一系列特征,可以更好地管理和控制开发过程。
2. 迭代开发:特征驱动开发采用迭代的开发方式,每个迭代都以一个或多个特征为单位进行开发。
每个迭代都有明确的目标和交付物,可以及时反馈开发进展,并进行必要的调整和优化。
3. 面向对象:特征驱动开发方法借鉴了面向对象的思想,将系统划分为一系列独立的特征对象。
每个特征对象都有自己的属性和行为,可以独立地开发和测试。
通过组合和扩展特征对象,可以构建出完整的系统。
二、特征驱动开发的步骤特征驱动开发包括以下几个基本步骤:1. 需求建模:在需求建模阶段,开发团队与客户合作,明确系统的功能和需求。
通过分析和讨论,确定系统的特征集合,并定义每个特征的详细规格。
2. 特征设计:在特征设计阶段,开发团队将每个特征转化为一个或多个特征对象。
特征对象包括属性、行为和关系等,可以通过UML 等建模工具进行描述和设计。
3. 开发计划:在开发计划阶段,开发团队根据特征的优先级和复杂度,制定开发计划。
计划包括迭代周期、交付物和质量保证等内容,以确保开发过程的可控性和可追溯性。
4. 迭代开发:在迭代开发阶段,开发团队按照计划进行开发工作。
每个迭代都以一个或多个特征为单位进行开发,包括需求分析、设计、编码、测试和集成等活动。
usb 驱动开发原理USB驱动开发原理USB(Universal Serial Bus,通用串行总线)是一种用于连接计算机与外部设备的通信接口标准。
USB驱动开发是为了实现计算机与USB设备之间的数据传输而进行的软件编程。
本文将介绍USB驱动开发的原理和步骤。
一、USB驱动开发的基本原理USB驱动开发的基本原理是通过驱动程序与USB设备之间的通信来实现数据的传输。
USB驱动程序负责管理和控制USB设备,将计算机的请求传递给USB设备,并将USB设备的响应传递给计算机。
USB驱动开发的基本流程如下:1. 初始化USB驱动程序:驱动程序需要初始化USB控制器和USB设备。
这包括初始化数据结构、分配内存空间、设置中断处理程序等操作。
2. 建立通信连接:驱动程序需要与USB设备建立通信连接。
这包括检测和识别USB设备、分配端点和接口、设置传输模式等操作。
3. 数据传输:驱动程序通过读取和写入USB设备的寄存器来实现数据的传输。
这包括发送和接收数据包、处理中断和错误等操作。
4. 终止通信连接:在完成数据传输后,驱动程序需要关闭通信连接。
这包括释放端点和接口、清除中断和错误等操作。
二、USB驱动开发的步骤USB驱动开发的步骤如下:1. 确定USB设备的功能和特性:USB设备可以具有多种功能和特性,例如存储设备、打印机、摄像头等。
驱动程序需要了解USB设备的功能和特性,以便正确地管理和控制USB设备。
2. 编写驱动程序:驱动程序是实现USB驱动开发的核心部分。
驱动程序需要根据USB设备的功能和特性编写相应的代码,以实现数据的传输和设备的控制。
3. 进行调试和测试:在编写驱动程序后,需要进行调试和测试来验证驱动程序的正确性和稳定性。
这包括检查驱动程序的功能、性能和兼容性等方面。
4. 发布和维护驱动程序:在通过调试和测试后,可以将驱动程序发布给用户使用。
同时,还需要对驱动程序进行维护,以修复bug和提升性能。
三、USB驱动开发的挑战和解决方案USB驱动开发面临一些挑战,例如设备的兼容性、驱动程序的稳定性、传输性能的优化等。
软件工程中的模型驱动开发软件工程领域中,模型驱动开发(Model-Driven Development,MDD)是一种以模型为核心的开发方法。
该方法通过将软件系统的不同视图以及各个层次的抽象模型进行统一管理和描述,从而提高开发过程中的效率和可靠性。
本文将介绍模型驱动开发的基本概念、核心原理以及应用情况。
一、基本概念在软件工程中,模型是对软件系统的抽象描述。
模型具有层次性、可扩展性和形式化等特点,是对现实世界或系统的简化和抽象。
模型驱动开发通过建立和维护模型来推动软件开发过程。
1. 模型模型是对系统进行抽象和描述的产物,可以是概念模型、业务模型、数据模型、功能模型等。
模型可以用图形、符号、代码等形式进行表示,其中类图、时序图、活动图、状态图等是常用的建模语言和工具。
2. 驱动驱动是指通过模型推动软件开发过程的过程和手段。
驱动可以是模型转换、代码生成、验证验证等,它们通过自动化工具和技术实现对模型的转换和计算。
二、核心原理模型驱动开发的核心原理是通过对模型的定义、转换和生成来实现软件的开发。
具体来说,模型驱动开发包括模型定义语言(Model Definition Language,MDL)、模型转换技术和模型生成技术。
1. 模型定义语言(MDL)模型定义语言是一种形式化语言,用于描述系统的各个视图和层次的模型。
MDL可以是通用的建模语言,如UML,也可以是领域专用语言(Domain-Specific Language,DSL),如MATLAB、Simulink等。
2. 模型转换技术模型转换是将一个模型转换为另一个模型或者代码的过程。
模型转换技术包括模型变换、模型合成、模型映射等,可以通过模型转换规则和模板来实现。
模型转换技术可以实现模型之间的相互转换和模型到代码的转换。
3. 模型生成技术模型生成是将模型转换为可执行的软件系统的过程。
模型生成技术通过模型到代码的转换,可以自动生成软件系统的源代码、配置文件、数据库脚本等。
测试驱动开发的流程
测试驱动开发是一种软件开发方法论,它的流程可以概括为以下几个步骤:
1. 编写测试用例
在测试驱动开发中,开发人员首先需要编写测试用例,用于描述所需功能的行为和期望结果。
测试用例通常被组织成一个测试套件,每个测试用例都要有一个唯一的标识符。
2. 运行测试用例
开发人员运行测试套件中的所有测试用例,以检查当前代码是否符合预期。
如果有任何测试失败,则意味着当前代码存在问题,需要进行调试或修改。
3. 编写代码
在测试失败的情况下,开发人员需要编写代码来解决问题。
在这个阶段,开发人员需要保持专注于当前测试用例的实现。
4. 运行测试用例
一旦代码被编写,开发人员需要再次运行测试套件中的所有测试用例,以确保新代码的实现符合预期。
如果测试成功,开发人员可以开始下一个测试用例的实现。
如果测试失败,开发人员需要继续修改代码,直到测试成功。
5. 重构代码
在实现和测试一系列测试用例之后,开发人员需要进行代码重构,以确保代码的可维护性和可读性。
重构可以包括代码优化、重构算法
和重构数据结构等。
测试驱动开发的流程强调了测试在软件开发中的重要性,使开发人员更容易编写可靠、可维护的代码。
这种开发方法论在敏捷开发中广泛使用,可以有效提高开发效率和软件质量。
Linux底层驱动开发从入门到精通的学习路线推荐Linux底层驱动开发是一项涉及操作系统核心的技术,对于想要深入了解Linux系统内部工作原理的开发人员来说,是一门重要的技能。
本文将为你推荐一条学习路线,帮助你从入门到精通掌握Linux底层驱动开发。
一、基础知识学习阶段在开始学习Linux底层驱动开发之前,你需要掌握一些基础知识。
以下是你可以参考的学习路线:1.1 Linux操作系统基础学习Linux操作系统的基础知识是理解和使用Linux底层驱动的前提。
可以选择阅读《鸟哥的Linux私房菜》等入门书籍,了解Linux的基本概念、命令行操作等。
1.2 C语言编程C语言是Linux底层驱动开发的主要语言。
建议学习《C Primer Plus》等经典教材,掌握C语言的基本语法和编程技巧。
1.3 Linux系统编程学习Linux系统编程是理解Linux内核和驱动开发的关键。
推荐学习《Linux系统编程手册》等教材,学习Linux系统调用、进程管理等知识。
1.4 数据结构与算法良好的数据结构和算法基础对于优化和设计高效的驱动程序至关重要。
可以学习《算法导论》等经典教材,掌握数据结构和常用算法的原理和实现。
二、Linux内核了解与分析阶段在掌握了基础知识后,你需要进一步了解Linux内核和驱动的工作原理。
以下是你可以参考的学习路线:2.1 Linux内核源码阅读通过阅读Linux内核源码,你可以深入了解Linux的内核机制和实现细节。
可以选择《深入理解Linux内核》等相关书籍,逐步学习Linux内核代码的组织结构和关键部分。
2.2 设备驱动模型了解Linux内核的设备驱动模型对于编写高效且可维护的驱动程序至关重要。
可以学习Linux设备驱动模型的相关文档和教程,例如Linux Device Drivers (LDD)等。
2.3 内核调试与分析工具掌握一些常用的内核调试和分析工具是进行底层驱动开发的必要技能。
RT-Thread之UART设备驱动开发教程(UART)介绍UART(Universal Asynchronous Receiver/Transmit(te)r,通用异步收发传输器)也常被称为串口。
UART作为异步串口(通信)协议的一种,(工作原理)是将传输数据的每个字符一位接一位地传输。
UART是在应用程序开发过程中使用频率最高的数据总线。
在(嵌入式)设计中,UART常用于主机与辅助设备通信,如嵌入式设备与外接模块((Wi-Fi)、(蓝牙)模块等)的通信,嵌入式设备与PC监视器的通信,或用于两个嵌入式设备之间的通信。
UART串口属于字符设备的一种,它的(硬件)连接也比较简单,只要两根传输线就可以实现双向通信:一根线(TX)发送数据,另一根线(RX)接收数据。
UART串口通信有几个重要的参数,分别是波特率、起始位、数据位、停止位和奇偶检验位,对于两个使用UART串口通信的(端口),这些参数必须匹配,否则通信将无法正常完成。
数据格式包含起始位、数据位、奇偶校验位、停止位。
起始位:表示数据传输的开始,电平逻辑为“0”。
数据位:数据位通常为8bit的数据(一个字节),但也可以是其他大小,例如5bit、6bit、7bit,表示传输数据的位数。
奇偶校验位:用于接收方对接收到的数据进行校验,校验一个二进制数中“1”的个数为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性,使用时也可以不需要此位。
停止位:表示一帧数据的结束,电平逻辑为“1”。
波特率:串口通信时的速率,它用单位时间内传输的二进制代码的有效位数来表示,其单位为bit/s。
常见的波特率值有4800、9600、14400、38400、115200等,数值越大数据传输越快,波特率为115200表示每秒传输115200位数据。
UART v2.0版本的UART框架和驱动讲解UART层级结构1)I/O设备管理层向应用层提供rt_device_re(ad)/write等标准(接口),应用层可以通过这些标准接口访问UART设备。
利用windriver开发了个usb的驱动,写个开发心得利用windriver 开发了个usb的驱动,写个开发心得项目组需要利用2440采集数字电视的采样数据,所以让我开发一个usb的数据采集系统,就两个要求1 速度要达到500kbyte/s以上2 稳定由于之前没有做过windows驱动的经验,所以花了3,4天时间读了读ddk的文档,期间还上chinapub找个本书,读了免费的第1章,按照他配置了vc的编译环境,呵呵。
然后就吧ddk下面的bulkusb源代码进行了修改,写好usb device的驱动,有些了个应用程序,测试一下,采集数据是ok了,但是发现有时候蓝屏,特别是采集100m左右,就会出现蓝品!这下没办法了,由于我本身就对windows内核编程不熟悉,有调试了大概3,4天确认问题可能处在电源管理方面,联系到自己对这方面不是很熟悉,而且时间紧迫,没办法转向windriver开发!我安装的是9.21版本(请到迅雷下载)。
1. 驱动的开发:a 这步开发比较简单,首先确认你的device固件正确能枚举成功,然后将device连接到pc usb ho st 端。
b 按照向导指引刷出你的设备进行配置,然后点击编译按钮生成代码。
这部分内容请参考安装文档的快速开发向导!2.应用程序开发:最主要的几个函数是,opendevice 和readwrite 函数:其实大家只要摘录向导生成代码的内容即可,这里贴一个我的static WDU_DRIVER_HANDLE hDriver = 0;static DRIVER_CONTEXT DrvCtx ;static BOOL DLLCALLCONVDeviceAttach(WDU_DEVICE_HANDLE hDevice,WDU_DEVICE *pDeviceInfo, PVOID pUserData){DRIVER_CONTEXT *pDrvCtx = (DRIVER_CONTEXT *)pUserData;DEVICE_CONTEXT *pDevCtx, **ppDevCtx;DWORD dwInterfaceNum = pDeviceInfo->pActiveInterface[0]->pActiveAltSetting->Descript or.bInterf aceNumber;DWORD dwAlternateSetting = pDeviceInfo->pActiveInterface[0]->pActiveAltSetting->Descript or.bAlt ernateSetting;TRACE("\nDeviceAttach: received and accepted attach for vendor id 0x%x, ""product id 0x%x, interface %ld, device handle 0x%p\n",pDeviceInfo->Descriptor.idVendor,pDeviceInfo->Descriptor.idProduct,dwInterfaceNum, hDevice);/* Add our device to the device list */pDevCtx = (DEVICE_CONTEXT *)malloc(sizeof(DEVICE_CONTEXT));if (!pDevCtx){ERR("DeviceAttach: failed allocating memory\n");return FALSE;}BZERO(*pDevCtx);pDevCtx->hDevice = hDevice;pDevCtx->dwInterfaceNum = dwInterfaceNum;pDevCtx->dwVendorId = pDeviceInfo->Descriptor.idVendor;pDevCtx->dwProductId = pDeviceInfo->Descriptor.idProduct;pDevCtx->dwAlternateSetting = dwAlternateSetting;OsMutexLock(pDrvCtx->hMutex);for (ppDevCtx = &pDrvCtx->deviceContextList; *ppDevCtx;ppDevCtx = &((*ppDevCtx)->pNext));*ppDevCtx = pDevCtx;pDrvCtx->dwDeviceCount++;OsMutexUnlock(pDrvCtx->hMutex);OsEventSignal(pDrvCtx->hEvent);/* Accept control over this device */return TRUE;}static VOID DLLCALLCONV DeviceDetach(WDU_DEVICE_HANDLE hDevice, PVOID pUserData) {DRIVER_CONTEXT *pDrvCtx = (DRIVER_CONTEXT *)pUserData;DEVICE_CONTEXT **pCur;DEVICE_CONTEXT *pTmpDev;BOOL bDetachActiveDev = FALSE;TRACE("\nDeviceDetach: received detach for device handle 0x%p\n", hDevice);OsMutexLock(pDrvCtx->hMutex);for (pCur = &pDrvCtx->deviceContextList;*pCur && (*pCur)->hDevice != hDevice;pCur = &((*pCur)->pNext));if (*pCur == pDrvCtx->pActiveDev){pDrvCtx->pActiveDev = NULL;pTmpDev = *pCur;*pCur = pTmpDev->pNext;free(pTmpDev);pDrvCtx->dwDeviceCount--;OsMutexUnlock(pDrvCtx->hMutex);if (bDetachActiveDev){/* When hDeviceUnusedEvent is not signaled, hDevice is possibly in use,* and therefore the detach callback needs to wait on it until it is* certain that it cannot be used.* When it is signaled - hDevice is no longer used. */OsEventWait(pDrvCtx->hDeviceUnusedEvent, INFINITE);}}DWORD DriverInit(WDU_MATCH_TABLE *pMatchTables, DWORD dwNumMatchTables, const PCHAR sDriverName, const PCHAR sLicense, DRIVER_CONTEXT *pDrvCtx) {DWORD dwError;WDU_EVENT_TABLE eventTable;/* Set Driver Name */if (!WD_DriverName(sDriverName))ERR("Error: Could not set driver name to %s, exiting\n",sDriverName);return WD_SYSTEM_INTERNAL_ERROR;}dwError = OsEventCreate(&pDrvCtx->hEvent);if (dwError)ERR("DriverInit: OsEventCreate() failed on event 0x%p: error 0x%lx " "(\"%s\")\n", pDrvCtx->hEvent, dwError, Stat2Str(dwError));return dwError;}dwError = OsMutexCreate(&pDrvCtx->hMutex);if (dwError){ERR("DriverInit: OsMutexCreate() failed on mutex 0x%p: error 0x%lx " "(\"%s\")\n", pDrvCtx->hMutex, dwError, Stat2Str(dwError));return dwError;}dwError = OsEventCreate(&pDrvCtx->hDeviceUnusedEvent);if (dwError){ERR("DriverInit: OsEventCreate() failed on event 0x%p: error 0x%lx " "(\"%s\")\n", pDrvCtx->hDeviceUnusedEvent, dwError, Stat2Str(dwError));return dwError;OsEventSignal(pDrvCtx->hDeviceUnusedEvent);BZERO(eventTable);eventTable.pfDeviceAttach = DeviceAttach;eventTable.pfDeviceDetach = DeviceDetach;eventTable.pUserData = pDrvCtx;dwError = WDU_Init(&hDriver, pMatchTables, dwNumMatchTables, &eventTabl e, sLicense, WD_ACKNOWLEDGE);if (dwError)ERR("DriverInit: failed to initialize USB driver: error 0x%lx ""(\"%s\")\n", dwError, Stat2Str(dwError));return dwError;}return WD_STATUS_SUCCESS;}VOID DriverUninit(DRIVER_CONTEXT *pDrvCtx){DEVICE_CONTEXT *pCur, *pTmpDev;if (pDrvCtx->hEvent)OsEventClose(pDrvCtx->hEvent);if (pDrvCtx->hMutex)OsMutexClose(pDrvCtx->hMutex);if (pDrvCtx->hDeviceUnusedEvent)if (hDriver)WDU_Uninit(hDriver);/* Release any remaining devices */ pCur = pDrvCtx->deviceContextList; while (pCur){pTmpDev = pCur;pCur = pCur->pNext;free(pTmpDev);}}DWORD OpenUsbDevice( void){DWORD dwError;WORD wVendorId = 0;WORD wProductId = 0;WDU_MATCH_TABLE matchTable; BZERO(DrvCtx);wVendorId = USE_DEFAULT;wProductId = USE_DEFAULT;/* use defaults */if (wVendorId == USE_DEFAULT)if (wProductId == USE_DEFAULT)wProductId = DEFAULT_PRODUCT_ID;BZERO(matchTable);matchTable.wVendorId = wVendorId;matchTable.wProductId = wProductId;dwError = DriverInit(&matchTable, 1, DEFAULT_DRIVER_NAME,DEFAULT_LICENSE_STRING, &DrvCtx);if (dwError){goto Exit;}/* Wait for the device to be attached */dwError = OsEventWait(DrvCtx.hEvent, ATTACH_EVENT_TIMEOUT); if (dwError){if (dwError==WD_TIME_OUT_EXPIRED){ERR("Timeout expired for connection with the device.\n""Check that the device is connected and try again.\n");}else{ERR("main: OsEventWait() failed on event 0x%p: error 0x%lx " "(\"%s\")\n", DrvCtx.hEvent, dwError, Stat2Str(dwError));}goto Exit;OsMutexLock(DrvCtx.hMutex);if (!DrvCtx.dwDeviceCount){OsMutexUnlock(DrvCtx.hMutex);return 1;}OsMutexUnlock(DrvCtx.hMutex);if (!DrvCtx.pActiveDev)DrvCtx.pActiveDev = DrvCtx.deviceContextList; OsEventReset(DrvCtx.hDeviceUnusedEvent);return 0 ;Exit:DriverUninit(&DrvCtx);return dwError;}void CloseUsbDevice( void){DriverUninit(&DrvCtx);}DWORD UsbRead(char *pBuffer , DWORD dwBufferSize , PDWORD pdwBytesTransferred){DWORD dwError ;WDU_DEVICE_HANDLE hDevice;OsMutexLock(DrvCtx.hMutex);hDevice = DrvCtx.pActiveDev->hDevice;OsMutexUnlock(DrvCtx.hMutex);dwError = WDU_TransferBulk(hDevice, 0x81,TRUE, 0, pBuffer,dwBufferSize,pdwBytesTransferred, TRANSFER_TIMEOUT);return dwError ;}3.驱动程序的发布:这个也比较简单,请参考自带文档usb manual 的11章节,其实就是用到了他的一个wdreg工具,我写了个批处理文件,想安装的直接点批处理即可!windriver开发驱动是比较方便,至于稳定性,现在正在测试,看来比较稳定!速度方面500kB是没问题!不过速度方面pc驱动固然有影响,device的firmware影响也是很大的,特别是双缓冲的ep,处理不当速度很难上去!。
linux驱动开发流程Linux驱动开发流程。
Linux驱动开发是一项复杂而又重要的工作,它涉及到操作系统内核的底层编程和硬件设备的交互。
在进行Linux驱动开发时,需要按照一定的流程来进行,以确保驱动程序的稳定性和可靠性。
下面将介绍一般的Linux驱动开发流程,希望能够对初学者有所帮助。
1. 硬件设备了解。
在进行Linux驱动开发之前,首先需要对要开发的硬件设备有一个全面的了解。
需要了解硬件设备的型号、接口、工作原理等信息,以便于后续的驱动程序编写和调试工作。
2. 硬件设备驱动框架选择。
针对不同的硬件设备,可以选择不同的驱动框架进行开发。
常用的驱动框架包括字符设备驱动、块设备驱动、网络设备驱动等。
根据硬件设备的特点和需求,选择合适的驱动框架进行开发。
3. 编写驱动程序。
在选择好驱动框架之后,就可以开始编写驱动程序了。
驱动程序是连接硬件设备和操作系统内核的桥梁,需要按照一定的规范和接口来进行编写。
在编写驱动程序时,需要考虑到硬件设备的特性和操作系统的要求,确保驱动程序能够正确地控制硬件设备。
4. 调试和测试。
编写完驱动程序后,需要进行调试和测试工作。
通过调试和测试,可以发现驱动程序中的bug和问题,及时进行修复和优化。
调试和测试是保证驱动程序稳定性和可靠性的重要环节,需要认真对待。
5. 集成到内核。
当驱动程序经过调试和测试后,可以将其集成到Linux内核中。
在将驱动程序集成到内核时,需要按照内核的规范和流程来进行,确保驱动程序能够正确地被内核加载和使用。
6. 发布和维护。
最后,当驱动程序集成到内核后,可以进行发布和维护工作。
发布驱动程序时,需要提供清晰的文档和说明,以便其他开发者能够正确地使用和理解驱动程序。
同时,还需要对驱动程序进行定期的维护和更新,以适应不断变化的硬件设备和内核版本。
总结。
通过以上的介绍,我们可以看到Linux驱动开发流程是一个系统而又复杂的过程。
需要对硬件设备有深入的了解,选择合适的驱动框架,编写稳定可靠的驱动程序,并经过严格的调试和测试,最终将其集成到内核并进行发布和维护。
软件测试中的模型驱动开发方法在软件开发过程中,测试是一个至关重要的环节。
通过对软件进行全面、系统的测试,可以发现潜在的缺陷、提高软件的可靠性和稳定性。
为了更高效地进行测试,软件测试中使用模型驱动开发方法成为了一种常见的做法。
模型驱动开发方法(Model-Driven Development, MDD)是一种基于模型的软件开发方法,它将软件系统建模作为软件开发的核心活动。
通过利用模型在系统开发生命周期中的各个阶段,可以实现自动化的代码生成、规范化的系统设计和快速的原型开发。
软件测试中的模型驱动开发方法则是将MDD应用于测试领域,以实现自动化测试、优化测试效率和提高测试质量。
下面将介绍几种常见的软件测试中使用的模型驱动开发方法。
1. 行为驱动开发(Behavior-Driven Development, BDD)行为驱动开发是一种通过使用自然语言描述系统行为的方法。
在BDD中,测试用例是通过Gherkin语言编写的,该语言可以表达软件系统的行为和验证条件。
通过定义这些行为和验证条件,开发人员和测试人员可以更好地理解软件的需求,并确定相应的测试策略。
2. 数据驱动测试(Data-Driven Testing, DDT)数据驱动测试是一种基于数据的测试方法,在测试过程中使用不同的测试数据来验证软件的功能和性能。
通过将测试数据集中管理,可以减少重复的测试工作,并提高测试的覆盖率。
同时,DDT还可以通过生成大量的测试数据,针对边界条件和异常情况进行测试,以确保软件的鲁棒性和可靠性。
3. 模型驱动的测试(Model-Driven Testing, MDT)模型驱动的测试是一种通过使用模型来生成测试用例的方法。
在MDT中,测试人员可以根据需求和系统模型生成相应的测试用例,并自动生成测试脚本。
这种方法可以大大减少手动编写测试用例的工作量,并提高测试的自动化程度。
同时,使用模型来生成测试用例可以更好地捕捉到系统行为和需求之间的关系,确保测试的全面性和准确性。
业务驱动开发的主要步骤和流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。
文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor. I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!业务驱动开发的主要步骤和流程。
1. 需求收集和分析。
与业务人员和利益相关者进行访谈、研讨会或调查,以收集有关业务需求的信息。
禅思斋试着用参禅的方式去思考驱动开发入门:WDK与VS2010分类: 编程练习 2012-09-17 22:03 188人阅读 评论(0) 收藏举报最近要开始做内核驱动了,现实属入门窥探,今花上一小时搞定了VS2010与WDK的配置,记录如下:1、WDK与VS2010自然要装好啦,似乎学习版的VS2010不行;2、如下增加一个配置方案名Driver3、设置Driver的VC++路径(下图已经显示所有需要配置的目录)4、新建一个cpp后调整C/C++与链接器常规目标文件扩展名:.sys预处理器预处理器定义:WIN32=100;_X86_=1;WINVER=0x501;DBG=1高级调用约定 __stdcall(/Gz)链接器设置常规启用增量链接:否(/INCREMENTAL:NO)输入附加依赖项ntoskrnl.lib;Hal.lib;wdm.lib;wdmsec.lib;wmilib.lib;ndis.lib;MSVCRT. LIB;LIBCMT.LIB忽略所有默认库:是 (/NODEFAULTLIB)清单文件启用用户账户控制(UAC)否系统(System)子系统: 控制台(/SUBSYSTEM:CONSOLE)高级入口点:DriverEntry随机基址:清空数据执行保护(DEP): 清空基址:0x10000测试代码#include "ntddk.h"NTSTATUSDriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath){return STATUS_UNSUCCESSFUL;}1>InitializeBuildStatus:1> 正在创建“Driver\DriverTest.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:1> DriverTest.cpp1>Link:1> DriverTest.vcxproj -> D:\Users\dell\Documents\Visual Studio 2010\Projects\DriverTest\Driver\Drive 1>FinalizeBuildStatus:1> 正在删除文件“Driver\DriverTest.unsuccessfulbuild”。
接触windows驱动开发有一个月了,感觉Windows驱动编程并不像传说中的那么神秘。
为了更好地为以后的学习打下基础,记录下来这些学习心得,也为像跟我一样致力于驱动开发却苦于没有门路的菜鸟朋友们抛个砖,引个玉。
我的开发环境:Windows xp 主机+ VMW ARE虚拟机(windows 2003 server系统)。
编译环境:WinDDK6001.18002。
代码编辑工具:SourceInsight。
IDE:VS2005/VC6.0。
调试工具:WinDBG,DbgView.exe, SRVINSTW.EXE上面所有工具均来自互联网。
对于初学者,DbgView.exe和SRVINSTW.EXE是非常简单有用的两个工具,一定要装上。
前者用于查看日志信息,后者用于加载驱动。
下面从最简单的helloworld说起吧。
Follow me。
驱动程序的入口函数叫做DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegisgryString)。
两个参数,一个是驱动对象,代表该驱动程序;另一个跟注册表相关,是驱动程序在注册表中的服务名,暂时不用管它。
DriverEntry 类似于C语言中的main函数。
它跟main的差别就是,main完全按照顺序调用的方法执行,所有东西都按照程序员预先设定的顺序依次发生;而DriverEntry则有它自己的规则,程序员只需要填写各个子例程,至于何时调用,谁先调,由操作系统决定。
我想这主要是因为驱动偏底层,而底层与硬件打交道,硬件很多都是通过中断来与操作系统通信,中断的话就比较随机了。
但到了上层应用程序,我们是看不到中断的影子的。
说到中断,驱动程序中可以人为添加软中断,__asm int 3或者Int_3();前者是32位操作系统用的,后者是64位用的。
64位驱动不允许内嵌汇编。
下面是我的一个helloworld的源码:注意第16行的宏。
驱动软件开发流程规范Ver.1.1 试行1.1) 2) 3) 4) 5) 6) 7)概述驱动软件开发流程规范(下文简称本规范)的用户: 软件部经理。
软件部开发人员。
软件部项目经理。
技术部经理。
技术部技术支持。
技术部测试人员。
其它一切参与和关注驱动软件开发的人员。
本规范的对象是软件部的驱动软件开发过程。
开发过程涉及的内容包括项目、产品和知识,三者之间 的关系描述如下。
对象项目是一个特殊的将被完成的有限任务,它是在一定时间内,满足一系列特定目标的多项相关工作的 总称。
产品是项目开发输出的结果。
知识是项目开发过程中积累的经验和教训。
在开发过程中,项目被分 为许多小型 Issue(任务、缺陷)分步或并行完成;项目开发输出产品,产品应用的信息作用到项目开发; 项目开发中能提炼知识,知识可应用到项目开发。
2.驱动软件开发管理平台(如何搭建服务器和客户端环境) 驱动软件开发管理平台(如何搭建服务器和客户端环境) 管理平台驱动软件开发管理平台(下文简称本平台)是实施本规范的设备和工具基础,本规范就是为本平台量身打造的。
其物理架构描述如下图,用户应根据下图安装相应的软件:反馈提炼应用 输出上图中的模块描述如下: 模块类型 模块 服务器计算机 Windows 操作系统、 其它支撑软件 服务器,IP:201.123.123.200 Windows 操作系统:Windows2003 JAVA 环境:jdk-1_5_0_08-windows-i586-p.exe 数据库:mysql-5.0.27-win32.zip SVN 是 Subversion 的缩写,SVN 是比 VSS 和 CVS 功能更加强大 SVN Server 的文件版本控制工具, SVN 可理解为 CS 结构。
SVN Server 即 SVN 的服务端,与 SVN Client 共一个安装程序:Subversion 1.4.0,安 装后自带命令行工具 Tortoise SVN 构建于 SVN 之上,是 SVN 的图像化界面工具,基本 Tortoise SVN 服务器端 产品 上可以替代 SVN 的自带命令行工具。
目录热身阶段 (2)问1:什么是过滤驱动?(2009-4-15) (2)问2:什么是IRP?(2009-4-15) (3)问3:驱动栈,设备栈?(2009-4-15) (6)问4:文件系统过滤驱动(FSFD)为什么能过滤文件系统(FSD)?(2009-4-16) (8)问5:怎么用好DDK(或WDK,现在起本书只说WDK)?(2009-4-16) (11)Legacy驱动阶段 (12)问6:DriverEntry和DriverUnload是干嘛的?(2009-04-20) (12)问7:SfCreate(2009-04-20) (12)问8:SfDisplayCreateFileName(2009-04-23) (14)问9:fastio系列例程(2009-04-28) (15)问10:总结sfilter(2009-04-28) (25)问11:fspyKern.h、fspydef.h和filespy.h(2009-04-28) (26)问12:fspyHash.c(2009-04-28) (27)问13:上下文(2009-04-30) (34)问14:fspyCtx.c(2009-04-28) (39)问15:FspyLib.c(2009-04-28) (49)问16:总结filespy(2009-04-30) (64)问17:legacy驱动透明加解密设计开发示例(2009-04-30) (64)概要设计 (64)定位机制设计 (66)跟踪机制设计 (66)加解密模块设计 (68)其他设计 (68)问18:总结legacy驱动(2009-05-04) (70)Mini驱动阶段 (71)问19:passThrough(2009-05-04) (71)问20:ctx(2009-05-04) (72)问21:scanner(2009-05-05) (75)问22:swapBuffers(2009-05-05) (78)问23:总结mini驱动(2009-05-05) (78)问24:fastfat(2009-05-05) (79)后记 ................................................................................................................ 错误!未定义书签。
热身阶段问1:什么是过滤驱动?(2009-4-15)经历过驱动开发之后,给我最大的一个认识就是:这里所谓的驱动和没有接触它之前所臆想的驱动有很大的不同。
我们最早入手的资料是楚狂人的《Windows 文件系统过滤驱动开发教程(第二版)》和toolflat公开的Sfilter Rc4加解密源码。
由于legacy源码动辄几千行,而且没有理论基础显得艰涩难懂。
因此我们决定先研究开发教程(这一问中涉及的IRP和IRP_MJ_XXX的概念第2问会讲到)。
这本书主要是依照DDK中sfilter的例子,逐步引入文件系统过滤驱动中的基本概念和基本方法,这可以以一种简单的方式尽快让你了解驱动。
不同环境下的文件名格式其他资料上都讲解得比较详细,这里不再讨论。
部分解析下《Windows 文件系统过滤驱动开发教程(第二版)》●第一章实用的东西不多,但对过滤驱动是做什么的、怎么做有一个简要的描述●第二章主要是驱动入口DirverEntry例程及各种对象。
总的来说,DriverEntry例程代码的各个部分都是既定的,需要修改的只是部分变量和参数。
本章需要注意的问题点是驱动中的各种对象。
DirverObject代表这个驱动实例,它有一组函数指针即dispatch函数的函数指针。
这些函数类似于MFC中对应某个消息的处理函数,它们分别用于处理各自对应的IRP请求。
举例来说(以sfilter为例):SfCreate对应IRP_MJ_CREATE即驱动只要收到MajorFunctionCode为IRP_MJ_CREATE的IRP就交给SfCreate例程处理。
编写一个驱动的主要任务也就是确定要处理哪些IRP_MJ_XXX的IRP,然后编写相应的处理例程。
CDO(控制设备对象)和DO(设备对象)比较好区分:首先,每个驱动只对应一个CDO,而可以有多个DO;CDO无设备扩展,DO有设备扩展;CDO的主要任务是作为某个操作(一般都是用户自定义的IOCTL等)的目标,用于修改整个驱动的内部配置,而DO是驱动对应某个卷生成的,只有以它为目标的IRP才会被生成这个DO的驱动处理(这也与驱动栈的概念关联紧密,后面详述)。
再来看本章给出的DriverEntry例程代码片段,主要目的是生成CDO。
这里主要有三个点:1、UNICODE_STRTING的使用,参考《驱动开发基础教程》;2、可用函数的调用。
需要说明的是由于驱动是由C语言编写的,因此大部分C运行时函数都可以用于驱动编程,但直接使用C运行时库有许多风险,推荐能使用DDK封装好的函数就尽量多用封装好的,除非你愿意自己做繁琐的版本移植和维护;3、对某个函数调用所产生的各种结果都要处理到位。
假如在用户模式下调用某函数不考虑其失败的情况,后面的程序要用到该函数返回的某个值(失败时该值无效)时就会发生错误,严重点也就程序运行时出错被迫终止并弹出一个相对友好的报错对话框。
在内核模式下的编程,假如有异常或错误没有及时处理,一般都会引起bugcheck,现象就是蓝屏。
本例只区分了成功或失败两种状态,在特殊场合,指定的函数调用的状态可能需要分很多种做相应处理。
●第三章和第3.5章主要讲了分发例程(dispatch routine)和fastio这两种方式。
两种方式都不是小问题,后面会专门分别讲,这里只简述。
先说说分发例程。
在legacy驱动模型中,你必须对所有类型的请求都做处理,而不管你需不需要过滤它。
因而有些IRP_MJ_XXX类型的IRP你只需要把它传给驱动栈中在你之下的驱动。
既然处理方式一样,为了避免重复编码的无用功,就需要一个通用的“下传”例程,即例中的SfPassThrough。
它没什么可说的,就只是负责下传当前的IRP。
那些需要处理的IRP类型,就得按照例子中的示范给出对应的分发例程,如DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;这样只要驱动接收到IRP_MJ_CREATE类型的IRP就会把它交给SfCreate例程处理。
断言的用法与用户模式对应,不再赘述。
这里可以形象地认为邮局(驱动)收到邮件(IRP),邮局根据邮件上收信人的邮编和地址(MajorFunction和MinorFunction),把邮件交给收信人(SfCreate)做处理。
这里只是比喻,IRP最终的“收件人”并不一定是当前这个过滤驱动的分发例程。
Fastio是cache调用引发的,且没有IRP。
你可以认为fastio操作的数据一定是在缓存中。
也就是说,用户模式下各种IO到内核模式下只走两天路线:IRP和fastio。
假如你只关心磁盘里的数据,那fastio就没什么意义。
关于其中出现的内存申请方面的技巧后面会详述。
提到的两种锁在后来对某些数据结构的操作中会经常碰到。
初期只需要知道。
●后面几章操作和编程方面,就示范目的而言讲解地比较详细,其中出现的很多概念和方法还需专门开问讨论,也不推荐过早考虑实际开发。
暂时要接受和理解这本书中提到的基本理论已经不容易了。
关于sfilter等源码需要另开题目讨论。
总结:一个驱动(以sfilter为例,这里要解释以sfilter为例的原因:它的数据结构和功能都相对简单,可参考的资料相对较多)主要组成部分有:数据结构、DriverEntry例程及其他各种例程。
它可以对自己所绑定的卷上的IO进行相应处理。
这就是实际编程中你看到的驱动。
NTFSI中过滤驱动的定义为:一个拦截到一些已有软件模块的请求的中间层驱动。
依靠在请求到达目标前截获请求,过滤驱动就有机会扩展或修改请求的原始接收者所提供的功能或服务。
比照上一段来理解,驱动这个概念就没有那么空了。
这里只是帮助你尽量块地融入到驱动的开发环境中。
不要只看某一份资料,偏执一处只会令你由无知变为“误知”。
文件系统过滤驱动为什么能起到过滤文件系统的作用就需要有一定的知识基础才好理解了。
暂时略。
问2:什么是IRP?(2009-4-15)问1和许多资料及网页都不断地提及IRP这个名词,对于刚接触驱动的人来说这玩意儿是陌生的,但在将来的学习和开发过程中它是一个关键性的基本概念之一。
MS在DDK 中解释了IRP及其结构,但有所保留。
下面用到的驱动栈概念会在问3中详述。
NT用一个基于包的结构来描述I/O请求。
即任何一个I/O请求都能用一个单一的I/O 请求包也就是IRP来描述。
当发出一个I/O系统服务时(比如创建文件或读文件的请求),I/O管理器就会通过构造一个描述此请求的IRP 并把该IRP 的一个指针传给设备驱动来开始对这个请求的处理。
假如OS 想向I/O 管理器和设备驱动完整地描述一个I/O 请求,那么IRP 中保存的信息就可以达到这个目的。
如下图,IRP 可以认为是由两个部分组成的:一个"固定"部分和一个I/O 栈。
固定部分包含这个请求的相关信息,有可能不同驱动中的IRP 的固定部分相同,也可能在不同驱动间传递IRP 时不需要关注它。
假如某个驱动要处理这个IRP ,那么I/O 栈就包含被指定给它的信息。
驱动栈中有几个要处理这个IRP 的驱动,那么I/O 栈中将至少有几个I/O 栈位置。
为避免每一个IRP 都要从NT 的非分页池中分配,I/O 管理器维护一对保存有预分配的IRP 的旁观列表(lookaside list ,其相关知识会专门加以讨论)。
NT V4.0中,其中一个旁观列表保存带有一个单一I/O 栈位置的IRP 。
另外一个旁观列表保存带有三个I/O 栈位置的IRP 。
I/O 管理器总是尽可能地使用这些旁观列表中的IRP 。
因此,只有没有可用的IRP ,或者要分配的IRP 所需的I/O 栈位置超过三个时,I/O 管理器才会从非分页池中分配IRP(关于内存分配的问题会专门讨论)。
否则,它会尽量使用旁观列表中的IRP 。
MdlAddressFlagsAssociateIrp.MasterIrpAssociateIrp.SystemBufferIoStatusRequestModeCancelCancelIrqlCancelRoutineUserBuffer Tail.Overlay.Thread Tail.Overlay.ListEntry I/O Stack Location3I/O Stack Location2I/O Stack Location1IRPMajorFunctionMinorFunctionFlagsControlParametersDeviceObjectFileObjectI/O 栈位置IRP 固定部分IRP 结构示意图IRP 中的I/O 栈IRP 的固定部分中需要特别关注或有用的域如下:MdlAddres, UserBuffer 和AssociatedIrp.SystemBuffer – 如果有一个关联I/O 操作请求者的数据buffer ,则这三个域被用来描述这个buffer 。