首页 > 文章中心 > 驱动程序设计

驱动程序设计

前言:想要写出一篇令人眼前一亮的文章吗?我们特意为您整理了5篇驱动程序设计范文,相信会为您的写作带来帮助,发现更多的写作思路和灵感。

驱动程序设计

驱动程序设计范文第1篇

关键词:WDF PCI 中断 驱动程序 同步时钟卡

中图分类号:TP336 文献标识码:A 文章编号:1007-9416(2015)05-0000-00

Abstract:This paper introduces the design of Device Drivers of PCI synchronous clock card based on WDF model. Briefly introduces the system architecture and works on our own PCI synchronous clock card, and Analysis the framework of the WDF model and the design process. Focused on the research and development of the WDF Device Drivers based on the PCI synchronous clock card, including hardware access, Interrupt notification. The driver has passed the test for stability and reliability.

Key words: WDF; PCI; interrupt; driver; synchronous clock card.

时间是科学实验、科学研究和工程技术等领域中的一个基本物理参量。为了保证系统各部分时间的一致性和正确性,系统内各设备的同步时钟从卡从时钟源获取高精度的标准时间,提供给相应设备。这样系统内各设备的时间与时间源相同而保持一致。同步时钟卡一般采用PCI总线方式。PCI总线能够实现设备间的快速访问,它以突出的性能受到计算机和通信界工程师们的青睐。

因此如何开发出稳定、可靠、高效的PCI设备驱动程序成为驱动工程师们面临的一个棘手的问题[5]。过去对于PCI设备驱动程序的开发大多采用WDM(Windows Driver Model)框架,但是它编程比较复杂,快速掌握其开发要领对于初学者来说比较困难[5]。本文所述的PCI同步时钟卡的驱动程序的开发采用微软最新推出的WDF(Windows Driver Foundation)驱动模型。WDF驱动模型提供事件驱动和面向对象的驱动程序开发框架,大大降低了设备驱动程序的开发难度[5]。

1 同步时钟卡系统架构

本文所述的驱动程序是基于自行研发的PCI同步时钟卡,其原理框图如图1所示。本同步时钟卡选择PCI9052芯片做为PCI总线的接口芯片。该电路除了用到PCI9052外,还用到了单片机、EEPROM、双口RAM、CPLD。单片机是系统的控制单元;串行EEPROM存储了PCI9052芯片所需要的配置信息;双口RAM用于PC机与时钟卡之间交换数据;CPLD用于200us时标的产生和中断的控制。

同步时钟卡的工作流程如下:同步时钟从卡接收时钟源输出的时间信号,单片机将其解析成高精度的同步时间信息,控制逻辑(CPLD)通过1PPS脉冲信号产生200us的高精度时间刻度,于是产生高精度的同步绝对时标,连续存储于双口RAM中,最后计算机通过PCI总线接口获取高精度的绝对时间。本系统中计算机获取双口RAM中的时间数据的方式有两种:(1)PC机主动读取双口RAM中的数据。(2)外部事件通过中断通知PC机事件发生,PC机收到通知后读取双口RAM中的时间信息,可获得外部事件发生的精确时刻。两种方式分别涉及驱动程序的硬件访问和中断通知。于是涉及到本文介绍的重点:基于WDF模型的PCI总线驱动程序的开发。

2 WDF驱动程序设计

微软对过去的WDM(Windows Driver Model)驱动程序的架构做了改进,形成了全新的WDF(Windows Driver Foundation)框架结构。它将原来普通软件开发中面向对象的技术应用到了驱动程序的开发中。WDF改变了驱动程序与操作系统内核之间的关系,在传统的WDM驱动程序中,不仅要处理硬件,还要处理驱动程序与操作系统内核之间的交互[4]。现在WDF则使驱动程序与操作系统内核独立开来,驱动程序与操作系统交互工作将由框架内封装的方法(函数)去完成,这样驱动开发工程师只需专注处理目标硬件的行为即可,避免了两面不周顾此失彼的弊端。不仅大大降低了驱动程序的代码量,还使整个系统更加稳定、可靠。

WDF驱动程序包括两个类型,一个是内核级的,称为KMDF(Kernel-Mode Driver Framework);另一个是用户级的,称为UMDF(User-Mode Driver Framework)。本文所述的驱动程序采用KMDF模式。

2.1 WDF驱动程序开发流程

本文所用开发环境为Microsoft Windows Driver Kit(WDK) 8.1和Microsoft Visual Studio 2013,操作系统为Windows7。先安装VS2013,再安装WDK8.1,便可在VS2013中直接创建KMDF工程。根据同步时钟卡所需功能编写好驱动程序即可进行编译。

WDF驱动程序框图如图2所示。

2.2 基于WDF模型的PCI设备驱动程序的实现

WDF模型的设备驱动程序从功能上可分为三个部分:初始化设备、控制设置与交换数据[3]。初始化设备主要实现设备的识别、驱动对象与设备对象的建立与硬件资源的分配;控制设置负责应用程序与驱动程序的连接和设备的打开;交换数据处理的是设备功能的具体应用,即PCI总线与同步时钟卡之间的数据传输。

从本质上来说,WDF模型的设备驱动程序是由入口函数DriverEntry和事件例程及其子函数组成的[3]。操作系统在第一次加载驱动程序时会通过调用DriverEntry例程来完成设备驱动程序和框架的初始化[3]。所有的驱动程序都必须包含一个DriverEntry例程。对于不同类型的驱动程序其入口函数DriverEntry也不同,可分为:设备驱动、纯软件驱动与过滤驱动。本文所述的PCI总线驱动程序属于设备驱动,在入口函数DriverEntry中,主要完成两件事:注册EvtDriverDeviceAdd回调例程、创建和初始化WDFDRIVER对象。

WDF_DRIVER_CONFIG_INIT(&config,PCIdriverEvtDeviceAdd);

//注册EvtDriverDeviceAdd回调例程

status = WdfDriverCreate(DriverObject, RegistryPath,...);

//创建驱动对象

2.2.1初始化设备

在驱动程序被成功初始化完成之后,操作系统会顺序调用EvtDriverDeviceAdd、EvtDevicePrepareHardware等回调例程以实现所控制的设备的初始化。

