驱动程序设计十篇

时间:2023-04-08 16:29:44

驱动程序设计

驱动程序设计篇1

关键词:wince 驱动程序;开发;设计

1 引言

WINCE和Windows 98或Windows 2000不同,它可以工作在12种不同的处理器体系结构、180余种CPU上;同时,WINCE是一个实时操作系统(实时系统的意义就是输入的指令不必进入队列就可以马上处理,过去我们使用的DDS就是实时系统),可以满足应用程序所需要的实时性要求。

Windows CE的模块化设计使得它能够在大量的平台上定制使用,从客户电子设备到专用的工业控制器。由于它是模块化的,因而我们可以使用满足平台系统需求的最小软件模块和组件集合来设计嵌入式系统平台,从而使内存用量最小,但最大可能地提高操作系统的性能。因此扩展设备就必须要有硬件驱动才能正常工作。

和其它的操作系统一样,Windows CE也提供设备驱动软件,这些软件的目的是驱动内部和的硬件设备,或为它们提供接口。设备驱动程序将操作系统和设备链接起来,使得操作系统能够识别设备或者为应用程序提供设备服务。

Windows CE支持广泛的基于各种CE平台的设备驱动程序。也提供一些用于驱动程序开发的模型(model) ,其中包括来自其它操作系统的驱动程序模型(model),因为这些丰富多变的驱动程序模型, Windows CE适应大部分的内部和设备口Microsoft Windows CE设备驱动程序工具包配备了文档资料,这些文档资料使得你能够为Windows CE创建设备驱动程序。目前,Windows CE提供了四种设备模型,其中两种是专用于Windows CE的模型,另外两种外部模型来自其它操作系统。

2 驱动程序开发简介

2.1 开发工具

Windows CE驱动可以使用Platform Builder或者Visual Studio开发,但是开发人员一般都使用Platform Builder开发设备驱动程序,对于部分驱动也会使用Visual Studio开发,应用程序开发人员更多的使用Visual Studio开发驱驱动程序。作为BSP(Board Support Package)的一部分进行整体编译开发。

2.2 驱动分类

2.2.1 按加载方式和接口类型分类

1) 本机驱动程序(Built-In Drivers)

通常由GWES加载,驱动接口一般都是定制的(Custom Purpose)。

2) 流驱动程序(Stream Drivers)

通常由Device Manager加载,驱动接口是标准的流式接口。

3) 混和型驱动程序

同时有定制式和流驱动两套驱动接口,但是和系统交互只使用流式驱动接口,比如PC卡槽驱动。

2.2.2 按驱动层次分类

1) 层次型驱动程序(Layered Driver)

> MDD(Model Device Driver),与硬件无关,面向上层应用程序,一般由微软建立统一框架;

> PDD(Platform Dependent Driver),针对具体硬件平台的操作代码,一般由驱动开发商实现MDD和PDD之间通过标准的设备驱动服务供应商接口DDSI连接。

2) 独立型驱动程序(Monolithic Driver)

> 独立驱动程序包含了MDD面向上层应用和PDD面向硬件平台两方面的代码;

> 适用于操作不复杂的驱动;

> 减少了MDD和PDD传递之间传递信息的开销,实时性更强;

3 流驱动程序的实现

    流驱动程序必须实现一套标准接口,流驱动程序适用于IO操作,这也是嵌入式系统中最常见的设备驱动,操作接口和文件系统操作相似,通过CreateFile,ReadFile,WriteFile,IOControl函数等来操作应用程序和流驱动交互,可以把设备当作文件操作。

3.1 文件前缀名确定

    根据文件前缀名在系统中必须唯一这一特点,在定义文件前缀名必须是三个字母,若有多个同类设备,由后缀一个阿拉伯数字区分,例如COM1,LPT3等等。文件前缀名将会在驱动的标准接口函数中体现,比如XXX_Init,XXX_Close等。

3.2 通用函数

    根据设备的不同,所需函数不同,通用函数如下所示:

1) XXX_Init:通知设备管理器为设备初始化分配资源;

2) XXX_Deinit:通知设备管理器回收设备初始化时分配的资源;

3) XXX_Open:打开设备。应用程序调用CreateFile时,通过文件系统映射为XXX_Open;

4) XXX_Close:关闭设备。应用程序调用CloseFile时,通过文件系统映射为XXX_Close;

5) XXX_PowerUp:设备上电时,操作系统调用该函数完成必要的上电操作;

6) XXX_PowerDown:设备掉电时,操作系统调用该函数完成必要的关机操作

7) XXX_Read:从打开的设备文件中读取数据,可以通过ReadFile映射;

8) XXX_Write:向打开的设备文件写数据,可以通过WriteFile映射;

9) XXX_Seek:文件定位,根据设备情况决定是否支持;

10) XXX_IOControl:IO操作扩展,可以根据设备情况来决定支持何种特殊的操作模式。

3.3 DEF文件建立

    流驱动一般以DLL形式存在,DEF文件定义了DLL需要导出的接口集,因此DEF文件的名称与设备驱动名称相同。

3.4 写注册表

    在wince中任何设备的识别都是通过注册表来实现的,因此必须在注册表中添加具体的设备驱动项,以便系统识别。具体方法如下:

在注册表中增加驱动程序入口点,找到注册表项,注册项位于注册表的Root Key下,一般为[HKEY_LOCAL_MACHINEDriversBuiltInSampleDrv],建立必要的子键和键值,“Prefix”和“DLL”是两个重要,而且是必须的键,分别描述了设备前缀名和驱动程序的动态连接库名,然后根据具体设备的需要建立驱动程序需要的其子他键。

4 调试驱动程序

驱动程序编写完毕后,就应该进行硬件的调试。具体方法如下:

4.1 调试区信息(Debug Zone)

调试区一般和WinCE的控制台调试工具Cesh.exe配合调试,在不打断OS运行情况下,进行驱动的实时调试,利用宏开关,可以选择需要输出的调试区信息,可以得到进程,线程和调试状态信息。并且可以利用IDE环境,动态选择开关调试区信息,但是打印驱动程序输出调试信。必须借助于至少一种外设显示调试信息,比如串口或者网卡或者其他通过调用RETAILMSG或者DEBUGMSG完成,不影响OS的运行,保证驱动程序运行的真实性,动态输出设备的状态信息,调试相对简单,也是最广泛使用的一种调试方法。

4.2 核心调试工具(Kernel Debugger)

核心调试工具将会禁止所有硬件中断,挂起操作系统,因此可以单步调试OS或者核心代码,可以访问堆栈信息,但是必须在Platform的环境下,利用至少一种外设进行通信。

4.3 硬件辅助调试方法

利用硬件调试工具可以观察物理设备的真实状态,一般常用的方法可以利用JTAG工具实时查看CPU内部寄存器,利用逻辑分析仪或者示波器实时查看物理外设的输入输出状态。利用指示LED来显示驱动程序实时状态信息。

4.4 Visual Studio调试

可以利用VS内置的调试工具进行单步跟踪,状态调试等。

5 测试驱动程序

驱动程序经过调试以后就需要对驱动的功能进行测试。其常用的方法如下:

1) 写一个应用程序来测试驱动程序的正确性

2) 模拟各种可能发生的硬件输入状态来测试驱动程序的正确性

3) 利用Windows CE自带的测试工具CETK来测试驱动程序的性能和完备性

6 驱动程序的集合和

6.1 驱动程序集成

驱动程序经过调试和测试确定其正确性后,就可以对驱动程序进行集成了。具体过程如下:

1) 在BSP的Driver目录下建立新的驱动文件夹MyDrv

2) 实现MyDrv驱动以及相关的DEF文件

3) 如果需要用到硬件中断资源,修改原BSP中的相关中断处理函数OEMInterruptEnable,OEMInterruptDisable,OEMInterruptDone,OEMInterruptHandler

4) 在Platform.reg中,增加驱动程序相关项

5) 在Platform.bib中,增加驱动程序的相关注册表项MyDrv.Dll$(_FLATRELEASEDIR)MyDrv.dll NK SH

6.2 驱动程序

驱动程序进过集成以后就可以使用了,具体的过程如下所示:

1) 利用CAB Wizard生成.cab驱动包

2) 直接提供驱动程序文件夹以及相关注册表项和修改说明

7 总结

本为详细的介绍了,wince下驱动开发的流程,介绍了驱动程序开发到的详细过程,并详细说明了各个部分的实现和操作方法,使是初学者对wince下驱动程序的开发流程和一般的开发工具有了初步的了解。

驱动程序设计篇2

关键词 VxWorks;多串口驱动程序设计

中图分类号:TP368 文献标识码:A 文章编号:1671-7597(2013)13-0156-01

嵌入式安全平台研制项目中,尤其应重视对多通路并发串行数据的传送和安全问题的处理。从当前市场发展状况看,传统的通用串口芯片在数据的接受和传送上已很难满足大数据传送的要求,所以,应考虑使用传送速度更高的串口芯片。同时针对标准的VxWorks驱动程序不能满足高速串口芯片的运行要求,本文重点对多通道高速串口驱动程序的设计进行简单的介绍。

1 VxWorks程序架构介绍

1.1 基本框架

VxWorks系统中I/O系统并不包含串行设备的驱动程序,其功能的实现主要凭借ttyDrv。串行设备的正常使用,一方面应保证其能够支持目标接口和I/O系统,另一方面其应在轮训两种方式或中断方式下正常工作。

对串行设备驱动程序而言,一般与设备无关的部分在虚拟设备ttyDrv实现,而主要程序需要程序员进行编写,然后利用系统提供的接口将其安装到ttyDrv中。虚拟设备ttyDrv重点负责I/O系统和驱动程序间的信息通讯。当系统中有对I/O操作的请求时,虚拟设备ttyDrv首先对请求进行处理,同时将请求涉及的命令交给设备驱动程序,在该驱动程序的操控下,实现对I/O系统的实际操作,同时在ttyDrv操作控制下将入口函数挂接在I/O系统中,然后对设备的相关描述进行初始化操作,处理完毕后系统会自动将其添加到设备列表中。一旦I/O系统发现有请求的命令时,就会触发挂接在I/O系统入口函数,从而响应有关请求。虚拟设备ttyDrv挂接函数时首先会利用ttyDrv()函数调用iosDrvinstall()函数,然后将ttyIoctl()、ttyOpen()、tyWtite()、tyRead()等一些函数挂接在驱动程序中供响应请求用。

1.2 创建专用串口设备

专用串口设备创建时系统会进行初始化处理。首先,初始化设备的描述符,并通过函数tyDevInit()初始化tyLib以及select的功能。其次,创建信号量以及用于输入、输出的缓冲区。最后,通过调用iosDevAdd()函数完成两项工作:1)将设备添加到设备的列表中;2)设置设备的工作模式为中断。

1.3 设备的读、写操作

应用程序为了响应读写操作会首先调用write()函数,接着I/O系统将数据请求传递ttyDrv执行函数tyWtite(),并通过复制的方式将存在于用户缓冲区的内容加载到环形缓冲区中,并初始化处理发送的循环,这里调用的函数是xxTxStartUp,将原来设置为中断的工作模式打开为发送工作做好准备,系统通过调用xxIntTx中断服务程序完成字符的发送工作,最后将中断清除。

当串口发现相关数据后,会立刻调用xxRcvInt中断服务程序在制定的缓冲区位置进行写操作,与此同时还需要将数据传送给高层协议,该传送过程需要使用tyIRd()进行操作。用户利用函数read()进行读操作的同时,I/O系统会使用函数tyRead(),将环形队列的内容读入到用户缓冲区中。