当首次枚举设备时,EvtDriverDeviceAdd例程在系统初始化时被PnP管理器调用。在系统运行过程中,任何时候一个新的相同设备被枚举,系统都将调用此例程。EvtDriverDeviceAdd例程是设备初始化过程中最新被调用的回调例程,它需要完成:设备对象的创建,创建符号链接或设备对象GUID接口,创建一个或多个I/O队列,各种事件的回调函数的注册,如即插即用、电源管理、I/O处理例程等[1]。

EvtDriverDeviceAdd例程的主要代码如下所示:

注册即插即用基本例程:

WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

pnpPowerCallbacks.EvtDevicePrepareHardware = PCIDriverEvtDevicePrepareHardware;

pnpPowerCallbacks.EvtDeviceReleaseHardware = PCIDriverEvtDeviceReleaseHardware;

..........

WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

创建设备对象:

WDF_FILEOBJECT_CONFIG_INIT(&f_config,...);

WdfDeviceInitSetFileObjectConfig(DeviceInit, &f_config,WDF_NO_OBJECT_ATTRIBUTES);

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, ..);

status = WdfDeviceCreate(&DeviceInit, &attributes, &control_device);

创建队列对象并注册回调例程:

WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,....);

ioQueueConfig.EvtIoDeviceControl = PCIdriverEvtIoDeviceControl;

ioQueueConfig.EvtIoStop = PCIdriverEvtIoStop;

status = WdfIoQueueCreate(control_device,&ioQueueConfig,...);

创建符号链接:

status = WdfDeviceCreateSymbolicLink(control_device, &ustring);

创建中断对象:

deviceContext = GetDeviceContext(control_device);

WDF_INTERRUPT_CONFIG_INIT(&interruptConfig,PCIDriverEvtInterruptIsr,

PCIDriverEvtInterruptDpc);//设置中断服务例程和延迟过程调用WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&interruptAttributes,..);

status = WdfInterruptCreate(control_device,&interruptConfig,

&interruptAttributes,&deviceContext->Interrupt);

EvtDriverDeviceAdd例程调用完成之后,系统将调用EvtDevicePrepareHardware例程初始化地址指针,将设备所占用的I/O地址和内存地址映射为虚拟地址,驱动程序将通过这些虚拟地址完成与设备的数据传输。由于串行EEPROM存储了PCI9052芯片所需要的配置信息,系统将自动为本文所述的PCI同步时钟卡分配资源,它们包括双口RAM的内存地址、PCI9052的I/O地址空间,所以EvtDevicePrepareHardware例程必须将这些资源映射为虚拟地址。对于I/O端口,只需将首地址与地址数目值保存在设备上下文;对于存储器芯片,调用MmMapIoSpace函数将物理地址映射为系统内核虚拟地址,然后保存于设备上下文。相对应的,当设备被卸载时,系统会自动调用EvtDeviceReleaseHardware回调例程释放之前申请的硬件资源。

for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++) {//WdfCmResourceListGetDescriptor函数获取该资源的描述符

descri = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);

switch (descri->Type)

{case CmResourceTypeMemory:

Mem_Count++;

if (Mem_Count == 2)//将双口RAM地址映射为虚拟地址

{pDevice_context->MemBaseAddress = MmMapIoSpace(

descri->u.Memory.Start,

descri->u.Memory.Length,

MmNonCached);

pDevice_context->MemLength = descri->u.Memory.Length;}

break;

case CmResourceTypePort://将PCI9052的I/O地址映射为虚拟地址

pDevice_context->Io_baseAddress = descri->u.Port.Start.LowPart;

pDevice_context->Io_length = descri->u.Port.Length;

default:

break;}}

2.2.2控制设置与数据交换

应用程序实现和驱动程序通信的过程是:应用程序首先调用CreateFile函数打开设备,然后可以使用DeviceIoControl和驱动程序通信,包括写数据给驱动程序和从驱动程序读数据两种情况,也可以用WriteFile写数据给驱动程序或用ReadFile从驱动程序读数据,当应用程序退出时,调用用CloseHandle关闭设备。本文所述的系统是用DeviceIoControl和驱动程序通信。CreateFile打开设备的方式有两种:符号链接名与GUID接口,本文所述驱动程序采用的是符号链接名的方式。

m_hDevice=CreateFile(sLinkName,...);//以符号链接名的方式打开设备

上述代码中sLinkName为符号链接名,它与驱动程序中设置的符号链接名相同。m_hDevice为返回的设备的有效句柄,应用程序就可以应用它调用DeviceIoControl函数与驱动程序交换数据。应用程序的请求会被放入请求队列中,并在EvtIoDeviceControl函数之中被处理。

本文中应用程序获取时钟卡上的时间信息的方式有两种:(1)直接读取。(2)中断方式。

对于第一种方式,应用程序直接调用DeviceIoControl函数与驱动程序交换数据。由于系统的双口RAM被映射到虚拟内存,驱动程序可以使用下面两条指令对双口RAM进行读写: READ_REGISTER_XXX;//读双口RAM,WRITE_REGISTER_XXX;//写双口RAM。

对于中断方式,当被捕获的外部事件发生时,驱动程序会进入中断服务例程EvtInterruptIsr,然后进入延时过程调用EvtInterruptDpc,首先清中断源,然后将双口RAM中的时间数据读取到设备上下文中缓存,该数据即为外部事件发生的时间,最后通知应用程序读取该数据。应用程序将调用DeviceIoControl函数获取设备上下文中的时间信息。驱动程序与应用程序通信的方法有两种:DeviceIoControl异步完成和WIN32事件通知。本文所述系统采用WIN32事件通知的方法。对于此种方法,应用程序初始化时首先生成一个通知事件,并通过DeviceIoControl函数的输入缓冲区发送给驱动程序,驱动程序创建相应的内核事件,同时使能PCI9052的LINT1中断,当该事件发生时,驱动程序会通知应用程序,应用程序的一个子线程不停的循环等待驱动程序发来的事件发生通知。当设备被卸载时需要撤销该内核事件。具体主要代码如下:

应用程序生成通知事件:

mhEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

应用程序子线程中等待事件发生:

while (WaitForSingleObject(mhEvent, 0) != WAIT_OBJECT_0)

{...}

驱动程序创建相应的内核事件:

ObReferenceObjectByHandle(....);

允许PCI中断,使能PCI9052的本地LINT1中断,pREG为PCI9052映射的I/O空间的基 地址:

inter = READ_PORT_USHORT(pREG + 0x4c);

inter |=0x43;

WRITE_PORT_USHORT(pREG + 0x4c, inter);

清中断源,设置PCI9052的CS3引脚有效,通知CPLD清掉LINT1信号:

inter = READ_PORT_USHORT(pREG + 0x50);

inter |= 0x800;

WRITE_PORT_USHORT(pREG + 0x50, inter);

驱动程序给应用程序发送事件,通知应用程序读取数据:

KeSetEvent(pDevice_context->Event, 0, FALSE);

驱动程序内撤销内核事件:

ObDereferenceObject(...);

3 结语

驱动程序是硬件与应用程序通信的桥梁,它对系统性能提升的作用举足轻重。高效、稳定、可靠的驱动程序可以使系统性能得到很好的提升。

本文简要介绍了PCI同步时钟从卡的工作原理,并重点讨论了基于WDF模型的PCI设备驱动程序设计方法。本文所述的PCI同步时钟卡驱动程序,在WDK8.1中成功编译,自动生成SYS文件(驱动程序代码)和INF文件(设备安装信息),成功安装并且能够稳定可靠地运行。经测试,捕获的时间精度达到误差小于200us,满足系统设计要求。涉及本驱动程序的系统已应用于三峡大坝左岸发电厂发变机组的故障录波系统中,运行稳定可靠。总而言之,WDF驱动模型优化并简化了设备驱动程序的开发,比传统的WDM驱动模型更加稳定。

参考文献

[1]武安河.Windows设备驱动程序WDF开发[M].北京:电子工业出版社,2009.

[2][美]Ronald D. Reeves 著,张猛等 译.Windows设备驱动程序开发[M].北京:人民邮电出版社,2012.

[3]黎顺杰,张艳荣.基于WDF的PCI-CAN设备驱动程序设计[J].电子测试,2013;5:20-21.

驱动程序设计范文第2篇

【关键词】USB 设备驱动 Linux

1 USB总线原理

USB 协议是1994年底由康柏、IBM、英特尔等几家公司联合提出来的外部总线接口协议。USB就是英文中Universal Serial Bus(通用串行总线)的缩写。USB总线具有其他总线所不具备的如:热插拔、数据传输可靠、扩展方便、成本低等一系列特点,因此在嵌入式系统中被广泛使用。

一个USB系统一般是由一个USB主机控制器、一个或多个USB集线器和一个或多个USB设备节点组成。USB系统的物理连接具有层次性。USB总线连接USB设备和USB主机,是一种星型拓扑结构。USB的拓扑结构如图1所示。

在一个USB系统传输数据的过程中有两个非常重要的概念,就是USB传输模式和USB描述符。USB传输模式是指USB设备传输数据的形式。USB设备支持四种传输模式:控制传输模式、同步传输模式、中断传输模式和批量传输模式。控制传输模式是用来处理USB主端口到USB从端口的数据传输,主要是设备控制指令、设备查询状态指令和确认指令。同步传输模式是指传输和时间关系密切的信息所使用的一种传输方式,是一种周期的、连续的单向传输方式。中断传输模式这类传输模式主要用于传输非周期性的、自然发生的、数据量很小的信息,这类数据传输的方向是从设备到主机,适用于键盘、鼠标、操纵杆等设备上。最后一种是批量传输模式,该模式适用于大量的、对时间没有要求的数据传输,如U盘或者移动硬盘等设备。

USB设备在逻辑上分为几个层次,分别是设备层(Device)、配置层(Config)、接口层(Interface)、端点层(Endpoint)。各个层次都有与之相对的描述符,分别是设备描述符、配置描述符、接口描述符和端点描述符。

2 Linux下的USB驱动框架

USB设备的设备描述符在Linux系统中用usb_device_descriptor结构体表示,它描述了USB设备的一般信息。配置描述符用usb_config_descriptor结构体表示,它给出了USB设备的配置信息。接口驱动程序是在一个配置内给出一个接口信息,它在Linux中由usb_interface_descriptor结构体表示。端口描述符被主机用来决定每个端口的带宽需求,它在Linux系统中由usb_endpoint_descriptor结构体表示。

编写一个USB驱动程序,是从usb_driver结构体开始的。Linux中模块加载函数调用usb_register()和usb_unregister()从而对usb_driver结构体进行加载与卸载。如果某个设备信息与该驱动中usb_device_id usb_mouse_id_table 结构体的信息相一致,则会调用usb_driver中探测成员函数probe(),将初始化USB断点信息,并对设备做一些初始化工作,分配urb结构体,准备数据传输。其urb处理大致框架结构如图2所示。

当鼠标设备在用户空间打开时,将提交 probe 函数构建的 urb 请求块,urb 将开始为传送数据而忙碌了。urb 请求块就像一个装东西的“袋子”,USB 驱动程序把“空袋子”提交给 USB core,然后再交给主控制器,主控制器把数据放入这个“袋子”后再将装满数据的“袋子”通过 USB core 交还给 USB 驱动程序,这样一次数据传输就完成了。

3 结束语

由于USB简单方便快捷等优点,许多外接设备会越来越青睐USB接口,这是一种发展的趋势。Linux系统具有开源、安全等特性,用户也在急剧增加。届时,会有越来越多的USB驱动加入Linux内核之中。

参考文献

[1]Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman等.LINUX设备驱动程序[M].北京:中国电力出版社,2006.

[2]Universal Serial Bus Specification Compaq,Intel,Mi―crosoft,NEC Revision 1.1.September 23,1998.

[3]温卡特斯瓦兰.精通Linux驱动程序开发[M].北京:人民邮电出版,2009.

[4]胡晓军,张爱成.USB接口卡发技术[M].西安:西安电子科技大学出社,2005:15-17.

作者简介

徐海林(1989-),男,江苏省南通市人。现为安徽理工大学计算机科学与工程学院学生。

驱动程序设计范文第3篇