2 VxWorks下多通道串口驱动程序设计

2.1 基本设计要求

多通道串口驱动程序设计时应满足以下几点要求:首先,设计工作的开展应以OX16PCI958串口芯片为基础,同时还应保证每路串口通道满足多任务并发访问的要求,并且能够对中断是否有效进行准确的判断,以此进一步提高CPU的利用率。其次,在实现端口设置的同时,能够保证芯片和应用程序之间进行正确的通讯。

2.2 设计应注意的问题

2.2.1 多任务并发设计

为了满足驱动程序能够正确处理并发需求的要求,驱动程序内部采用中断所和任务锁界定对临界资源的修改权限,并保证了连续寄存器操作指令能够不断被打断。驱动程序实际的设计时每个通道会对应一个独立的ST16C_CHAN,从而当访问某个通道时不会对其他通道造成影响,以此实现并发访问。

2.2.2 中断共享设置

为了提高CPU的工作效率,外部设备与CPU之间的通讯机制为中断,以此防止频繁查看外部设备,增加CPU的运算时间。中断运行的原理是:系统会利用存在于sysSerial.c文件中的函数sysSerSerialHwInit()实现对pciConfigInByte()函数的调用,同时将参数设置为PCI_CFG_DEV_INT_LINE,并从寄存器中获得中断线,并使用pciIntConnect()函数将函数ST16C958Int()进行挂接,最后为了对中断进行共享还需要调用sysIntEnablePIC()函数。另外,在处理中断时还应注意其他共享同一信号设备的中断。

2.2.3 端口设置

用户访问虚拟设备ttyDrv时会首先调用ioctl()函数,与此同时I/O系统也会调用ttyIoctl()函数,该函数会访问ST16C958Ioctl()函数然后实现查询、设置工作模式、设置波特率等功能。另外,驱动程序设计时还应注重把握应用程序和串口访问数据之间的交互设计。

3 总结

在VxWorks下以OX16PCI958芯片为基础进行多串口驱动程序设计,综合数据结构等方面的知识,实现了多通道串口通信驱动的要求,同时对今后VxWorks下多串口卡驱动程序的设计具有较高的借鉴价值。

参考文献

驱动程序设计篇3

关键词:VxWorks;USB设备驱动;管道;回调

中图分类号:TP316文献标识码:A文章编号:1009-3044(2008)24-1200-04

Design of USB Device Driver Based on Real Time Operation System VxWorks

WANG Hao

(College of Computer, Xidian University, Xi'an 710071, China)

Abstract:The architecture of USB dirver based on VxWorks is given, general method and key technology in developing USB device dirver are analyzed.Then the device driver of LM9833 is implemented, expectant performace of target system is achieved. The general process of developing USB device dirver used in this paper can be refered by others USB device driver developing based on VxWorks.

Key words: VxWorks; USB device driver; pipe; callback

1 VxWorks下USB驱动概述

VxWorks是WindRiver公司开发的具有工业领导地位的高性能实时操作系统(Real Time Operation System, RTOS)内核。VxWorks5.5实现了USB1.1协议栈。图1提供一个VxWorks下USB主驱动栈的简单结构。

在栈的最低层是USB主控制器(USB Host Controller, HC),这是主系统中控制每一个USB设备的硬件。在主控制器上层是一个与硬件独立的主控制器驱动(USB Host Controller Driver,HCD)。USBD是在HCD之上的与硬件独立的模块,USBD管理每一个与主机相连的设备,向高层提供可与USB设备通信的路径,USBD实现了USB总线枚举、总线带宽分配、传输控制等操作。在栈的顶层是USB Client 模块,一般是特定的USB Class Driver,负责管理与USB主机连接的不同类型的设备。用户自己的USB设备驱动程序通常是在USBD这一层上完成。

2 VxWorks下USB设备驱动详解

2.1 驱动程序提供的函数

2.1.1 向应用程序提供的接口函数

设备驱动程序的主要作用是向上层应用程序屏蔽硬件,向上层应用程序提供统一的接口函数,驱动程序一般需要实现的函数如表1所示。

图1 USB主驱动栈结构

表1 驱动程序提供的接口

usbMSCDevInit();这是一个通用的初始化例程,可以在BSP中调用,也可以由应用程序来调用,但只能被调用一次,该例程初始化必须的数据结构,并向USBD注册驱动程序。USB设备与USB主控制器之间的所有操作都通过USBD来完成,因此在调用usbMSCDevInit()之前必须确定USBD已经初始化,在使用USB设备之前也要确保USB主控制器已经挂接到USBD。

usbMSCDevCreate();这是一个创建设备例程,当有设备接入时,回调函数usbMSCDevAttachCallback()调用该例程创建一个逻辑设备,当这个例程被调用时必须在系统中存在一个实际的USB物理设备。

usbMSCDevDestroy();从系统中删除设备。首先释放设备占有的资源,从设备链表中移除该设备,同时调用usbdPipeDestroy()销毁该设备与主机之间的通信管道,最后释放设备结构体。

usbMSCDevShutDown();该例程卸载已注册的设备驱动程序,并回收所有已分配资源,包括删除设备、回收信号量等。

2.1.2 两个重要的回调函数

在编写USB设备驱动程序时,除了上述接口函数外,还需要编写另外两个重要的回调函数:usbMSCDevAttachCallback()和usbMSCIrpCallback()。usbMSCDevAttachCallback()用于跟踪设备的请求实现动态接入或删除;usbMSCIrpCallback()是一个IRP callback,当每一个IRP执行完成之后调用该回调函数,实现IRP之间同步。

2.2 设备标识

在VxWorks中USB设备用USBD_NODE_ID来唯一区别,它是USBD用来跟踪一个特定设备的句柄,它与USB设备的真正USB地址无关。这表明Client并不关心设备是物理上与哪一个USB主控制器连接,应用为每个设备抽象一个Node ID,使Client可以不用考虑物理设备的连接细节以及USB地址分配。当一个Client通知有一个设备连接或断开时,USBD经常通过Node Id来定位设备。同样,当USB设备与USBD通信时,它必须向USBD传递该设备的Node Id。Node ID通常作为设备结构体的一个重要成员。

2.3 回调(Callback)

USB操作是严格遵守时序的,WindRiver USBD采用回调机制来解决时序问题。例如在USBD识别一个动态连接事件之后会激活一个动态attach callback操作,这是一个注册到USBD的回调例程,回调函数会判断当前的操作,如果是接入(USBD_DYNA_ATTACH),就会调用usbMSCDevCreate()来在当前的USB句柄上创建一个逻辑设备结构体;如果是移出(USBD_DYNA_REMOVE)就会调用usbMSCDevDestroy()来删除设备。同样,当USBD处理完成一个USB IRP之后,Client的一个IRP callback被激活,该回调例程是由Irp.userCallback域来指定。在IRP callback中释放IRP同步信号量。

2.4 数据传输

USB设备与主机之间是通过USB管道进行通信的。一旦Client配置完一个设备,就可以利用USBD提供的管道(pipe)传输功能与设备进行数据交换。管道是建立在USBD Client与设备特定的endpoint之间的单向通道。调用usbdPipeCreate()函数创建一个管道后返回一个管道句柄USBD_PIPE_HANDLE,以后所有的读写操作都分别在各自的管道句柄上进行。管道在刚创建完后是处于终止的状态,为了能有效使用它们,还必须用usbdFeatureClear()来清除该终止状态。每一个管道有以下性质:USBD_NODE_ID、端点地址,管道类型、数据流方向、包的最大有效载荷量、带宽需求等。对于块传输没有带宽限制。VxWorks的USB驱动程序的各层驱动程序间通过IRP机制进行通信,当有数据传输请求发生时,上层向下传递IRP。USBD得到请求后,调用HCD接口,将IRP转化为usb的传输。这就需要提供一个特殊的回调函数usbMSCIrpCallback(),当块传输结束时调用该回调函数。以下是读设备的具体过程。

1) 创建设备时创建out和in管道:

usbdPipeCreate(usbdHandle, NodeId, outEpAddress, configuration, interface, USB_XFRTYPE_BULK, USB_DIR_OUT,maxPacketSize,0,0, outPipeHandle);

usbdPipeCreate(usbdHandle, NodeId, inEpAddress, configuration, interface, USB_XFRTYPE_BULK, USB_DIR_IN,maxPacketSize,0,0, inoutPipeHandle);

2) 定义IRP callback:usbMSCIrpCallback(pVOID p)。

3) 构造USB_IRP outIrp请求包。

4) 提交outIrp:usbdTransfer (usbdHandle, outPipeHandle, &outIrp)。读命令在outIrp.bfrList[0].pBfr域中。

5) 等待outIrp处理结束,结束调用usbMSCIrpCallback()释放IRP同步信号量。

6) 构造USB_IRP inIrp请求包。

7) 提交inIrp:usbdTransfer (usbdHandle, inPipeHandle, &inIrp)。

8) 等待inIrp处理结束,读取的数据在inIrp.bfrList[0].pBfr域中。

2.5 多个设备管理

驱动程序用LIST_HEAD 来存储多个设备,每个接入的USB设备利用其LINK节点加入到LIST_HEAD链表当中;一个LINK节点包含三部分:linkFwd指针、linkBack指针和pStruct指针;其中pStruct指向一个待连接的设备结构体。当有一个设备创建完成时调用usbListLink()将该设备加入链表,删除设备之前调用usbListUnlink()从链表中移出该设备。由于USB设备是用Node ID来唯一标识的,在查找设备的时需要利用usbListNext()来遍历设备链表,直到某个设备的Node ID与特定设备的Node ID相匹配为止。在多个设备管理时,采用USBD_NODE_ID usbd_scan_id[DEVICE_NUM]数组来存放多个设备的Node ID,在对设备进行读写时只需提供设备的索引序号就可以直接得到设备Node ID,提高了对设备的访问速度。

3 VxWorks下LM9833驱动程序实现

3.1 LM9833 USB接口简介

LM9833扫描仪控制器在一个单独的IC上可以提供一个完整的USB图像扫描控制系统。它的USB接口提供4个USB端点(Control Endpoint,Interrupt Endpoint,Bulk In Endpoint和Bulk Out Endpoint),内部有00~7F个寄存器,其中00寄存器是存放一个8bits的图象数据,其它分别为控制或状态寄存器。通过向bulk out端点发送四字节的读命令可以从bulk in端点读取这些寄存器的值,也可以向bulk out端点发送四字节的写命令加待写数据完成写寄存器。四字节命令依次表示:读写模式(1字节)、起始地址(1字节)、读写长度(2字节)。其中读写模式bit0为0表示写,1表示读;bit1为0表示非增模式,为1表示增模式,即读写寄存器完成之后寄存器地址加1。LM9833的工作过程就是通过读写这些寄存器来完成的。

3.2 设备描述符结构

typedef struct _usbScanDev

{

USBD_NODE_ID scanDevId; /* USBD node ID of the device */

UINT16 configuration; /* Configuration value */

UINT16 interface; /* Interface number */

UINT16 altSetting; /* Alternate setting of interface */

UINT16 outEpAddress; /* Bulk out EP address */

UINT16 inEpAddress; /* Bulk in EP address */

USBD_PIPE_HANDLE outPipe; /* Pipe handle for Bulk out EP */

USBD_PIPE_HANDLE inPipe; /* Pipe handle for Bulk in EP */

USB_IRP inIrp; /* IRP used for bulk-in data */

USB_IRP outIrp; /* IRP used for bulk-out data */

USB_IRP statusIrp; /* IRP used for reading status */

UINT8 * scanInData; /* Pointer for bulk-in data */

UINT8 * scanOutData; /* Pointer for bulk-out data */

BOOL connected; /* TRUE if USB_SCAN device connected*/

LINK scanDevLink; /* Link to other SCAN devices */

UINT8 CommandByte[4]; /* Which read/write command the device */

UINT16 actBytes; /* actual bytes will be transfered */

UINT8 direction; /* data transfer direction */

} USB_SCAN_DEV, *pUSB_SCAN_DEV;