第一节windows nt网络结构

§1.1.1 windows nt网络体系结构

windows nt的网络体系结构是基于国际标准化(iso)制定的标准模型──开放式系统互连(open system interconnection:osi)参考模型分层建立的,这种方式有利于随时扩展其它功能和服务。

windows nt网络模型开始于mac子层,网卡驱动程序就驻留在其中。它通过相关的网卡把windows nt与网络连接起来,图中的多个网卡表明在一台运行windows nt的计算机上能使用多种网卡。

这一网络体系结构包括两个重要接口──ndis接口与传输驱动

程序接口(tdi)。这两个接口把两个层隔离开来,办法是相邻的部件只允许按单一的标准来写,不允许多重标准。例如一个网卡驱动程序(在ndis接口的下面)就不需要特地按每个传输协议来写它的代码块,恰恰相反,该驱动程序是写给ndis接口的,它通过符合ndis的相应传输协议来请求服务。这些接口包含在windows nt的网络体系结构中,以容纳可移植、可互换的模块。

在两个接口之间,是传输协议。它在网络中起着组织者的作用。一个传输协议规定了数据以何种方式呈递给下一个接收层,以及如何对数据相应地进行打包。它通过ndis把数据传给网卡驱动程序,并通过tdi把数据传给转发程序(redirector)

tdi之上是转发程序,它把本地的网络资源申请转送给网络。

为了能和其他厂商的网络互连,windows nt允许有多个转发程序。对于每一个转发程序windows nt计算机必须也有一个相应的供应者(provider)(由网络厂商提供)。多供应者路由选择程序决定适当的供应者,然后借助于供应者,对应用请求到相应的转发程序做出选择。windows nt支持两种类型的网络驱动程序

传输驱动程序

实现数据链路层中的逻辑链路控制子层协议和传输层协议。向 下与ndis接口,向上与tdi接口。

网卡驱动程序

实现对物理层的管理和数据链路层中介质访问控制子层协议,通过ndis向下管理物理网卡,向上与传输驱动程序通信。

§1.1.3 windows nt网卡驱动程序

windows nt环境下的网卡驱动程序也分为两种:

miniport网卡驱动程序:miniport驱动程序只须实现与网络硬件相关的操作(包括发送和接收)。而所有底层网卡驱动程序的通用操作(如同步),一般由ndis接口程序来实现。

full网卡驱动程序:full网卡驱动程序必须实现所有硬件相关和同步、排队等操作。例如full网卡驱动程序为了响应数据接收,需要保持本身的捆绑信息,而miniport就可以由ndis接口库来实现。

在windows nt的早期版本中,full网卡驱动程序要求开发者实现许多底层操作,来处理多处理器的核心问题以及处理器、线程的同步,这样不同的开发者在大量重复着许多相同的工作。

而miniport网卡驱动程序允许开发者仅仅写一些与网络硬件相关的代码即可,而那些通用的函数由ndis接口库来实现,这样开发出来的驱动程序减少了不必要的工作。

第二节miniport驱动程序的结构

ndis接口规范了网卡驱动程序的实现,同时也对tdi驱动程序的实现提出了一定的要求,在nt中,ndis约束下的网卡驱动程序、tdi驱动程序和系统的关系如下图所示:

图2.0 ndis约束下的网卡驱动程序、tdi驱动程序和系统的关系

miniport驱动程序包括驱动程序对象、驱动程序源代码和ndis接口库代码。windows nt ddk提供ndis.h作为miniport驱动程序的主要头文件,定义了miniport驱动程序的入口点、ndis接口库函数和通用数据结构。

上边缘函数的作用是网卡驱动与ndis接口库进行通信,而下边缘函数是tdi协议驱动程序与ndis通信的手段。ndis用一个叫做逻辑网卡的软件对象来描述系统中的每块网卡,而逻辑网卡与windows nt设备对象的通信由i/o子系统来管理,描述网卡的设备对象包括相关的网络信息如名字、网络地址和网卡内存基地址等,它还包含与硬件相关的驱动程序状态数据(捆绑数目,捆绑句柄,包过滤数据库等)。ndis分配一个句柄到miniportinitialize这个上边缘函数的一个结构中,然后miniport网卡驱动程序将在以后提供这个句柄来给ndis调用,这个结构一直被ndis保持,并且对miniport驱动程序不透明。 当miniport网卡驱动程序初始化一块网卡时,它创立自己的内部数据结构来描述网卡,记录需要它管理的与设备相关的状态信息。当miniport网卡驱动程序调用ndismsetatttibutes或ndismsetattributesex两ndis库函数时,它传递一个句柄给这数据结构。这样,当调用miniport驱动程序入口点时,它就传递这个句柄来验证驱动程序所对应的网卡的正确性。这个数据结构为miniport网卡驱动程序所拥有并维护。miniport nic驱动程序还需要维护一组对象,这些对象是系统定义的对象标识符(object idetifier:oid)来标识,以描述驱动程序的性能和当前状态信息。为查询这些信息,上层驱动程序调用ndisrequest向ndis接口库指示oid。oid表示了调用所需的信息类型,如miniport驱动程序所支持的lookahead缓冲区大小等。ndis接到上层驱动程序的查询请求,将oid传递给上边缘函数miniportqueryinformation实现对oid的查询,如果上层驱动程序请求改变状态信息则调用miniportsetinformation实现对oid的设置。典型的miniport nic驱动程序必须有一些函数来通过ndis接口实现上层驱动程序与硬件的通信。这些函数称为上边缘服务函数。

这些上边缘服务函数由驱动程序的开发者根据驱动程序面向的特定低层网络类型和硬件以及相应环境,可以有选择地实现,但必须保证驱动程序最基本的功能,这些基本功能包括初始化、发送、中断处理、重置、参数查询与设置和报文接收。

miniportinitialize:操作系统根据系统配置信息,检测出网卡已安装时,由ndis接口在初始化时调用,主要完成低层网络类型确定,对应于物理网卡的逻辑网卡初始化,中断信息注册,网卡与主机通讯方式的确认。i/o端口的申请与注册,内存映像,mib的初始化,物理网卡的验证与初始化等。

miniportreconfigure:支持网卡参数动态变化,和miniportinitilize一样由ndis接口以初始化级别调度执行(不能屏蔽中断,必须由驱动程序承认并清除在此期间产生的中断),支持即插即用和软配置的网卡在动态改变参数时,必须提供此函数。

miniportqueryinformation:查询网卡的状态以及网卡驱动程序的操作或统计参数,如是否支持组通讯、网卡的物理速率是否支持回环、是否支持直接拷贝等,这些参数以oid方式统一管理。

miniportsetinformation:ndis接口或协议驱动程序通过调用此接口改变驱动程序维护的oid库,一些操作参数的改变也将同时改变驱动程序状态,例如组地址的设置。

miniportreset:包括网卡硬件重置和驱动程序软件重置,软件重置包括驱动程序状态重置,以及一些相关的参数重置,还需考虑有些参数的恢复,重置时不必完成所有正在活跃的外部请求,但必须释放已占用的外部资源。

miniporthalt:挂起网卡并释放该网卡驱动程序占用的所有资源,在此期间不屏蔽中断。

miniportisr:高优先级的中断处理程序,进行的工作包括初始中断处理类型,决定是否进行中断转交,对卡上中断进行处理 等,该服务类型只在以下情况被调用:

ndis接口调用miniportinitialize和miniporthalt两函数时。

.中断处理类型设为每此中断处理过程都调用时。

为使系统能及时响应所有硬件中断,高优先级的硬件中断处理程序应尽可能的减少运行时间,防止长时间的屏蔽低优先级中断,避免造程中断丢失。

miniporthandleinterrupt:由中断延时处理程序在中断延时处理时进行调用。ndis排队所有的延时处理,该服务主要处理发送完成、报文接收、描述符用尽、溢出、网卡异常等中断。

miniportsend:ndis收到上层发送请求时经过若干协议处理再向下调用此服务过程,发送的packet已含有llc和mac头,该服务过程进行边界对齐、packet约束重整、描述符映射和报文发送、以及发送资源和packet缓冲队列管理。

miniporttransferdata:多个已和网卡捆绑的协议驱动程序在接收到报文到达指示后,向网卡驱动程序发出传送请求以拷贝各自所需的报文数据部分,网卡驱动程序根据各协议驱动程序对单个packet是否进行多次拷贝,以决定是否暂存只允许单次拷贝的packet等。

miniportcheckhandle:ndis每秒调用此服务函数一次,驱动程序发现网卡异常时报告给ndis由ndis调用miniportreset进行硬件重恢复。

miniportenableintrrupt:中断使能。

miniportdisableinterrupt:中断屏蔽。

另外,每个网卡驱动程序必须有一个初始化入口点,由driver entry函数实现,它和系统相关,由操作系统在装入驱动程序时调用,主要完成初始化ndis wrapper,再由wrapper初始生成驱动程序管理块并完成相应各种初始化工作,登录网卡驱动程序所有上边缘服务入口点,同时写入ndis版本信息。ndis接口库包括在ndis.sys中,它是一个核态函数库,有一套抽象的函数,无论协议驱动程序还是nic驱动程序都连接到这个库中,以实现上下层之间的操作。

第二章fddi网卡驱动程序的加载和运行

第一节 网卡驱动程序的安装

windows nt网卡驱动程序安装的目的是实现网卡相应硬件信息和驱动程序在windows nt注册库中的注册,使windows nt能够正确识别网卡,了解所必需的软硬件信息并能在windows nt启动时加载相应驱动程序。

网卡驱动程序安装时,首先在主群组的控制面板中选择“网络”,然后添加网卡,指定相应信息文件──oemsetup.inf的路径,以完成以下两个必要的操作:

复制驱动程序到相应的系统目录(windows nt根目录system32drivers)中;

在windows nt注册库中存入相应软硬件信息。

下面主要以fddi网卡为例介绍安装驱动程序所必需的工作:

§2.1.1网卡一般硬件参数

对于fddi网卡,必须在编写其oemsetup.inf文件时确定以下硬件参数:

总线类型:pci(5)……括号中的数字5表示pci总线在ndis中的总线类型代码;

厂商代号:0x5588……系统加载时确定网卡的标记,也是编程时确定pci槽号的标识;

cfid: 0x01;

介质类型:光纤(3) ……括号中的数字表示光纤在ndis中的介质类型代码;

是否支持全双工:支持。

对于其它的硬件信息在此inf配置信息文件中可有可无,如若配置,则可在驱动程序的编写时利用这些信息,方便编程,同时有利于其它应用对其参数的确定和使用。网卡驱动程序的安装通常将创建登录表中的四个不同子键:

software registrion键,对应于驱动程序,存在于hkey_local_machinesoftwarecompany productnameversion中。我们的fddi网卡驱动程序所对应的是hkey_local_machinesoftwarenet612yhfddiyhfddi1.0;

网卡的软件登录键,存在于hkey_local_machinesoftwaremicrosoft windows ntnt3.51networkcardsyhfddi1;

驱动程序的服务登录键,存在于hkey_local_machinesystemcurrentcontrolsetservices

网卡的服务登录键,存在于hkey_local_machinesystemcurrentcontrolsetservices

对于每一个网络部件,一个名为netrules的特殊子键在邻近的驱动程序或网卡登录子键里创建,netrules标识网络部件为网络整体的一部分。

fddi网卡驱动程序对应的标准软件登录表项将出现在以下路径:

hkey_local_machinesoftwarenet612yhfddiyhfddi1.0;

驱动程序对应的标准项的值为:

description =yhfddi/pci adapter controller

install date =……

……

refcount =0x01

servicename =yhfddi

softwaretype =driver

title =yhfddi/pci adapter controller

而且在yhfddi驱动程序相关的netrules子键下,这些值项为:

bindable =yhfddi driver yhfddi adapter non exclusiver

bindform =“yhfddisys”yes no container

class = reg_multi_sz “yhfddi driver basic”

infname =oemnad1.inf

type =yhfddisys ndisdriver yhfddidriver

use =driver

yhfddi网卡在如下路径的networkcards子键里介绍:

hkey_local_machinesoftwaremicrosoft

windows ntnt3.51networkcardsyhfddi1;