设备描述符结构中包含了设备的一些重要信息和访问该设备时的必须资源,如Node ID、IN/OUT管道、IN/OUT IRP等等。

3.3 注册设备(LM9833)驱动程序

注册驱动程序一般包含两大步:与USBD建立连接和注册attach callback。以下是注册LM9833驱动程序的源代码。

#define USB_SCAN_CLASS 0xff

#define USB_SCAN_SUB_CLASS0x00

#define USB_SCAN_DRIVE_PROTOCOL0xff

STATUS usbScanDevInit()

{……

if(usbdClientRegister ("SCAN_CLASS", &usbdHandle)!=OK||

usbdDynamicAttachRegister (usbdHandle, USB_SCAN_CLASS, USB_SCAN_SUB_CLASS,

USB_SCAN_DRIVE_PROTOCOL, usbScanDevAttachCallback) != OK)

……

}

usbScanDevInit()调用usbdClientRegister()向USBD注册一个名为SCAN_CLASS的Client,同时调用usbdDynamicAttachRegister()向USBD注册一个回调例程usbScanDevAttachCallback (),跟踪该Client请求,当设备动态地接入或移出系统时会自动地调用该回调函数。一个Client在利用usbdDynamicAttachRegister()进行注册时只对特定的class、subclass、protocol感兴趣。在成功注册Client后,USBD返回一个Client句柄(USBD_CLIENT_HANDLE),以后对USBD的调用都会用到这个句柄。Attach callback 如下。

LOCAL VOID usbScanDevAttachCallback

(

USBD_NODE_ID nodeId,

UINT16 attachAction,

UINT16 configuration,

UINT16 interface,

UINT16 deviceClass,

UINT16 deviceSubClass,

UINT16 deviceProtocol

)

该回调函数主要响应外部设备的动作,实现USB设备的动态接入和移除。

3.4 创建设备

创建设备函数如下:

LOCAL STATUS usbScanPhysDevCreate(USBD_NODE_ID nodeId, UINT16 configuration, UINT16 interface)

当接入设备时激活usbScanDevAttachCallback()操作,回调函数会根据接入(USBD_DYNA_ATTACH)动作调用usbScanPhysDevCreate()创建一个逻辑设备,在创建设备的同时,创建设备与USB主机之间通信的管道(pipe)。管道是建立在USB设备端点(endpoint)之上,是主机与设备之间数据传输的单向通道。设备与主机之间数据传输管道是建立在批量端点(bulk endpoint)之上,有BULK_IN和BULK_OUT两个端点,从而建立双向的数据通路。最后将该设备加入设备链表,进行多个设备的管理。创建设备流程如图2所示。

图2 创建设备流程

3.5 读写设备

对设备进行读写时,首先需要将读写函数转换成设备能够识别的命令,对于LM9833来说,需将读写函数转换成LM9833所能识别的四字节读写命令,读写时将这四字节的命令置于IRP包数据域的最前端,这样到数据到达设备时首先接收到的是四个字节的命令,LM9833会根据这四个字节的命令完成相应的功能。读写函数原型为:

STATUS usbScanRead/usbScanWrite

(

UINT dev, /* sequence number of the device */

UINT Addr, /* start address in register */

UINT8 *pBuffer, /* pBuffer to receive/send data from/to device*/

UINT Len, /* lenth of pBuffer */

BOOL bIncrement /* incremece of address in register or not */

)

LM9833的一个读写控制流程如图3所示,查找设备流程如图4所示。

图3 LM9833读写控制流程

图4 查找设备流程

设备命令组帧:

const unsigned int MODE_INC_READ = 0x03;

const unsigned int MODE_NOINC_READ = 0x01;

const unsigned int MODE_INC_WRITE = 0x02;

const unsigned int MODE_NOINC_WRITE = 0x00;

switch (Cmd)

{

case USB_SCAN_WRITE:/* bulk out */

pScanDev->CommandByte[0] = (bIncrement>0)? MODE_INC_WRITE : MODE_NOINC_WRITE;

pScanDev->CommandByte[1] = Addr+((bIncrement>0)? i : 0);

pScanDev->CommandByte[2] = (Len >> 8); /* length of the data to be written */

pScanDev->CommandByte[3] = (Len & 0xff);

memcpy(pScanDev->scanOutData, pScanDev->CommandByte, 4); /* 4 bytes Lm9833 command followed by write data */

memcpy(pScanDev->scanOutData + 4, pBuffer + i, Len);

pScanDev->actBytes = Len+4; /* actual length to be transfered*/

pScanDev->direction = USB_SCAN_DIR_OUT;

break;

case USB_SCAN_READ: /* bulk in */

驱动程序设计篇4

关键词:PCI; vxworks;驱动程序;运动控制卡

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2012)29-6966-03

VxWorks是目前世界上用户数量最大的实时嵌入式操作系统, 它具有高度可剪裁的微内核结构、高效的多任务调度、灵活的任务间通信手段、快速灵活的I/O系统、确定的微妙级中断延迟时间等优点。

本文介绍了基于PCI 接口规范的通用运动控制卡在VxWorks下的驱动程序的设计。对其设计驱动程序需要对实时操作系统、实时软件设计、硬件设备有深入的了解。因此, 该设计不仅本身具有很高的应用价值, 也为实时驱动程序的设计提供了一个样例。

1 系统组成

在基于微机的数据采集、处理与控制系统中,计算机接口卡常常是其中的关键硬件设备。目前在运动控制领域,各类运动控制卡得到广泛运用,其中以工控机通过ISA或PCI等系统总线连接运动控制卡的主从式结构最为流行,由工控机发出控制指令和参数,控制卡根据接收到的指令及参数完成具体控制功能。由于PCI总线的高速和即插即用特性,使其取代ISA被广泛应用于高速数据采集与传输等系统中,有效地解决了实时采集、实时传输和实时存储等问题。

2 PCI 配置空间

PCI系统具有三种地址空间:存储器空间、I/O空间和配置空间。每个PCI设备都有64个配置双字用于实现配置寄存器,64个配置双字分为两部分,⑴PCI协议定义了开头16个双字的格式和用途,称为设备的配置头区域;⑵其它48个双字的用途是由设备指定的。目前PCI协议定义了两种头区域格式,第1类配置头区域用于定义PCI-PCI桥,而第0类配置头区域用于定义其它PCI设备。所有的PCI设备,包括PCI-PCI桥都必须实现下述配置寄存器:厂商标志、设备标志、命令、状态、分类码、版本标志和头区域类型寄存器。如表1所示为PCI配置寄存器。这些寄存器对编程访问PCI设备至关重要,我们就是利用vendor ID 和device ID来枚举出对应的设备,再进一步获得设备的其他信息的。

3 驱动程序的开发

VxWorks 提供在指定目标系统上运行的板级支持包(BSP),本文选用的是针对pentium的板级支持包。VxWorks是支持PCI总线的,提供了一些库函数专门用来访问PCI设备。为了调用这些函数以方便开发,需要包含如下头文件"iosLib.h"、"pciConfigLib.h"、"pciIntLib.h"、"sysLib.h"和"pciLocalBus.h",还需要导入sysOutLong()和sysInByte()等函数。在config.h里面定义INCLUDE_PCI以添加VxWorks对PCI的支持,还可以定义PCI_CFG_TYPE为PCI_CFG_FORCE、PCI_CFG_AUTO 或 PCI_CFG_NONE,我们一般定义为PCI_CFG_NONE,Vxworks只需把配置好的信息读出来就可以了。

针对PCI 总线结构的数据采集模块,其驱动程序的主要开发步骤如下:确定设备的PCI 配置信息确定设备的内部存储器、寄存器基地址及中断号设备初始化中断服务程序设备各功能函数。以下按照程序执行的顺序分步骤给出源代码,并加以详细的说明。

4 结束语

利用上文所述的方法编写的驱动程序,达到了本项目所要求的性能指标,系统经过实际验证是高速稳定可靠的,而且由于PCI总线的即插即用特性,不需要用户去手动跳线,极大得方便了使用。

参考文献:

[1] microsoft msdn[EB].2001.

驱动程序设计篇5

第一节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)(由网络厂商提供)。多供应者路由选择程序决定适当的供应者,然后借助于供应者,对应用请求到相应的转发程序做出选择。

§1.1.2  windows  nt网络驱动程序

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通信的手段。

§1.2.1  miniport网卡对象

ndis用一个叫做逻辑网卡的软件对象来描述系统中的每块网卡,而逻辑网卡与windows  nt设备对象的通信由i/o子系统来管理,描述网卡的设备对象包括相关的网络信息如名字、网络地址和网卡内存基地址等,它还包含与硬件相关的驱动程序状态数据(捆绑数目,捆绑句柄,包过滤数据库等)。ndis分配一个句柄到miniportinitialize这个上边缘函数的一个结构中,然后miniport网卡驱动程序将在以后提供这个句柄来给ndis调用,这个结构一直被ndis保持,并且对miniport驱动程序不透明。  

当miniport网卡驱动程序初始化一块网卡时,它创立自己的内部数据结构来描述网卡,记录需要它管理的与设备相关的状态信息。当miniport网卡驱动程序调用ndismsetatttibutes或ndismsetattributesex两ndis库函数时,它传递一个句柄给这数据结构。这样,当调用miniport驱动程序入口点时,它就传递这个句柄来验证驱动程序所对应的网卡的正确性。这个数据结构为miniport网卡驱动程序所拥有并维护。

§1.2.2网络对象标识符

miniport  nic驱动程序还需要维护一组对象,这些对象是系统定义的对象标识符(object  idetifier:oid)来标识,以描述驱动程序的性能和当前状态信息。为查询这些信息,上层驱动程序调用ndisrequest向ndis接口库指示oid。oid表示了调用所需的信息类型,如miniport驱动程序所支持的lookahead缓冲区大小等。ndis接到上层驱动程序的查询请求,将oid传递给上边缘函数miniportqueryinformation实现对oid的查询,如果上层驱动程序请求改变状态信息则调用miniportsetinformation实现对oid的设置。

§1.2.3  miniport网卡驱动程序代码

典型的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版本信息。

§1.2.4  ndis接口库

ndis接口库包括在ndis.sys中,它是一个核态函数库,有一套抽象的函数,无论协议驱动程序还是nic驱动程序都连接到这个库中,以实现上下层之间的操作。

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

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

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

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

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

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

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

§2.1.1网卡一般硬件参数

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

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

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

cfid:  0x01;  

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

是否支持全双工:支持。  

对于其它的硬件信息在此inf配置信息文件中可有可无,如若配置,则可在驱动程序的编写时利用这些信息,方便编程,同时有利于其它应用对其参数的确定和使用。

§2.1.2  fddi网卡加载时需在注册库登录表里做的网络配置

网卡驱动程序的安装通常将创建登录表中的四个不同子键:

software  registrion键,对应于驱动程序,存在于hkey_local_machine\software\company\  productname\version中。我们的fddi网卡驱动程序所对应的是hkey_local_machine\software\net612\yhfddi\yhfddi1.0;  

网卡的软件登录键,存在于hkey_local_machine\software\microsoft\  windows  nt\nt3.51\networkcards\yhfddi1;  

驱动程序的服务登录键,存在于hkey_local_machine\system\currentcontrolset\services  

网卡的服务登录键,存在于hkey_local_machine\system\currentcontrolset\services  

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

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

hkey_local_machine\software\net612\yhfddi\yhfddi1.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_machine\software\microsoft\

windows  nt\nt3.51\networkcards\yhfddi1;

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

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的启动过程

第一阶段:调入装入程序。和硬件平台相关,x86机器首先由rom装入根扇区,再由根扇区装入ntldr;

第二阶段:硬件检测。x86机器调ntdetect程序最大限度地获取各种硬件设备信息,引导hal及基本卷设备驱动程序,以便引导nt内核;

第三阶段:获取注册库中各种控制信息,如用户定义的非页内存大小;第四阶段:初始化注册库  \registry\machine下system和hardware并创建currentcontrolset,为装入相关硬件设备驱动程序作准备;

第五阶段:装入基本核心驱动程序;

第六阶段:释放一些已经完成使命的装入初始数据块;

第七阶段:进一步初始化注册库,以便有些依赖于基本核心驱动程序的上层驱动程序能顺利装入;

第八阶段:服务控制器装入应该由该服务控制器装入的各种驱动程序。

§2.2.2  fddi网卡驱动程序的加载过程

在windows  nt启动的第五个阶段,将加载核心驱动程序。而对于ndis网卡驱动程序是在ndis接口(ndis.sys)加载后调入运行,向ndis  wrapper注册、初始化、查询设置参数等。

windows  nt启动时,相应的实体如nt的服务控制器根据注册库中yhfddi驱动程序的配置注册信息,初始化ndis  wrapper,并装入相应的驱动程序,生成驱动程序管理块结构,申请内存以保存各种信息,向ndis  wrapper注册驱动程序。初始化和注册完毕后,再由服务控制器读取注册库中相应的链接信息。

在ndis  wrapper和yhfddi驱动程序初始化和注册成功后,ndis  wrapper根据系统相应的注册信息,加入和yhfddi驱动程序所对应的fddi网卡,同时读入网卡的注册信息,并进行网卡注册和网卡初始化。

在以上过程成功后,wrapper将查询和设置驱动程序的各种参数,了解驱动程序对哪些操作支持,决定对上层驱动程序的支持范围。

第三节fddi网卡驱动程序的注册

driverentry函数是windows  nt  ddk规定的核心驱动程序的入口点,wrapper识别到入口点后,调入驱动程序,在driverentry函数内完成两个基本注册任务:

调用ndisminitializewapper函数向ndis接口报告驱动程序将以miniport类网卡驱动程序注册。ndis建立它需要记录的驱动程序状态信息,同时返回ndiswrapperhandle,驱动程序保存这个句柄,以利后来调用ndisxxxconfiguration和initialization等函数。  

填写ndisxx_miniport_characteristics属性结构,主要记录ndis版本号和驱动程序支持的miniportxxx函数的入口点,然后调用ndismregisterminiport函数实现驱动程序的整体注册。  

以yhfddi为例所要注册的属性结构的内容大致如下:

ndis_miniport_characteristics  yhfddichar;

(ndis_miniport_characteristics这个结构将在第三章介绍)

yhfddichar.majorndisversion=yhfddi_ndis_major_version;

yhfddichar.minorndisversion=yhfddi_ndis_minor_version;

这两个属性决定驱动程序是ndis的哪个版本所支持,我们所用的是ndis3.0  

yhfddichar.disableinterrupthandler=yhfddidisableinterrupt;

yhfddichar.enableinterrupthandler=yhfddienableinterrupt;

yhfddichar.isrhandle=yhfddiinterruptservice;

yhfddichar.handleinterrupthandler=yhfddihandleinterrupt;

以上四项属性是中断处理所需的上边缘服务函数的入口点(句柄)。fddi网卡驱动程序需要有smt站管理功能,而smt是以中断处理方式进行的,故这四项属性在fddi网卡驱动程序中是很重要的。

yhfddichar.initializehandler=yhfddiinitialize;

此项注册的是驱动程序的初始化函数句柄。

yhfddichar.queryinformationhandler=  yhfddiqueryinformation;

yhfddichar.setinformationhandler=yhfddisetinformation;

这两项注册的是参数查询和设置函数的句柄。

yhfddichar.sendhanler=  yhfddisend;

yhfddichar.transferdatahandler=  yhfdditransferdata;

主要提供数据发送和接收函数句柄。

yhfddichar.resethandler=yhfddireset;

此项注册网卡软硬件重置函数句柄。  

yhfddichar.halthandler=  yhfddihalt;

此项注册网卡驱动程序挂起函数句柄。

yhfddichar.checkforhandler=null;

yhfddichar.reconfigurehandler=null;

这两个上边缘服务函数是fddi网卡驱动程序所不提供的,故置为null。

填好这些结构以后,调用以下函数实现驱动程序的注册:

ndismregisterminiport(

yhfddiwrapperhandle,

&yhfddichar,

sizeof(yhfddichar));

其中yhfddiwrapperhandle是在此之前初始化wrapper调用ndisminitializewrapper所得的句柄。

如果调用ndismregisterminiport不能返回ndis_status_success,必须在退出driverentry之前释放已经分配的资源(如yhfddiwrapperhandle等),故调用

ndisterminatewrapper(yhfddiwrapperhandle,null)。

这样驱动程序没能正确注册,亦不能正常运行。

第四节  网卡驱动程序对象查询与设置

如果ndis的管理实体要查询或设置一个特定的网络对象,它必须提供一个32位的oid。oid的结构如下:  图2.3.0  oid结构图

由上可以看到,oid可分为三大类:

所有ndis驱动程序都有的一般对象;  

特定介质的对象;  

特殊的与具体实现相关的对象(如多目地址表的长度)。  

一般的和特定介质的oid被记录在windows  nt  ddk中,对于这些oid  ddk文本指明了相关的对象能否通过miniportqueryinformation查询参数和通过miniportsetinformation设置参数。

oid也可被分为操作特性(如多目地址表长度参数)和统计参数(如广播包接收)。最后oid可分为必须的和可选的两种。

oid的前三个字节表明oid的不同类别,而最后一个字节确定这一类别内特定的信息管理对象。

针对于fddi网卡,被查询的oid的第一个字节为0x03。而ndis所查询的介质相关参数为:

0x03010104  oid_fddi_long_max_list_size

0x03010108  oid_fddi_short_max_list_size

0x03010102  oid_fddi_long_current_addr  

0x03010106  oid_fddi_short_current_addr

tcp/ip传输驱动程序所要查询的fddi  oid为:

0x03010102  oid_fddi_long_current_addr  

0x03010103  oid_fddi_long_multicast_list

0x03010107  oid_fddi_short_multicast_list

通过以上两阶段的查询,ndis和tcp/ip驱动程序就分别了解了网卡驱动程序对其的支持,从而进行相应的捆绑,以便数据传输时正确选择网卡驱动程序。

第五节  开发环境与调试方法

开发环境:

fddi网卡驱动程序的开发环境为nt  server  3.51,sdk,ddk  for  workstation  3.51,  vc++4.1,硬件平台为586。

调试平台:

主机为nt  server  3.51,windbg32

目标机为nt  workstation3.51  (check  944)

调试方法:

利用dbgprint把目标机上关键信息通过串口传到主机进行分析,以得出ndis驱动程序的调度机制和运转状况;

利用assert产生异常断点,由主机对异常进行控制

自定义宏,进行分级控制,以根据不同情况产生不同调试信息  

第四章  与smt移植相关的问题讨论

在本yhfddi网卡驱动程序中,smt的移植是极其关键的一部分,主要承担了驱动程序中硬件初始化和中断延迟处理。但由于smt是相对独立的软件,这样就有一个ndis  wrapper与smt间参数传递的问题。所以本章主要讨论miniport驱动程序与smt的关系和移植smt过程中初始化的要求、中断处理的要求,ndis  wrapper与smt如何传递参数。

(一)miniport  fddi网卡驱动程序与smt的关系。

在第一章已经谈及网卡驱动程序主要实现osi参考模型中的物理层和mac层。而对于fddi网络的物理层又可分为介质相关子层和介质无关子层。

对于我们的fddi/pci是基于x.3.19、x3.148、x3.166和x3.229而实现的。

smt在整个iso七层模型中属低两层范畴。下图是iso模型与fddi层次的对应关系,从而可知fddi  miniport驱动程序在nt网络结构中的位置。

即在windows  nt  fddi网卡驱动程序应包含smt,实现fddi拓扑环上的站管理。

而在驱动程序内部smt主要是在miniport驱动程序中的中断延迟处理上边缘服务中实现的,也可以说是将smt嵌入中断延迟处理程序中,实现ndis接口对smt的正确调度。

yh-fddi驱动程序的实现可分为硬件无关部分和硬件相关部分。  

移植smt过程中初始化的要求.  

这里的初始化主要是指硬件初始化,包括寄存器的初始化和数据结构的初始化,由smt共用的硬件相关例程库中硬件初始化部分来完成.  我们在开发过程序是调用fddi_main(bdd_t*bdd)这个函数来调用smt共用的硬件相关例程库的.可见使用fddi_main(bdd_t*bdd)时,需要传递bdd这个参量,而bdd_t这个数据结构的定义如下:

它包含了各类硬件寄存器的基址,所以要对其进行正确赋值就必须首先在nt的内存中映射一块虚存与网卡内存相对应,也就实现了bdd_t结构的赋值,对fddi_main(bdd_t  *bdd)的正确调用.  

因此,我们在调用fddi_main前首先将网卡上寄存器内存空间映射到nt的虚存空间上,并将bdd结构正确赋值.以映射bsi_phy_base为例,具体过程如下:

pchar  destination;

bdd_t  *bdd;

ndis_physical_address  physicaladdress;

ulong  baseaddress;

ndis_status  status;

baseadress  =0x0d0000+bsi_phy_base;

ndissetphysicaladdresshigh(physicaladdress,0);

ndissetphysicaladdresslow(physicaladdress,baseaddress);

status=ndismmapiospace(

(pvoid  *)&destination,

miniportadapterhandle,

physicaladdress,

bsi_phy_len

);

bdd->bsi_vir_base=(pchar)  destination;

adapter->  bdd->bsi_vir_base=  bsi_vir_base;  

/*对adapter结构中的bdd结构赋值,以便在其它上边缘函数中使用这些虚存基地址*/

中断处理要求.  

对于中断处理,在smt中主要调用cspintrhandandler()来实现.我们的fddi网卡驱动程序是miniport方式的,若在isr中做此处理将占用大量系统资源,使系统崩溃,所以我们采用只在isr中进行中断的排队,而在dpc中调用cspintrhandler()来完成中断处理.

在中断处理方面还有一个中断屏蔽和中断使能的问题,这两方面smt并不提供,故我们要正确处理.

具体处理方法见第三章.

ndis  wrapper与smt间参数如何传递.  

miniport方式的网卡驱动程序中,网卡上有中断时,系统反映给ndiswrapper,再由wrapper调度中断处理上边缘服务实现中断处理,在我们的yhfddi网卡驱动程序的中断具体处理是smt完成的所以在调用cspintrhandler时应将adapter结构传进smt以便在以后应用.