网卡的标准项包括以下这些值:

description =yhfddi/pci adapter controller

install date =……

manufacturer =net612

productname =yhfddi

servicename =yhfddi01

title =[01]yhfddi/pci adapter controller

§2.1.3编写inf信息配置文件

gui inf描述语言被windows nt用以书写系统所有部件的配置文件,当然也可以用以书写网络系统各部件的配置文件,该配置文件描述了网络部件安装、配置、删除的执行过程。当网络部件进行初始安装或二次安装(通常通过ncpa进行)时,安装程序读取部件对应的配置文件,进行解释执行。gui inf描述语言由节、命令、逻辑操作、变量规范、流程控制以及一套调用dll或外部程序的机制组成,其中,节是配置文件的主体,节可分为install节(类似于函数),shell节(也类似于函数,但可调用insall和shell节),detect节(不包含命令),一个配置文件一般由若干不同类型的节组成。驱动程序的开发者根据需要可以在配置文件中编写相应代码,使得用户和系统之间能进行交互,并且由用户决定一些配置参数。

nt网卡配置文件有其一套规范,驱动程序开发者必须按规范编写配置文件,一般来说,一个配置文件至少应该提供下面三个节:

安装入口点:[identify]shell节。该节主要功能是给出安装部件的类型名,系统通过它识别该部件属于哪一大类(display,mouse,scsi,network等)中的哪一类(网络adapter,driver,transport,service,network和netprovidor),同时,还需要给出映像文件和配置文件所在的源介质及标识。

[returnoption]shell节。系统执行安装identify节后,执行该节。它主要功能是检查所需安装的部件是否支持的硬件平台和语言,并给出网卡名(有些配置文件支持多类网卡,此时必须让用户进行选择,并获得选择结果)。

[installoption]shell节。该节是配置文件得主体,也是上次安装完后再次进行配置、删除、更新的入口点。主要功能是拷贝映像文件和配置文件,生成配置的各种选项,创建该部件在注册库中对应的各种登录子树并更新重写。

第二节 驱动程序的加载过程

§2.2.1 windows nt的启动过程

驱动程序设计范文第4篇

关键词:ACM竞赛;程序设计;课程;教学改革

中图分类号:TP3-4 文献标识码:A 文章编号:1007-9599 (2012) 19-0000-02

1 引言

计算机软件技术的发展日新月异,给高等院校相关专业的教学带来了很大的挑战,为了更好地适应不断变化的社会就业需求,就必须在传统的计算机专业教学模式的基础上开辟出一条新路。

在这样的背景下,乐山师范学院计算机科学学院早在2005年就开始开展校企合作办学,与企业联合培养校企合作方向的学生,至今已是第八届。相比普通班,校企合作教改班所开设的专业课程更符合于当前计算机人才市场的需求,典型的特点就是注重对学生的专业技能尤其是程序设计和软件开发能力的系统性培养,严格按照软件工程师的培养模式来开展相关的理论和实践教学环节,这在很大程度上改变了以往只注重专业理论教学的局限性。

在对近几年教改学生的就业情况进行分析以后,明确肯定了校企合作教学模式为我院本科人才培养体系的改革起到了决定性的促进作用,学生的专业技能有了明显的增强,也大大提高了毕业生的就业率。

但与此同时也认识到存在的一些问题:首先,传统的以程序设计语言语法描述为主线的教学方式,以及模式化的实验内容,使教师在教学过程中容易将重点偏向理论,降低了对学生实践能力的锻炼和考核;其次,我们的软件工程师主要是在教室和机房这样的环境下培养出来的,缺乏真刀真枪的实践锻炼机会;最后,虽然校企合作人才培养方案的整体实施效果不错,但也很难培养出高层次的计算机专业人才。

如果以上几点不能有效地解决,那么校企合作办学的成效和前景将受到限制,因此迫切地需要一种途径去驱动程序设计类专业课程的教学模式改革,经过长期、反复的思考和摸索,我们认为通过开展学科专业竞赛活动来推动课程教学改革是比较可行的。而在种类繁多的计算机学科专业竞赛中,最权威、级别最高的就是《ACM/ICPC国际大学生程序设计竞赛》。

本教改项目结合ACM竞赛来促进计算机专业教学体系特别是程序设计类课程的教学改革,教改实施对象主要为计算机科学学院软件工程专业方向的学生。首先针对程序设计类课程教学存在的问题以及问题产生的原因进行分析,然后在ACM竞赛模式和特点的基础上,尝试通过结合ACM竞赛来改革课程开设体系和课程教学模式,最后提出了解决问题的具体措施,并在实际教学应用中取得了一定的成效。

2 当前程序设计类课程教学存在的问题

2.1 人才培养模式陈旧,实践教学比例不足

在传统的被动教学模式中,学生缺乏学习主动性、创新性和行业竞争力。而计算机专业课程大多属于实践型课程,强调动手能力。为了加深对理论知识的理解,必须提高实践教学质量,理论和实践教学的学时分配要作适当调整。

2.2 实践内容模板化,缺乏创新能力的培养

首先,设计性、综合性实验偏少,很难培养学生的创造性思维;其次,实验内容严重脱离了现代软件工程过程,更谈不上对综合型应用问题的解决;最后,在实践教学过程中,教师干预太多,学生处于被动完成实验任务的角色。

2.3 缺乏互助学习能力,团队协作意识较差

当前软件项目的开发都是以团队形式实施的,团队成员之间需要合理分工和无障碍沟通。但在传统教学模式中,以项目组为单位来开展教学活动的机会非常少,更谈不上互助学习和团队协作了。

2.4 课程考核模式单一,缺乏激励机制

课程考核主要采用传统考核模式,考核内容受限于教材知识点,缺乏对学生知识结构与实践技能的综合考察,不利于学生综合实践能力和创新能力的培养,最终形成“高分低能”的现象。

3 改革措施

本教改项目主要通过以下几个方面来实施以ACM竞赛促进程序设计类课程教学改革的方案。

3.1 改革课程开设计划

全面分析了目前程序设计类专业课程教学中存在的一些问题(比如教法和学法等方面),结合ACM的竞赛大纲和竞赛模式来调整开课计划,把原计划一学期的《程序设计基础》课程的教学时间调整为一学年,第一学期是程序设计的入门教学,主要介绍高级程序设计语言编程基础;第二学期是程序设计的进阶教学,主要介绍算法设计与分析。

3.2 改革课程实践教学模式[1]

(1)实验内容分级化:

将实验内容分成知识型(单一算法)、应用型(算法和实际问题结合)和综合型(若干小算法的综合,用于解决一个较大规模的问题)。不同级别题型的权值不同,每一级别中又包含若干个相同权值的题目,学生可以根据自身情况选择不同级别的题型和题目数量,这样既考虑到了不同层次学生的学习需求,又达到了统一的实验目的。

(2)实验题目趣味化:

传统的程序设计类实验题目普遍比较枯燥,难以调动学生的学习兴趣和设计思路。参考ACM的海量题集,由任课教师将实验题目生活化和趣味化,使学生自主选择合理的数据结构和算法来解题,这样可以充分激发学生的学习主动性和积极性,将被动学习转化为主动学习,更好地达到了实践教学的目的。

(3)实验时间分散化:

考虑到实验课时非常有限,可参照ACM竞赛平台来构建“程序设计在线评测系统”,功能包括用户管理、题库管理、在线提交、在线排名、在线讨论等。学生注册后可在任何时间登陆该系统进行选题、提交、评测和讨论等自主学习环节,将有限的课内练习时间延续到课外。

3.3 开发资源网站

在全面搜集ACM竞赛相关资源的前提下,以程序员协会的学生会员为主力设计并开发了“ACM资源网站”,并挂靠在学院的Web服务器上,以该资源网为平台来开展竞赛的宣传、组织、培训等活动,同时也为相关课程的理论实践教学和学生自主学习提供了一个优质的信息化平台。

3.4 建设学生梯队

依托于乐山师范学院第二课堂课程《ACM程序设计》的开设,以乐山师范学院三星级社团“程序员协会”为活动主体,在全校范围内吸纳对计算机编程和竞赛感兴趣的学生,成立“ACM竞赛兴趣小组”,通过举办专业讲座、学生科研、协会内部竞赛、协会沙龙等活动,为本专业学生提供一个进一步增强职业技能的交流和学习平台,同时也要在兴趣小组中发现适合参加ACM竞赛的后备人才,面向各年级构建ACM竞赛梯队。

3.5 建立激励机制

增设创新学分,设置创新环节,搭建创新实践的平台,让学生有更多的机会展示自己的专业特长。将参加ACM等学科竞赛纳入学生的综合测评,通过设立竞赛奖学金制度来引导学生积极参加课外科技活动、不断提高自身的创新素质。

3.6 组织参赛

在本教改项目的实施过程中,还要积极组织学生参加各个级别的ACM赛事。对于每一次竞赛,首先成立竞赛领导小组,分析官方公布的竞赛大纲,及时、准确地改革专业教学体系目标和课程开设计划;其次根据往届参赛经验,结合本次竞赛的具体情况制定出竞赛活动方案,将竞赛的宣传、组织、选拔、培训、参赛、奖励等环节制度化;然后选拔ACM参赛队伍,指派经验丰富且取得过优异成绩的教练对参赛队员进行长期、深入、全方位的强化培训和指导;最后通过对竞赛成绩的分析再次调整专业课程开设计划和教学模式。[2]

3.7 改革考核手段

ACM模式的重要特色之一是完善而严谨的考核机制,所以我们大胆尝试将ACM的考核方式借鉴到程序设计类课程的考核环节中,采用ACM模式的黑箱测试,将学生在“程序设计在线评测系统”中获得的成绩以50%的权重加入到课程考核指标当中。这一方面减少了教师的工作量,降低了考核错误率,另一方面做到了客观、公正,更好地发掘了学生的创新能力,提高其对知识点的掌握程度。

4 要解决的关键问题

4.1 课程教学形式的改革,特别是如何处理实践教学和理论教学的比重关系,以及如何让学生能够真正地解决问题,而不是按照设定好的思路去模仿着解决问题。

4.2 课程评价体系的改革,尤其是目前的实践环节评价机制弊端明显,严重束缚了学生的创新能力,错误地引导学生把自己改造为一个受制于理论教材的傀儡。

4.3 差异化教学,考虑到ACM竞赛的难度较大,所以必须考虑到在将ACM融入到专业课程教学过程之后,如何确保整体教学质量并解决好部分学生学习能力较差的问题。

4.4 在ACM竞赛中取得更好的成绩,必须建立有效的组织、选拔、培训、参赛、总结等相关机制。

5 结语

ACM竞赛对程序设计类专业课程的教学改革起到了积极的推动作用,从教学队伍建设的角度来看,它在提高教师的教学水平、科研能力、促进专业的对外交流等方面都起到了重要的作用;从学生培养的角度来看,它在提高学生的学习兴趣、自学能力、创新能力、求真务实的科学态度上有很大的帮助。

总之,通过合理的应用ACM竞赛这个平台,可以使我们的计算机专业教学更趋科学化、规范化,可以让我们的学生开拓视野,促进实践型、创新型人才的培养,提高学生的就业竞争力。

参考文献:

[1]常子楠.基于ACM模式的程序设计类课程实践教学探索[J].计算机教育,2010(16):144-146.

[2]项炜.以学科竞赛促进计算机专业教学改革的探索[J].改革与开放,2009(12):207.

[作者简介]

驱动程序设计范文第5篇

为了保证操作系统的平安性和稳定性以及应用程序的可移植性,Windows操作系统不答应应用程序直接访问系统的硬件资源,而是必须借助于相应的设备驱动程序。设备驱动程序可以直接操作硬件,假如应用程序和设备驱动程序之间实现了双向通信,也就达到了应用程序控制底层硬件设备的目的。它们之间的通信包括两个方面摘要:一方面是应用程序传送给设备驱动程序的数据;另一方面是设备驱动程序发送给应用程序的消息。前者的实现较轻易,通过CreateFile()函数获取设备驱动程序的句柄后,就可以使用Win32函数,如DeviceIoControl()、ReadFile()或WriteFile()等实现应用程序和设备驱动程序之间的通信。后者的实现远比前者复杂,同时介绍这方面情况的文章较少。这不等于说它不重要,相反,它在有些应用场合发挥着重要的功能。设备驱动程序完成数据的采集工作后,需要马上通知应用程序,以便应用程序能够及时将数据取走并进行处理。诸如此类情况,不一而足。