如在处理接收中断时,处理的最后应调用ndisindicatefddireceive,向ndiswrapper指示以接收到一个数据包,而ndisindicaterfddireceive的调用需要adapterminiporthandle作为参数,这就必须一级级从中断延迟处理函数(yhfddi  handleinterrupt)中将adapter结构传递下来.  当然,其它方面如发送,也会有类似的问题需要考虑.

总之,对于smt的移植,需要详尽的在程序中做好接口,才能实现与

smt的数据交换.

结束语

ndis规范在网络两层间提供了一个统一界面,ndis对网络本身而言,是一个带有协议功能的标准接口,对实现者而言,它应该是一个环境,这种环境不仅带有协议功能,更重要的是带有和软、硬平台无关的核心功能支持,它不会受软、硬平台的变化严重影响,无疑,它是软件的移植和兼容的可靠保证,ndis把网络的一部分共性抽象出来,并根据具体的操作系统实现系统和平台相关的基础库以保证ndis的标准性和对开发者提供最大的功能支持,这也将加速和规范开发过程,但是,在操作系统之上提供ndis基础库获得标准同时也失去直接作用于操作系统带来的灵活性以及更强的功能支持,同时,ndis处于网络中层和低层之间,低层网络的快速发展和ndis对网络部分共性的抽象必然导致ndis对实现者的滞后,例如ddk3.51提供的ndis开发环境只支持10m以太网、fddi、令牌网(802.5)、localtalk、arcnet等,而对新出现的快速以太网及atm不提供支持,这对我们如何在ndis环境下实现诸如atm的lan  emulation,ip  over  atm、快速以太网带来很大问题。

smt是实现fddi网卡驱动程序的关键,然而由于应用ddk开发miniport驱动程序时要遵循其结构框架,所以要想完整地按其结构移植smt,就必须分解smt适应之,即要求对smt有一个很好的理解。但smt是庞大的给开发带来了一定的困难。

参考文献

【1】《device  driver  kit用户手册》

【2】《device  driver  kit核心驱动程序设计》  

【3】《device  driver  kit网络驱动程序设计》

驱动程序设计篇6

引言

近年来电力行业为了快速部署变电站,采用了建造整体变电所的方法:在生产基地将变电站的内部设备安装、调试完成,只留下与外界的接口,整体运到变电站所在地后进行安装和简单调试即可投入运行。其内部设备通过CAN总线进行通信,系统原有的监控软件基于DOS系统,维护调试比较困难,因此想要寻求更方便、友好的系统支持。经过比较,嵌入式操作系统市场上风头正劲的Windows CE .NET成为最终选择。微软的最新产品Windows 提供了端对端的开发、调试手段,可以不拆卸设备的情况下通过Telnet登录到WindowsCE上进行调试和维护,其系统本身为嵌入式市场进行重新设计,包括创建一个基于WindowsCE的定制设备所需的一切。这样就需要将原来DOS下的程序移植到下,但是各个硬件厂商目前还没有提供CAN通信卡在Windows 下的驱动,所以开发Windows 下的CAN卡驱动成为项目推行中的关键一环。

本文主要针对研华的双口CAN卡PCM3680进行分析,介绍在WindowsCE.ENT系统下进行底层设备驱动开发的方法并提供CAN通信的实例。

1 CAN总线通信协议及CAN通信卡介绍

CAN总线是德国Bosch公司20世纪80年代初为解决现代汽车中众多的控制与测试仪器之间的数据交换而开的一种串行数据通信协议。它是一种多主总线,废除了传统的站地址编码,而代之以对通信数据块进行编码。这种方法使网络内节点个数在理论上不受限制,扩展格式中的29位的标识码便可以定义2 29个不同的数据块。

在本项目中使用的是研华的PCM3680,这是一块嵌入式PC104的双口CAN总线通信卡;CAN控制器采用Philips的独立CAN控制器SJA1000芯片;CAN收发器采用Philips的P82C250,可以同时操作两个CAN网络,提供高达1Mb/s的传输速度。PCM3680支持很宽的中断范围:中断3、4、5、6、7、9、10、11、12、15,同时1000V的光电隔离提供系统高可靠性。在CAN卡通信中,要用到CAN控制器中的很多寄存器,各个寄存器的含义和作用可以参考控制芯片的说明书。图1列出驱动程序设计中用到最主要的寄存器结构。

2 CAN卡驱动底层函数设计

本方案设计CAN驱动是放在Windows CE操作系统的内核下层,位于OEM adaptation layer(OAL)层的一个真正的驱动,而不是在主程序中的串口操作。在Windows CE的设备管理器可以看到CAN1和CAN2两个端口,并且可以查看其工作的正常与否和对其进行配置。如:中断号和I/O地址。

2.1 CAN卡寄存器读写函数

CAN卡的通信是通过操作CAN卡上的CAN控制器进行的。在CAN控制器中有很多寄存器,如控制寄存器、命令寄存器、状态寄存器、中断寄存器等,通过读写这些寄存器中的命令状态字可以检测和控制CAN卡的行为。在Windows 下,通过调用DOK中的API函数HalTranslateBusAddress,将CAN卡分配的物理地址映射为逻辑地址。这样各个寄存器对应的就是CAN卡基地址的偏移地址,因此,对寄存器的读写就转化为对内存地址的读写。下面是CAN卡寄存器的读写函数:

*在偏移量为off的地址读取一个字节的数据inline BYTE CANR(LPCAN_HW_OPEN_INFO hCan,DWORD off)

{

return hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr[off];

*将一个字节数据写到偏移量为off的地址中inline VOID CANW(LPCAN_HW_OPEN_INFO hCan,DWORD off,BYTE val)

{

hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr[off]=val;

}

参数LPCAN_HW_OPEN_INFO定义的是CAN卡的数据结构,其中成员lpMappeBaseAddr[0]表示的是映射后基地址,lpMappedBaseAddr[1]就是基地址+1的地址,对应CAN卡的寄存器是命令寄存器。通过上述两个函数可操作CAN卡上的所有寄存器。

2.2 CAN卡初始化

CAN卡的控制器比较复杂,在通信前必须确认硬件信息正确性、初始化各寄存器。初始化函数的基本流程如图3所示。

第一步,检查端口号和硬件信息的正确性,主要是CAN卡中断号是否有效。

第二卡,设置CAN卡默认参数:

CanCardConfigInfo CAN_DEFAULT_SETTING=

{0X00,0XFF,0X03,0X1C};/*设置默认波特率为125Kbps*/

DWORD dwThreadID =0;

PHYSICAL_ADDRESS phyAddr={hwInfo->dwIOBaseAddr *16,0 };

第三卡,用WinCE API函数LocalAlloc为CAN卡驱动中用到的数据结构分配缓冲区;通过HalTranslateBusAddress和MmMapIoSpace函数映射I/O地址,提供直接访问设备的虚拟地址:

if(!HalTranslateBusAddress(Isa,0,phyAddr,0,&phyAddr))

goto _ExitInit;

hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr=

(LPBYTE)MmMapIoSpace(phyAddr,CANCARDADDRLEN,FALSE);

if(!hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr)

goto _ExitInit;

如果分配内存或映射逻辑地址失败,则退出初始化程序,CAN卡初始化失败。

第四步,初始化读写属性、共享模式、读超时时间和第二个CAN口的基地址。

第五步,创建CAN卡事件和数据接收事件:hCan->lpCanHWInfo->hCanEvent=CreateEvent(NULL,FALSE,FALSE,NULL);

hCan->lpCanHWInfo->hRecvMsgEvent=Cre

ateEvent(NULL,FALSE,FALSE,NULL);第六步,初始化中断,如果CAN卡有复位请求就退出初始化程序。设置好中断后启动数据接收线程,设置线程优先级继续线程处理;最后配置CAN卡参数,进入正常运行状态。

2.3 CAN卡信息发送

CAN卡的信息发送分为两个步骤。在对CAN卡基本信息进行检查后,首先设置发送缓冲的ID号。CAN标准模式的ID号为11位,偏移地址10中存放的是ID号的高8位,偏移地址11的高3位存放的是ID号的低3位,剩下5位分别是RTR位(远程传送请求位)和数据长度。通过CANW函数将处理后的数据写入到相应的偏移地址,设置完相应的地址数据后,通过循环将偏移地址12~19的数据采集回来存到数组中。然后,设置CAN卡的传输请求为允许并不断侦测状态寄存器的变化,当传输缓冲满标志或传输结束标志为1时通出程序,完成一次数据采集。传输缓冲区的寄存器如表1所列。

表1

ID号10ID.10ID.9ID.8ID.7ID.6ID.5ID.4ID.3RTR,数据长度码11ID.2ID.1ID.0RTRDLC.3DLC.2DLC.1DLC.0数据1~812~19数据数据数据数据数据数据数据数据表2

ID号20ID.10ID.9ID.8ID.7ID.6ID.5ID.4ID.3RTR,数据长度码21ID.2ID.1ID.0RTRDLC.3DLC.2DLC.1DLC.0数据1~822~29数据数据数据数据数据数据数据数据CAN消息发送函数的实现如下:

BOOL CAN_SendMessage(LPCAN_HW_OPEN_INFO hCan,LPCanCardMessageBuflpMsg)

{

BOOL bSuc=FALSE;

ASSERT(hCan && lpMsg && lpMsg->dwMessageLen <=8); /*防错处理*/

if(0= =(hCan->dwAccessCode & GENERIC_WRITE))

return FALSE;

:: EnterCriticalSection(&hCan->lpCanHWInfo->

TransmitCritSec); /*进入临界区*/

BYTE byV=static_cast(1pMsg->dwMsgID>>3);

CANW(hCan,10,byV); /*设置ID值高8位*/

byV=static_cast=((lpMsg->dwMsgID & 7)<<5);

if(lpMsg->bRTR) byV|=0x10;

byV+=static_cast(lpMsg->dwMessageLen);

CANW(hCan,11,byV);/*设置ID值低3位、RTR及数据长度*/

for(UINT i=0;dwMessageLen;++i)

{

CANW(hCan,12+i,lpMsg->byMsg[i]);

} /*采集数据*/

CANW(hCan,1,1);/*重置传输请求*/

while(TRUE)

{byV=CANR(hCan,2);

if(byV & 0X40) /*传输缓冲区满,退出*/

{break;}

if(byV & 0X8){ /*传输结束,正确返回退出*/

bSuc = TRUE;

break;}

}

::LeaveCriticalSection(&hCan->lpCanHWInfo->TransmitCritSec); /*离开临界区*/

return bSuc;

}

2.4 CAN卡信息接收

CAN卡的信息接收是发送的逆过程,当接收缓冲区标志为1时,表示缓冲区已满可以接收数据,将数据接收到数组后释放接收缓冲区,然后对接收到的数据进行分解并存储到CAN卡信息缓冲区的结构体。接收缓冲区的寄存器结构如表2所列。

CAN消息接收函数的实现如下:

BOOL CAN_RecvRecvMessage(LPCAN_HW_OPEN_INFO

HCan,OUT LPCanCardMessageBuflpMsg)

{……

if(CANR(hCan,2)&1){ /*判断接收缓冲区是否已满*/

for(UINT i=0;i<10;++i)

recvBuf[i]=CANR(hCan,20+i);/*将数据暂存到临时缓冲区*/

CANW(hCan,1,4); /*释放接收缓冲区*/

LpMsg->dwMsgID=recvBuf[0]<<3; /*取出ID的高8位*/

BYTE byV =recvBuf[1];

LpMsg->dwMsgID+=byV >>5;/*取出ID低3位,然后和高8位合并*/

LpMsg->bRTR =byV &0x10?TRUE:/*返回RTR状态*/

LpMsg->dwMessageLen = byV &0XF; /*返回数据长度*/

……

}

else

{++hCan->lpCanHWInfo->dwErrorMsgCount;}/*没有收到数据,错误计数加1*/

::LeaveCriticalSection(&hCan->lpCanHWInfo->

ReceiveCritSec); /*离开临界区*/

Return bSuc;

}

2.5 CAN卡事件处理

CAN卡事件处理函数是CAN卡驱动程序中很重要的部分。驱动设计要求具有消息通知的功能,当事件发生时及时捕获事件并进行消息处理。

下面是事件处理函数的实现:

staric DWORD WINAPI CAN_EventHanle(LPVOID lpParam)

{

ASSERT(lpParam);

LPCAN_HW_OPEN_INFO hCan=(LPCAN_HW_OPEN_INFO)lpParam;

CanCardMessageBuf bufMsg;

while(TEUE)

{ /*循环等待CAN卡消息产生,然后进行处理*/

::WaitForSingleObject(hCan->lpCanHWInfo->hCanEvent,0XFFFFFFFF);

if(hCan->lpCanHWInfo->bKillCanThread) break; /*若CAN线程已关闭则中断*/

if(CAN_RecvMessage(hCan,&hufMsg)){ /*正确接收数据后*/

CAN_RecvBufPush(hCan,&bufMsg);} /*将数据压入缓冲*/

BYTE byV=CANR(hCan,3); /*将3号寄存器读出然后立即写入*/

CANW(hCan,3,byV);/*能够获取每次中断*/

InterruptDone(hCan->lpCanHWInfo->lpCanObj->dwSysIrqt);

} /*本次中断结束,等待下次中断*/

return 0;

}

2.6 其它函数

为了提供更多的功能和更方便地使用CAN卡进行通信,在CAN卡驱动程序中还设

计了一些函数如CAN_Config用CAN卡信息配置、CAN_RecvBufPop用于处理接收缓冲区、CAN_Reset用于复位CAN卡、CheckHWInfo用于硬件信息检查等。这些函数提供了对CAN通信卡的设置、检查等功能,在这里不再详述了。3 CAN卡驱动封装设计

CAN卡底层驱动函数虽然功能完整,但是对于用户使用比较复杂并且一般用户不需要了解底层实现的机制。为了便于使用,最后对CAN卡的驱动进行了封装,提供CanOpenFile、CanSendMsg等五个函数用于CAN总线的通信,以动态连接库(DLL)的形式提供给用户调用。封装函数及功能如下:

*CanOpenFile;初始化并打开CAN卡的一个端口。

*CanCloseFile;关闭由CanOpenFile打开的CAN卡端口。

*CanRecvMsg;接收CAN卡数据,打开CAN卡时必须具有GENERIC_READ权限。

*CanSendMsg;通过CAN卡发送数据。打开CAN卡时必须具有GENERIC_WRITE权限。

*CanIOControl;设置或获取CAN卡I/O参数支持的I/O控制包括:IOCTL_CAN_CONFIG,IOCTL_CAN_RESET,IOCTL_CAN_TIMEOUT,IOCTL_CAN_SENDREADY,IOCTL_CAN_RECVREADY。

下面是CanSendMsg函数实现的代码:

BOOL CanSendMSg(

HANDLE hCan,

LPCanCardMessageBuflpMsg)

{

if(!hCan||INVALID_HANDLE_VALUE= =hCan||

!lpMsg||lpMsg->dwMessageLen>8)return FALSE;

return CAN_SendMessage(LPCAN_HW_OPEN_INFO)

hCan,lpMsg);

该函数就是通过封装CAN卡的底层驱动函数SendMessage来实现的,这样将功能集中的五个函数更方便了用户使用。

结语

驱动程序设计篇7

关键字:C程序设计;任务驱动;层次教学;弹性教学

随着信息时代的来临,社会对高校毕业生的要求越来越高,基础扎实、专业面宽、动手能力强的毕业生日益受到用人单位的欢迎,其中计算机技术水平的高低是衡量人才的重要尺度。如何加强计算机基础教育,为各专业培养出具有扎实的计算机应用能力人才,是计算机基础教学亟待解决的重要课题。

C程序设计课程是国内大部分高校中绝大部分专业的必修计算机基础课。在实际的教学过程中,我们发现,如果采用传统的教学方法,如满堂灌的单项式教学法,或者按照从易到难,从简单到复杂的顺序循序渐进地进行教学,学生容易感到枯燥乏味,不能充分调动学习的积极性、课堂教学中没有突出课程本身的特色,没有给学生提供一个充分进行创造思维的空间[1]。

如果采用任务驱动模式教学,不仅教学效果好,而且非常有利于培养学生的素质和能力。

1任务驱动教学方法内容

任务驱动模式教学以学生为中心,以任务为驱动的教学方式,属于探究式教学的一种,其教学过程是:教师的教学与学生的学习围绕着一个目标,基于几项任务,在强烈的问题动机驱动下。通过对学生资源的积极主动运用,进行自主探索和互动协作的学习实践活动,适合于培养学生的自主学习能力和相对独立分析问题、解决问题能力[2]。

它是一种以学生主动学习与教师加以引导相结合的教学方法,既符合探究式的学习模式,又符合教学的层次性和实用性。它可以让学生在完成“任务”的过程中,形成分析问题、解决问题的能力以及独立探索的学习精神和与人合作的精神。

任务驱动教学法具有以下特点[3]:

(1) 任务驱动。以工作任务为中心引领知识、技能和态度,让学生在完成工作任务的过程中学习相关理论知识,发展学生的综合职业能力。

(2) 目标具体,内容实用。任务驱动教学法的教学目标清楚明确,能更好地指导教学过程,也可以更好地评价教学效果;教学内容的选择要紧紧围绕工作任务完成的需要,不求理论的系统性,只求内容的实用性。

(3) 做学一体。任务驱动教学法打破长期以来的理论与实践二元分离的局面,以工作任务为中心,实现理论与实践的一体化教学。

(4) 提高学生分析问题和解决问题的能力。

(5) 提高学生学习的主动参与意识,激发学生的学习兴趣。

2任务驱动教学任务设计

采用任务驱动法进行教学,教师教学和学生学习都是围绕如何完成这个具体的任务进行。教师教学思路清晰,学生学习目的明确,更容易掌握学习内容。

课程任务教案设计是整个任务驱动教学模式的起点和物质基础,一般来说将需要将教师教学过程中积累的授课技巧、授课方法加以总结,并巧妙地设计组合成任务场景,同时精心设计每次课的教学任务的引入以及要达到的任务目标。对于每一次上课的任务样本模型,通过设计、修改、论证和研讨,力争能够较广地反映课本概念,逻辑性强,重点突出,能启发学生思维,培养学生能力,引导学生创新。

采用任务驱动教学模式不是孤立地介绍各部分的概念、作用和操作方法,而是先宏观上将该问题作为一个大的任务呈现出来,例如在“程序设计基础―C程序版”教学中的循环程序设计里面的内容是有一节讲素数判断问题程序如何编写,教师通过讲解如何利用结构化程序编制思想让学生掌握该部分教学内容,教师可以将整个内容设计为“判断素数”这一具体的任务。首先,要完成这样一个相对复杂的任务,必须要有原始数据,然后分析其是否是素数,最后输出结论。这样,就将一个大的任务分解成为三个小任务:(1)输入任务――利用系统库函数scanf;(2)分析判断任务――需要自定义函数;(3)输出结果――利用系统库函数printf。通过教师的分析,学生对结构化程序设计中“自顶而下、逐步求精”等概念就有了直观的认识。接下来教师再讲如何判断、利用数学上的概念来实现等该任务方法。

这样教学,学生学得快、学得牢。不论对学生还是教师,整个教学过程都显得条理清楚、层次分明、顺理成章、轻松自然。

进一步地来说,学生可以在完成任务的成就感的驱使下,还可以课后自己设计与课程内容相关的其他任务,这进一步激发了学生学习的主体性和能动性。

3任务驱动教学目标实现

采用任务驱动法教学,还可以使对计算机有兴趣的同学,根据自己的兴趣爱好、能力特长,在课堂外自主地选择自己感兴趣的内容,自己摸索。计算机教学如果仅仅局限于教材所指定的软件,是远远不能满足学生对计算机知识的求知欲的,也是不能跟上计算机发展的需要的[4]。

在教学中,学生常有这样的疑问:“现在计算机软件的种类很多,为什么我们一定要学教材中指定的软件呢?这个软件到底有什么优越性呢?”教师可以将这些软件系统的优势和缺点给学生讲解清楚,让学生根据自己的情况自主选择。如针对C语言实验软件系统,习惯使用DOS系统的同学可以选择传统的Turbo C 2.0,喜欢Windows环境的同学可以使用Win TC或VC++ 6.0。

采用任务驱动法教学,学生为了完成具体的任务,一方面会认真学习教材内容;另一方面,当学生发现有些功能用教材中所介绍的方法不能令其满意时,就会尝试着寻求其他参考书或者资料来帮助解决问题。这样,就把计算机的学习内容从教材内可以延伸到教材外,学生在探索其软件的学习过程中,直观地感受到不同解决方法的区别、特点及优劣,除了掌握教材限定的书本使用方法,同时还学会了同一问题其他的程序编写方法。学生学习的内容会更多、更深,知识面会更广。

在C程序设计的实验课或者程序课程设计课堂上,教师可以根据一个班学生个体差异与他们不同基础、不能兴趣爱好基础上,对整个班级学生进行分类排队,按照一定的标准将其划分为不同的层次,可以将整个班级不同层次学生不同几组,针对每个层次的不同特点,相应地布置难易程度不同的实验任务或者课程设计任务,有针对性地加以指导。

总之,任务驱动教学法有利于实现个性化教学、分层次教学和弹性教学的教学目标。

4任务驱动教学模式应注意的问题

我们的教学目的不仅是向学生传授知识要点,更主要的是教会学生使用恰当的学习方法,激发学生学习的兴趣,为学生的终身学习做好准备。C程序设计课程采用任务驱动教学模式,其优势是明显的,但也存在一些问题。由于教师主要是进行方法的引导,学生有更多时间动手摸索,而学生的学习能力是不同的,因而在同一节课内,全班同学所掌握的程度会有所不同,容易造成学生成绩两极分化和教学知识点的疏漏。

如果课程一开始设计的任务超出学生的知识范围过高,那样反而使得学生反感、厌学,如果任务内容是前几章涉及到的程序例子内容,利用已有的知识,使得学生上手容易,这样完成任务就不成问题,学生也有成就感;同时,任务内容最好跟同学们实际生活相关,否则学生会感到枯燥等,比如指针学习任务可以设计成生活中的密码箱游戏。

运用“任务驱动”教学法于教学之中,不但要服从一般性的教学原则外,还要把握以下几个原则[5]:

(1) 任务适当原则。“任务驱动”教学法的关键就是“任务”的建立和下达,建立难度适中的任务关系到教学的成败。这个任务应该是学生通过适当努力能够完成的,所以任务设置要适当。

(2) 学会学习原则。“任务驱动”教学法,将目标定在培养学生的学习动机和能力上。在教师的指导下,使学生能根据已有的知识经验,掌握有序的学习途径,在教师的指导下去解决问题,完成任务。在完成任务的过程中学会学习。这一目标的定位,也符合目前终身学习的指导思想。

(3) 学用互促原则。“任务驱动”教学法完成教学任务的途径是通过“用”来促进“学”的,用后知不足才能学,学以致用,学用互动,相互促进。

(4) 合作交流原则。在教学中要注意个体探究能力的差异。把个体自学与群体讨论,合作探究结合起来。提供三个学习空间,把个体学习、小组学习、班级学习有机地结合起来,使学生人人参与,鼓励提出不同见解,使教学方式变成更为生动、活泼的全员探究合作教学。

5使用情况

基于任务驱动教学方法内容,是根据作者实际教学过程中学生存在的问题提出的,并最近几年的程序设计基础课程教学实践中运用,通过考试成绩和学生信息反馈,取得了比较令人满意的教学效果。

作者教授2005级学生时采用的传统的教学方法,期末考试成绩反映学生的成绩不是很理想(如图1);在教授2007级学生时使用了基于任务驱动教学方法,取得了良好的教学效果(如图2)。

对C程序设计课程使用基于任务驱动教学方法的进行教学与改革,坚持以人为本的教学理念,对提高教学质量,实现培养目标起到了促进作用。

通过作者自己的选择基于任务驱动的实践教学,发现学生不仅可以在轻松的氛围中学到很多知识,而且能够很好地把握知识点在实际任务中的应用,同时还能为使用该方法进行后续课程学习打下很好的基础。

6结语

C程序设计是一门逻辑性强、知识内在联系紧密的课程,在教学过程中不仅要精选设计教学任务,明确讲授任务重点及难点,而且要注意学生对任务的学习效果反馈情况,才能为下步如何改进完善该教学任务以达到逐步提高教学质量的目的。

任务驱动教学方法有利于激发学生的内在积极性与潜能的充分发挥;有利于培养学生分析问题、解决问题的能力,进一步提高学生的创新能力和协作能力。

参考文献:

[1] 秦玉平,沈泽刚. C语言程序设计教学法研究[J]. 渤海大学学报:自然科学版,2005,26(2):113-115.

[2] 徐肇杰. 任务驱动教学法与项目教学法之比较[J]. 职业与教育,2008(11):36-37.

[3] 章振周,唐成棉. 职业教育任务驱动课程模式的建构[J]. 中国职业技术教育,2008(6):45-46.

[4] 吴耀兴,王泽林. 工程管理专业实践教学改革探索[J]. 中国成人教育,2008(5):146-147

[5] 金春寒,郭成. 策略性知识的学与教[J]. 四川教育学院学报,2006(10):7-8.

Discussion on Task-drive Teaching Method of C Language Programming

YANG Sheng-quan, LIU Bai-lin, LIU Ping-ping

(School of Computer Science and Engineering, Xi'an Technological University, Xi'an 710032, China)

驱动程序设计篇8

关键词:任务驱动教学;VB程序设计;教学探讨;高职教育

中图分类号:TP311文献标识码:A文章编号:1009-3044(2011)14-3378-02

Application on Task-Driven Teaching Method of Visual Basic Program Design in Vocational Education

OU Gao-lin1,2

(1.Modern Education Technology Center ,Jiangsu Institute of Economic & Trade Technology, Nanjing 211168, China; 2.School of Electronics and Information Engineering ,Nanjing University of Technology, Nanjing 211816, China)

Key words: The paper is based on course content and features of VB and the mode of education with vocational education. and it studies Task-driven teaching,which is Used in teaching in VB.Teaching computer programming is designed to provide useful experience and advice, enrich teaching methods that promote the development of computer teaching.

Abstract: task-driven teaching; visual basic program design; teaching discussion; vocational education;

VB程序设计是高职院校计算机专业开设的一门专业基础课,开设这门课程的目的是让学生进行入门级编程教育,方便以后进行更深入地学习计算机编程和设计。VB程序设计的特点是界面友好,采用可视化编程技术,“所见即所得”,适合做界面设计和数据库管理。计算机编程是一件枯燥无味和繁琐的应用技术, 如果没有强烈的求知欲望和学习兴趣,编程学习难以开展和深入研究。

高职院校侧重于职业教育,生源素质参差不齐,主要是成绩中等偏下的高中毕业生和中职毕业生。通过对高职学生知识能力架构进行统计和测量分析,数据显示,高职学生普遍存在厌学心理,高考的失足是一个沉重的打击,他们对计算机编程学习有强烈的抵触情绪,没有自学意识。激发学生学习兴趣成为VB程序设计教学的首要任务。高职学生虽厌恶理论和教条,但他们乐于动手实际操作,对简单实验和数据分析非常感兴趣,这种群体教育适合开展任务驱动教学。教学实践表明,在完成一个具体项目并投入实际应用时,学生充满了成就感和自豪感,大大提高了学生的主观能动性。

1 任务驱动教学设计

任务驱动教学,是指在学习的过程中,学生在教师的帮助下,紧紧围绕一个共同的任务活动中心,在强烈的问题动机的驱动下,通过对学习资源的积极主动应用,进行自主探索和互动协作的学习,并在完成既定任务的同时,引导学生产生一种学习实践活动。它以建构主义教学理论为基础。针对任务驱动教学的特点,对课程进行总体目标、内容的整体设计、项目开发详细设计与流程分析等方面进行设置和分析。

1.1 课程的总体目标

依据“因材施教”原则,VB程序设计采用多媒体教室或电子教室教学与实训机房上机实践相结合的授课方式。学生在做中学,在学中做,以及边学边做,重点突出技能培养。在突出技能的同时,还重点讲解解决思路和方法。学生通过学习,达到课程的总体目标:

1)专业能力:了解可视化编程语言VB的特点;掌握面向对象程序设计的基本概念和方法;掌握程序设计常用算法;掌握VB的编程环境、常用的VB标准控件的基本使用方法;通过实验教学环节,熟练掌握VB可视化界面设计方法及相应编程;能够正确的阅读、分析、调试VB程序;达到能用VB设计简单的应用系统的能力。能够与他人合作组成一个小型的项目开发团队并积极主动的完成自己的工作。