鉴于设备驱动程序通知应用程序的重要性,本人结合一些经验,对它进行了总结,归纳出5种方法摘要:异步过程调用(APC)、事件方式(VxD)、消息方式、异步I/O方式和事件方式(WDM)。下面分别说明这几种方式的原理,并给出实现的部分源代码。

1 异步过程调用(APC)

Win32应用程序使用CreateFile()函数动态加载设备驱动程序,然后定义一个回调函数backFunc(),并且将回调函数的地址%26amp;backFunc()作为参数,通过DeviceIoControl()传送给设备驱动程序。设备驱动程序获得回调函数的地址后,将它保存在一个全局变量(如callback)中,同时调用Get_Cur_Thread_Handle()函数获取它的应用程序线程的句柄,并且将该句柄保存在一个全局变量(如appthread)中。当条件成熟时,设备驱动程序调用_VWIN32_QueueUserApc()函数,向Win32应用程序发送消息。这个函数带有三个参数摘要:第一个参数为回调函数的地址(已经注册);第二个参数为传递给回调函数的消息;第三个参数为调用者的线程句柄(已经注册)。Win32应用程序收到消息后,自动调用回调函数(实际是由设备驱动程序调用)。回调函数的输入参数是由设备驱动程序填入的,回调函数在这里主要是对消息进行处理。

2 事件方式(VxD)

首先,Win32应用程序创建一个事件的句柄,称其为Ring3句柄。由于虚拟设备驱动程序使用事件的Ring0句柄,因此,需要创建Ring0句柄。用LoadLibrary()函数加载未公开的动态链接库Kernel32.dll,获得动态链接库的句柄。然后,调用GetProcAddress(), 找到函数OpenVxDHandle()在动态链接库中的位置。接着,用OpenVxDHandle()函数将Ring3事件句柄转化为Ring0事件句柄。Win32应用程序用CreateFile()函数加载设备驱动程序。假如加载成功,则调用DeviceIoControl()函数将Ring0事件句柄传给VxD;同时,创建一个辅助线程等待信号变成有信号状态,本身则可去干其它的事情。当条件成熟时,VxD置Ring0事件为有信号状态(调用_VWIN32_SetWin32Event()函数),这马上触发对应的Ring3事件为有信号状态。一旦Ring3事件句柄为有信号状态,Win32应用程序的辅助线程就对这个消息进行相应的处理。

3 消息方式

Win32应用程序调用CreateFile()函数动态加载虚拟设备驱动程序。加载成功后,通过调用DeviceIoControl()函数将窗体句柄传送给VxD,VxD利用这个句柄向窗体发消息。当条件满足时,VxD调用SHELL_PostMessage()函数向Win32应用程序发送消息。要让该函数使用成功,必须用#define来自定义一个消息,并且也要照样在应用程序中定义它;还要在消息循环中使用ON_MESSAGE()来定义消息对应的消息处理函数,以便消息产生时,能够调用消息处理函数。SHELL_PostMessage()函数的第一个参数为Win32窗体句柄,第二个参数为消息ID号,第三、四个参数为发送给消息处理函数的参数,第五、六个参数为回调函数和传给它的参数。Win32应用程序收到消息后,对消息进行处理。

4 异步I/O方式

Win32应用程序首先调用CreateFile()函数加载设备驱动程序。在调用该函数时,将倒数第2个参数设置为FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,表示以后可以对文件进行重叠I/O操作。当设备驱动程序文件创建成功后,创建一个初始态为无信号、需要手动复位的事件,并且将这个事件传给类型为OVERLAPPED的数据结构(如Overlapped)。然后,将Overlapped作为一个参数,传给DeviceIoControl()函数。设备驱动程序把这个I/O请求包(IRP)设置为挂起状态,并且设置一个取消例程。假如当前IRP队列为空,则将这个IRP传送给StartIo()例程;否则,将它放到IRP队列中。设备驱动程序做完这些工作后,结束这个DeviceIoControl()的处理,于是Win32应用程序可能不等待IRP处理完,就从DeviceIoControl()的调用中返回。通过判定返回值,得到IRP的处理情况。假如当前IRP处于挂起状态,则主程序先做一些其它的工作,然后调用WaitForSingleObject()或WaitForMultipleObject()函数等待Overlapped中的事件成为有信号状态。设备驱动程序在适当的时候处理排队的IRP,处理完成后,调用IoCompleteRequest()函数。该函数将Overlapped中的事件设置为有信号状态。Win32应用程序对这个事件马上进行响应,退出等待状态,并且将事件复位为无信号状态,然后调用GetOverlappedResult()

函数获取IRP的处理结果。

5 事件方式(WDM)

Win32应用程序首先创建一个事件,然后将该事件句柄传给设备驱动程序,接着创建一个辅助线程,等待事件的有信号状态,自己则接着干其它事情。设备驱动程序获得该事件的句柄后,将它转换成能够使用的事件指针,并且把它寄存起来,以便后面使用。当条件具备后,设备驱动程序将事件设置为有信号状态,这样应用程序的辅助线程马上知道这个消息,于是进行相应的处理。当设备驱动程序不再使用这个事件时,应该解除该事件的指针。

6 结语

在目前流行的Windows操作系统中,设备驱动程序是操纵硬件的最底层软件接口。它向上提供和硬件无关的用户接口,向下直接进行I/O、硬件中断、DMA和内存访问等操作。它将应用程序和硬件细节屏蔽开来,使软件不依靠于硬件并且可在多个不同的平台之间移植。本文介绍了5种设备驱动程序通知应用程序的方法,其中前3种方法主要用于VxD中,后2种方法主要用于WDM。这5种方法都经过实际测试。测试结果表明,它们都能够达到设备驱动程序通知应用程序的目的。

参考文献摘要:

[1欧青立,徐建波,李方敏,等. 虚拟设备驱动程序VxD的探究和开发. 计算机工程,2003