2)方法能力:培养学生的协调沟通能力、活动组织实施能力、语言表达能力、项目策划能力;具备分析问题、解决问题能力;具备资料检索和阅读能力;能够使 用Office工具完成文档编写。

3)社会能力:学生能够吃苦耐劳、保持严谨细致的工作作风;具备团队协作的能力;能够熟练的进行技术交流;使命感和责任感,强烈的自学意识和自学能力。

1.2 课程内容的整体设计

在项目的设置上,把VB程序设计课程设置为9个具体开发项目,每个项目作为一个主题学习单元,项目均实行双线学习制,即课堂上教师指导学生完成一个规定项目,课外学生模仿课堂项目再完成一个自选项目。课程共设置72个学时,36个学时理论,36个学时实际操作和教师指导,每个项目占用8个学时。在课程的最后,设置一个综合项目开发的主题学习单元,与前面的学习单元不同的是,它是一个开放的项目,即需要学生自行组建开发团队,每个开发团队自行构思应用程序的类型和内容,明确软件的功能和效果,并完成应用程序的开发,这个主题学习单元可以综合培养学生的团队协作和组织能力,实现知识技术学习与能力培养一体化的目的。部分项目设置如表1。

1.3 项目开发详细设计与流程分析

通过对每个具体项目进行详细的系统分析,要开发出一个完整而实用的VB应用程序,需要经历6个典型的工作任务模式如图1。

每个工作任务模式具体描述:

1)准备工作(系统分析):确定要解决的问题;用什么方法实现;需要使用几个模块、几个窗体和每个窗体使用什么控件;使用什么算法,必要时需要画出流程图。

2)创建工程(程序设计):这是整个程序设计的重点,也是学习的难点。具体步骤:①建立用户界面;②设置窗体和控件的属性;③编写代码。

3)运行与调试(软件测试):有3种方法可以运行程序:① 执行“运行”菜单中“启动”命令;② 单击工具栏上的“启动”按钮;③ 按F5键 。若程序代码有错,会出现错误信息提示框,针对具体的错误提示,对程序进行调试分析,并排除错误。在运行程序时,对界面和数据代码进行分析和调整,达到解决具体问题的要求。

4)保存文件(存储与备份):VB的应用程序包含窗体、代码、类模块、标准模块等,所以保存文件时要分别保存窗体文件(.frm)、工程文件(vbp)、标准文件(.bas)、类模块文件(cls)等。具体步骤如下:①单击“文件”菜单中的“保存工程”或工具栏上的“保存工程” 按钮。如果是从未保存过的新建工程,系统打开“文件另存为”对话框; ②选择文件的存放位置;③给要存盘的文件命名(可以含有路径,如d:\VB程序开发\PROG1);④ 单击“保存”按钮或按回车键。

5)生成可执行文件(投入使用):操作步骤如下:①执行“文件”菜单中的“生成VB1.exe”命令;②“文件名”部分是生成的可执行文件的名字。默认的可执行文件名与工程文件名相同,其扩展名为.exe。如果不想使用默认文件名,则应键入新文件名(eg:vb.exe) ;③单击“确定”按钮。

6)对文件进行打包(制作安装程序):在用VB等语言编写并编译成程序后,往往会制作一个精美的安装程序来自己的软件。通过对行业打包软件的对比,Setup Factory打包软件操作简单,实用易学,是一款强大的安装程序制作工具。Setup Factory提供了安装制作向导界面,即使学生对安装制作不了解,也可以生成专业性质的安装程序;该软件可建立快捷方式,也可直接在 Windows 系统的注册表加入内容,还能在 Win.ini 和 System.ini 内加入设定值,更可以建立反安装选项等等;它内附的向导可以一步步的带领学生做出漂亮又专业的安装程序。

1.4 根据流程分析图,结合任务驱动教学,组织学生进行项目开发

1) 授课教师对具体项目进行需求分析,对项目作分类整理,列出项目需求分析表。

2) 针对项目需求分析表,授课教师指导学生制定项目开发的详细方案。根据项目需求表、结合所了解的资讯,组织学生分组讨论,确定任务实施方案;让学生列出任务实施的方案与步骤。

3) 组织学生按照详细方案进行项目开发。授课教师列出方案实现的重点与难点,让学生重点把握和攻克难点。创建工程(程序设计)是本次项目实践的重点,打包是项目实践的难点。

4) 参照项目需求分析表,授课教师对学生做好的应用程序和具体任务进行验收,并组织学生写出相关实验报告。可采用项目组互评、教师评价综合评判等方式进行,授课教师对各组反馈作点评,同时让学生有一个反复再实践的过程。

2 结束语

基于任务驱动模式的VB程序设计教学方法,符合国家软件人才的培养目标,采用引入知识点、讲述知识点、强化知识点、应用知识点、综合知识点的模式,由浅入深地展开对技术内容的讲述;在整体上体现了内容主导、实例解析,以点带面的模式。该教学方法以项目为主线、教师为主导、学生为主体,以能力培养为目标,并以实际工作的实例引入概念,符合学生的认知规律;以具体项目为载体设置主题学习单元,每个主题学习单元的项目相互独立,也相互关联,都包含了完整的工作过程,但项目难度是从简到繁,从易到难,循序渐进,深入浅出,承上启下,对知识和能力的要求也逐级递进,激发学生的学习兴趣,培养学生的学习能力和创造能力,打破传统的以教为中心,而是以学为中心的教学模式,激发了学生的学习积极性。

参考文献:

[1] 于鹏,李霞.中文版Visual Basic 6.0程序设计项目教程[M].北京:清华大学出版社,2010.

[2] 张凯,李妙妍,袁静.任务驱动教学法在VB语言程序设计课程教学中的应用初探[C].Proceedings of 2010 Third International Conference on Education Technology and Training(Volume 8),2010.

[3] 段旭,潘舒,易德成.任务驱动教学法在VB教学中的应用与实践[J].科技信息,2010(30).

[4] 苗h.“任务驱动教学法”在“Visual Basic”课程中的应用[J].电脑知识与技术,2005(36) .

[5] 李美满,李湘黔,易德成. 任务驱动教学法在VB教学中的应用[J].电脑学习,2010(5).

驱动程序设计篇9

USB(Universal Serial Bus)通用串行总线。1995年11月由Compaq、Digital、IBM、Intel、微软、NEC以及北方电讯(加拿大)等7家主要电脑、电子科技厂商共同开发了USB0.9标准。这是一种PC的外挂总线,诸家公司联合提出这一新型总线,是为了解决PC机设备的拥挤和提高设备的传输速度。但是,由于USB的复杂性,各公司不能及时提供必要的硬件和软件支持,这种新型的PC总线直到Windows98推出以后,才得到迅猛发展。它的市场价值才真正显现出来,人们才真正领略到它的方便与快捷。USB具有许多其他总线无法比拟的优点。这里主要就USB1.1技术做一些研究和应用。

WDM驱动模型

WDM即Win32驱动程序模型,是微软公司在VxDs之后推出的新驱动模型,运行平台是Windows98/2000/XP操作系统。WDM中驱动程序的识别是通过一个128位的GUID实现的。USB总线驱动程序由操作系统Windows XP提供,负责与实际USB总线通信。因此,USB驱动程序的开发实际上是USB设备驱动程序的设计。

WDM驱动程序有一个主要的初始化入口点,即一个必须称为DriverEntry的例程。它有一个标准的函数原型。当WDM驱动程序被装入时,内核调用DriverEntry例程。系统提供的默认驱动程序的入口处为DriverEntry,负责驱动程序的初始化,用以初始化驱动程序范围的数据结构和资源。

在AddDevice例程中,驱动程序创建一个设备对象作为目标I/O设备,并将设备对象附着到设备堆栈中,设备堆栈为每一个相关设备驱动程序包含一个设备对象。在设备被第一次枚举时,系统初始化时调用AddDevice例程。DriverObject参数指向一个驱动程序对象,就是在DriverEntry例程中初始化的驱动程序对象。PDO参数对应于设备堆栈底部的物理设备对象(PDO)。对于设备驱动程序,其AddDevice函数的基本职责是创建一个设备对象并把它连接到以PDO为底的设备堆栈中,相关步骤如下:通过调用IoCreateDevice例程创建设备对象之后建立一个私有的设备扩展对象;为了使应用程序能识别设备,需要对USB一个或多个设备接口寄存,以便应用程序能知道设备的存在。另外,给出设备名以便创建符号连接。初始化设备扩展对象和设备对象中的Flag成员;通过IoAttachDeviceToDeviceStack函数把新设备对象放到堆栈上。

即插即用(PnP)是计算机硬件和软件支持的组合,包括硬件设备、系统软件和驱动程序的支持。其功能为:对已安装的硬件进行自动动态识别;硬件资源分配;加载驱动程序;PnP使驱动程序和用户模式的代码登记,并通知一定的硬件事件。

电源管理是在系统范围内用集成的方法来使用和保存电源,包括电源管理的软硬件支持,提供以下功能:实现最小的启动和关机延迟。系统能在低电力状态时休眠,在这种状态下要恢复操作完全无须重新引导系统。从用户的角度来看,可以简单的唤醒休眠中的计算机;提高了电源效率和电池生命期。仅仅当设备传输功能给用户时电源才启用于设备,如果一个设备未使用,按照命令,电源可被断开,而后再加电;使操作更加安静。

驱动程序开发

采用DriverStudio开发USB驱动程序,必须严格遵循安装顺序:首先安装Visual C++6.0,然后安装WinXP DDK,最后安装DriverStudio。安装之后,Visual C++编程工具栏中自动添加了一个菜单DriverStudio。由于DriverWorks所用的类库是在DDK库函数基础上生成的,所以必须在Visual C++中打开DriverWorks\source目录下的VdwLibs.dsw,选择Batch Build菜单,通过Rebuild All来创建自己的库文件。

在使用DriverWorks开发工具之前,首先要设置一下DDK的路径,SetDDkGo用以创建编译驱动程序的环境,它执行一系列的操作:运行SETENV BAT;设置DriverWorks环境变量;设置开始程序的环境属性。缺设置情况下,自动调用C++编译器编译所生成的工程文件。

驱动程序设计篇10

关键词:任务驱动;程序设计;Visual Basic 运用

一、“任务驱动”教学法的特点

任务驱动是以完成任务来引导和激发学生的学习兴趣。通过布置与现实工作岗位的真实任务,让学生进行实操作训练,学习新的知识与技能。在程序设计课中体现“任务驱动”教学法,就是让学生通过完成软件开发公司的程序设计员岗位任务进行学习,在完成程序设计任务的过程中,培养学生多方面的能力。“任务驱动”教学法有以下两个特点:①“任务驱动”是一种适用于学习操作类知识和技能的学习方法。②“任务驱动”是一种适用于培养学生自学能力和独立分析问题能力的教学方法。

二、“任务”设计的具体要求

任务驱动中任务的作用,一方面任务是“导火索”,把所要学生掌握的内容设置为岗位任务,使学生通过完成任务来提高技能水平和理论知识。另一方面,学习任务的设计的另一个目的是为了允许学生可以“多途径”“不同角度”进入学习,“多途径”运用不同的学习资源进行学习,“不同角度”选择合适的任务进行操作。

(1)要有明确的目标要求。例如《VB程序设计》教学中,制作一个“电子相册”,就要明确到有“运行界面”,有“打开”“保存”“浏览”“修改”相片的功能,并要求相片存放在数据库中。

(2)任务设计应联系学生实际生活,创设适当的教学情境。在设计任务时,要尽量与丰富多彩的生活相联系,使学生能将学习到的知识真正运用到解决生活实际问题当中,给学生创设一种“在用中学,在学中用”的学习情景。多次实验表明,学生在完成程序设计员要做的工作任务时,他们会很认真、充满激情。例如制作“电子相册”,同学们平时有很多相片没有处理,现在能自己动手制作一个“电子相册”,把相片都整理在一起,既美观又能分门别类,同学们都乐意去完成这样的任务。

(3)任务设计要体现出以学生为中心,要切合学生的实际。学生学知识和技能的快慢不同。不同性格特征的学生,他们的能力差别有时很大。教师在进行布置教学任务时,要切合学生的实际,难度不能过大,要以学生通过学习新的知识和技能就能完成为宜,最初的任务要让学生先掌握方法,然后再提高难度。设置任务时要切合学生实际,根据学生现有的知识基础来设置任务,这样学生才能通过运用各种资源学习来完成任务,学生能完成的任务才符合学习特点。“电子相册”是对于有《数据库》和《程序设计》基础的学生进行布置任务的,其中用到的数据库可以是简单的ACCESS,也可以是稍难一点的SQL SERVER,任务中没作硬性规定就是为了让学生自己选择。

(4)尽可能抓住以“学生为中心、教师为主导”的原则。一般的教学方法中都是以教师为主讲,上课时学生就像听广播一样,教与学不能互动,学生不能主动用心去听,能学到的东西很有限。任务驱动教学法就不一样,整个任务的完成过程中都是以学生为中心,学生主动地学习,遇到问题就向老师和同学请教,还可以是教师和同学之间进行探讨,能增强学生的自信心和学习兴趣。因此,教师进行“任务”布置时,要以“学生为中心”,切合学生的实际。

(5)“任务”布置要兼顾学习能力强与弱的需求。“任务驱动”教学法还强调要兼顾学习能力强与弱的需求。在程序设计课程的教学中,教师进行“任务”布置时,要适当布置适合学习能力强的任务。这样布置出来的任务,既能满足大部分同学的学习需求,提高大家的技能和知识水平,也可以满足学习能力强的学生想多学知识和技能的需求。如进行网站设计等比较大的项目就需要进行“协作”学习,网站设计要涉及资料的收集与整理、动画设计、美工制作、动态页面编辑、网页功能的实现等等,要按小组布置“任务”,让小组协作完成。

三、任务教学的具体实例

实例:运用Visual Basic程序设计制作一个“电子相册”,要求有“运行界面”,可以“打开”“保存”“浏览”“修改”相片,并要求相片存放在数据库中。我首先运行自己制作好的“电子相册”作个演示,让学生有个概念,接下来就布置任务。①在Visual Basic中新建工程,把“电子相册”的界面做好,并保存。②上互联网找相关资源,下载有“源代码”并能运行的“电子相册”程序。③把下载的程序代码“移植”到自己设计的“电子相册”中。④建立用来存放相片的数据库,数据库可以选择用ACCESS或 SQL SERVER。⑤建立数据源(开始——设置——控制面板——管理工具——数据源ODBC)。⑥对代码进行调试,分四部分。(调试到能正常运行为止)。1)数据库连接部分。登录数据库的账户和密码,数据库的名称,表的名称。2)“打开”部分。运用了CommonDialog控件。3)“保存”部分。运用“流格式”(ADODB.Stream)来保存。4)“浏览”部分。运用了“ADODC”“IMAGE”和“DATAGRID”。⑦调试通过后,把程序打包生成“EXE”文件。

在完成任务的过程中,学生充满了好奇心和表现欲望,积极主动地参与实践,在“界面”制作过程中,运用自己喜欢的图片作背景,标题写上有个性的词语来突显自己的个性。以前学习的数据库都只用来存放“数字”“文字”等,对现在用来存放“相片”比较好奇,很想自己体验一番,就积极地上INTERNET寻找资料。有了界面,有了代码,有了数据,还不能体现聪明才智,电子相册要能“动”起来才引人注目。于是,学生们都很活跃地去完成一个一个的任务,争取让自己的“电子相册”早点“动”起来,就不断去探索学习。教师对每个任务都作相应的引导。学生完成后,交上自己的作品,教师和同学们一起逐个点评,评出每个任务作品的亮点和不足之处。在本实例中,我所布置的任务里只有“电子相册”的“打开”“保存”和“浏览”共三个功能,至于“修改”功能没有布置,就是留给学生自主学习的,体现个性学习的差异。因为有的学生基础比较好,有的比较差一些,所以不作为任务而让学生课后自己去完成。

本实例充分调动了学生的学习兴趣和积极性,虽然“电子相册”制作起来难度有点大,但是只要把任务细分下来,把要点都作提示,学生肯上INTERNET查找资料学习,还是不难实现的,这就体现了“任务驱动教学法”中任务设计的重要性了。学生作为学习的主体,教师只是布置任务,对学生的学习进行组织、引导。

小结:实践证明,通过学生的亲身实践与体验,才能真正培养和提高他们的计算机应用能力。而且,只有经过自身探索学到的知识和技能,才能真正做到深刻理解,扎实掌握。任务设计是实施“任务驱动”教学成功与否的关键,要去企业多了解当今社会岗位要求的能力,多布置实用的、能引起学生学习兴趣的、价值高、能实施的“任务”,让学生在完成“任务”中不断提高技能水平、理论知识和学习能力。在“任务驱动”教学中教师的作用不可忽略,教师要引导学生尽快进入自主学习状态、教师给予学生的指导要恰到好处、教师应组织学生相互帮助,互相协作。学生完成任务后,要对学生的“作品”进行点评,总结学生遇到问题时分析问题、学习知识、解决问题的方法和各种优点。

参考文献:

[1]何克抗.建构主义学习环境下的教学设

计[M].北京:北京师范大学出版社,2005.

[2]姜振安.“任务驱动”教学法与学生实践