驱动程序设计范文

时间:2023-11-14 16:55:56

驱动程序设计

驱动程序设计篇1

关键词:程序设计教学 分组 任务驱动程序设计课程要求学生具有较强的逻辑思维和细心制作的能力,计算机真实地检验学生的程序是否做得出来而且有无错漏,这些要求使许多初学程序设计的学生有畏难情绪;传统的大班式教学从讲理论到上机编程验证程序的教学方法,往往使学生所做的程序达不到学习内容要求的结果,学生编程练习错漏多,学习效果参差不齐,制作软件的创造能力得不到提升,为此我们上程序设计课采用任务驱动教学法。

“任务驱动”是一种建立在建构主义学习理论基础上的教学方法,它将再现式教学转变为探究式学习,学生的学习活动必须与大的任务或问题相结合,以探索问题来引动和维持学习者学习的兴趣和动机,教师创建真实的教学环境,让学生带着真实的任务学习;在任务驱动教学法中学生必须拥有学习的主动权,教师则不断地挑战和激励学生学习取得进步。

在程序设计课程的教学中,教师采用任务驱动教学法大多是把任务布置给学生并作简单讲解后,由学生自己看书学习完成任务,学生的创新能力和独立分析问题、解决问题的能力明显提高,但这种教学法也有缺陷,主要是学生自学太多,总体学习效率较低,学生各自为证统一性差,而且没有改变不同层次学生学习的问题,鉴于这些原因,我们可把“任务驱动”和“分组”两种教学法结合起来应用,教学效果会更好。

一、分组

1、分组前的工作

分组前要对全班各个学生的学习能力和知识基础有全面深入的了解,要发现和培养学生中的学习带头人,这个过程往往要占去全部课程学习时间的1/3左右,在分组前的教学可用不分组的任务驱动教学法或讲解——上机——点评归纳的教学法,边教学边了解学生,同时教学的进行使学生打下一定的理论基础和制作技能。

2、怎样分组

一个班级有几十个学生,可分为若干个学习小组,但分组数不宜超过5组,组数太多使每组人数太少不便于对学生作统一要求,教师兼顾太多组亦会顾此失彼;每个小组要确立一至二名学习带头人作为学习小组长,同时兼顾学生间的友情和合作,方便互相学习,好中差三类学生适当搭配完成分组。

二、任务驱动下的分组学习

1、设置任务

教师精心设置任务是教学成功的第一步,如果要学习的新知识点多,我们可把教材中的每一章设计成一个大任务,再将大任务分为若干小任务,每一节又由一个或几个小任务组成;在教材和各种参考资料中会有许多练习题,任务驱动学习要求精选习题配合新知识点学习,而不是做大量习题的“题海战术”;如果已经把大多数的新知识点学完,我们就要设置综合程序设计任务,培养学生综合运用知识技能进行程序开发设计的能力。

对于同一章节的学习或同一部分内容所设置的任务,任务可准备多个,便于把任务分配到各个学习小组使用。

2、任务的分配

在分配任务到各个小组之前,教师应招集各个小组长进行研讨学习,小组长在教师的提点下提出自己学习并完成任务的思路,教师甚至可以让小组长先行去完成任务,使小组长能更好地带领全组同学完成任务。当这些准备工作做好后,就可以把任务分发到各个小组的学生中去,要让每个学生都明确完成任务要用到的新知识点和任务要求所要达到的目的,使他们有的放矢去学习并完成任务。各个小组间的任务可以相同,也可以不同。如果任务相同,在学生学习完成同一任务的过程中,教师把各个小组完成任务的优劣进行对比讲评,在各个小组之间形成竞争,提高学习效率,同时使对全班学生的统一要求达到更好的效果。如果各个小组的任务不同,可以使全班分小组学习应用不同的知识点,各个小组完成任务后进行小组之间的交叉对比学习,最终使各个小组都能完成多个任务,全班学生接触到更广阔的知识面,取得更高的学习效率。

3、任务的完成

完成任务的过程就是学生学习运用知识点进行程序设计的过程,在这个过程中学生是学习的主角,因为教师在之前已经培训了各个小组长,他们在各个小组学生学习完成任务的过程中要起到以点带面的作用,其实由已经学会了的学生去教那些正在学习的学生会有不错的教学效果。教师在这个过程中要做的就是督促和鼓励学生去完成任务,当然,对于学生的典型问题教师可以分小组或在全班进行讲解,保证不会因为“卡壳”造成学习效率的降低。

当各个小组的任务完成到一定程度时,教师要及时调用学生的程序,在全班进行演示点评,造成班级中各个小组之间一种竞争为了更好地完成任务的态势,同时也是小组之间相互借鉴学习的机会。通过这样的学习并完成任务的过程,各个学生按任务要求所做的作品既有个人的创造性,又能达到任务要求的统一标准,学生作品的水平普遍比其它教学方法要高得多。

4、任务的总结和测试

许多使用任务驱动教学法的教师并不重视对学生完成任务和学习情况的总结,认为这样做浪费学生的学习时间,其实这是一个误区。尽管教师在学生完成任务的过程中已经对各个学习小组所做的任务进行点评比较,但在每部份的任务完成后,教师再次对学生作品进行演示评价,并找出学生作品中的典型案例作为样板,进而对所学习和运用到的知识点做归纳是必要的,这样做会使任务驱动下的分组学习法的教学效果得到升华,承上启下为后继内容的学习和完成更多的任务打下基础。任务驱动分组学习法强调学生之间的互助学习,会造成一些学得差学生的依赖性,甚至有的学生把组内别人的作品抄袭复制上交了事,所以教师的还有一个重要任务就是在各个任务学习和任务制作阶段完成后对学生进行测试,这样教师才能掌握各个学生的学习情况,也使得学生看到自己的差距,激励学生把差距变成学习的动力,特别是测试后发现差生,就要由学习小组长帮助他们学习,以达到共同进步的目的。

驱动程序设计篇2

关键词:MCP2515 嵌入式Linux 驱动 CAN

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

1系统硬件结构介绍

本系统的硬件平台主要由OK2440开发板、基于MCP2515的CAN总线通信模块和以STC89C52为控制器的CAN节点模块组成。CAN通信模块用来完成OK2440开发板和STC89C52控制的节点模块之间的数据传输。

1.1 MCP2515功能简介

MCP2515是一款独立的CAN总线控制器,完全支持CAN V2.0B 技术规范。MCP2515 拥有六个验收滤波寄存器和两个验收屏蔽寄存器,通过它们可以过滤掉总线上不需要的报文,从而减少MCU关于处理CAN总线上无用数据的开销。MCP2515与MCU 的连接是通过业界标准串行外设接口来实现的。

1.2 TJA1050功能简介

TJA1050 是介于CAN控制器和物理总线之间的一种符合ISO 11898标准的高速CAN收发器。其最高速率可达1Mbit/s,而且它的电磁抗干扰EMI性极高,至少可以连接110个节点。在实际电路中,可为物理总线提供差动发送和为CAN控制器提供差动接收。

2 MCP2515相关驱动程序设计

2.1 Linux设备驱动简介

在Linux系统中,由于对硬件的操作必须处在特权模式下,在用户工作模式下,程序一般不能直接和硬件进行通信。因此,设备驱动程序则承担了用户模式下硬件和用户应用程序之间的通信工作,同时它还为应用程序和内核中其他的部分访问这些设备提供了程序接口。大多数设备驱动程序可以在系统工作时,以动态方式进行加载,在不需要的时候又可以将其卸载掉。

2.2 MCP2515驱动程序设计

2.2.1 MCP2515驱动初始化函数

在MCP2515的驱动初始化函数中首先通过s3c2440_spi_ioremap()函数将S3C2440上的SPI寄存器的物理地址映射到内核空间,这样才可以在驱动程序中访问和配置S3C2440的SPI寄存器。在正确的配置S3C2410的SPI寄存器后,通过s3c2440_spi_init()来完成对S3C2440相关寄存器的赋值。然后通过s3c2440_irq_init()函数来完成中断方面相关的设置。MCP2515_init()和MCP2515_dev_init()两个函数主要是针对于MCP2515控制器进行相关的配置和为MCP2515设备驱动程序申请和初始化内存空间。最后通过MCP2515 _cdev_register(Device0)函数完成MCP2515在内核中的注册。

2.2.2 MCP2515相关中断函数的注册

在CAN总线驱动程序中,CAN通信模块接收和发送数据必须以中断的方式与系统内核之间进行数据的交换,所以在MCP2515的驱动程序中必须用到内核中的相关中断函数。对于MCP2515的中断注册函数request_irq(),如果此中断注册函数返回值为0则表示中断注册成功,返回负数则表示注册失败。

2.2.3 MCP2515的文件操作函数

MCP2515_fops中定义了很多与设备有关的操作函数,内核可以通来它来访问与MCP2515操作有关的函数。在MCP2515的文件操作函数中,read()和write()两个函数是用来完成读写CAN总线上数据的功能的,通过传递不同的参数给驱动程序中的read()和write(),我们可以读取和写入相应的数据。驱动中的CAN总线读函数read()是整个驱动程序设计的难点,其中在函数的设计中采用了Linux内核阻塞机制。read()读取完CAN总线上的数据后,通过验收滤波寄存器和屏蔽滤波寄存器来决定总线上的数据帧是否存入到总线控制器相应的接收缓冲寄存器里。

2.2.4 MCP2515的卸载函数

当我们不需要继续使用某个设备时,我们可以将这个设备从内核中卸载掉。在设备的卸载过程中,必须将其内核中所对应的设备号释放掉。在模块的卸载函数中,我们通过调用int unregister_chrdev_region(unsigned int major,const char *name)函数来完成设备驱动的卸载。此函数的两个参数分别对应设备文件的主设备号和设备名。在卸载模块时,Linux内核会把设备名与内核中已注册的设备名称进行对比,如果两者相等,则完成设备的卸载,反之则卸载失败。MCP2515的驱动卸载函数主要是完成MCP2515驱动在内核中所占用的中断的释放和MCP2515在内核中的注销。

3 结语

本文重点讨论了S3C2440中MCP2515的驱动程序设计方法,并详细介绍了Linux系统下如何开发MCP2515的驱动程序的方法。实验结果表明,本文所设计的Linux下MCP2515驱动程序可以在OK2440开发板上正常运行,基本可以完成CAN总线上数据的正常发送与接收,测试结果符合论文的要求。本文提到的基于Linux下MCP2515驱动程序的开发,对其他Linux驱动程序的开发具有一定的启示作用。

参考文献

[1]宋宝华.Linux设备驱动开发详解[M].北京:人民邮电出版社,2008.

[2]杨庆华,张景元.单片机和MCP2515的CAN总线通信模块设计[J].单片机与嵌入式系统应用,2007.

[3]刘淼.嵌入式系统接口设计与Linux驱动程序开发[M].北京:北京航空航天大学出版社,2006.

收稿日期:2016-03-04

驱动程序设计篇3

关键词:PowerPC;FPGA;设备树文件;U-Boot;Linux内核;FPGA驱动程序

中图分类号:TP368.1

基于TCP/IP体系结构采用Ad hoc技术的无中心节点的自组无线网络结构,具有自组能力、良好的抗毁性、机动性、鲁棒性和易于构建,能很好满足在军事、抢险、应急通信等复杂环境中对无线通信系统的需求[1]。

国外针对采用Ad hoc技术的无线传感网络通常使用IEEE 802.15.4(Zigbee)技术、IEEE 802.15.1(蓝牙)技术、IEEE802.11a/b/g/n(WiFi)技术、IEEE 802.16(WiMax)技术等[2]。而针对采用Ad hoc技术的应急无线通信网络通常使用Zigbee技术、WiFi技术和非公开的无线技术。基于Zigbee技术和WiFi技术的自组网络的终端传输距离受限,无法实现长距离、在高速运动中的数据传输。基于PowerPC+FPGA的无线系统实现长距离、在高速运动中的数据传输,能很好的满足军事和应急通信对无线通信系统的要求。

本文基于PowerPC+FPGA平台设计一种FPGA驱动程序来实现一路无线信号的发射和一路无线信号的接收,使用设备树文件来配置FPGA网络MAC地址、FPGA访问地址、中断信息等硬件配置信息,MAC地址保存在U-Boot环境变量中,U-Boot在引导Linux内核启动之前把MAC地址添加到设备树文件中。

1 FPGA驱动设计与实现

1.1 PowerPC平台硬件架构

基于PowerPC+FPGA的无线系统由网络基带板、射频板和背板组成,网络基带板和射频板通过背板连接。网络基带板实现操作系统的支持,FPGA实现无线通信的链路层和物理层以及无线信号的收发控制。射频板实现一路无线信号的发射和接收。网络基带板使用Freescale公司的MPC8536E处理器,提供256MB的Nor Flash存储空间,512MB的DDR2 SDRAM内存空间,两个RS232接口,两个千兆以太网接口,一个PCI总线接口,一个miniPCIe接口,三个USB host接口。FPGA使用Xilinx公司的XC5VLX110T,提供32Mb配置文件存储空间,使用LVDS信号接口和RS232接口与射频板进行通信。MPC8536E通过eLBC局部总线与FPGA通信,预留PCIe总线和eSPI接口。见图1系统硬件架构图。

1.2 PowerPC平台的统软件架构

操作系统选择开源的嵌入式操作系统Linux,引导程序选用开源的引导程序U-Boot。根文件系统选择Ramdisk文件系统。U-Boot选择u-boot-200908的版本,Linux选用2.6.32-rc5的版本。

随着Linux/PowerPC内核的发展,把32位和64位PowerPC内核代码合并,使用一个OpenFirmware式的固件接口设备树来支持所有的PowerPC平台,在这之前大多数PowerPC的嵌入式系统使用板卡特定数据结构在引导程序和Linux内核之间进行数据传递,引入设备树简化了Linux/PowerPC内核启动顺序[1]。U-Boot使用设备树文件把硬件配置信息传递给Linux内核。Linux/PowerPC内核对每个硬件平台都定义一个machdep_calls数据结构,内核在启动时调用probe_machine()遍历“.machine.desc”代码段,并调用machdep_calls数据结构相应的.probe()函数,每个.probe()检查设备树并返回真,确定设备树支持该硬件平台[1]。使用设备树的大多数嵌入式PowerPC平台使用of_platform平台总线,of_platform平台总线是一个软件注册的虚拟总线。Linux内核平台代码使用of_platform_bus_probe()遍历设备树的一部分,为其中的每个设备分配和注册一个数据结构of_device。反过来设备驱动程序使用数据结构of_platform_driver来注册,of_platform平台总线负责匹配设备和驱动程序。

1.3 FPGA网络驱动设计与实现

1.3.1 FPGA网络驱动的设计

Linux系统将设备分为三种类型:字符设备、块设备和网络设备,字符设备和块设备都是面向数据流的,通过/dev目录下的设备文件来访问,Linux系统中字符设备和块设备的区别在于驱动程序和内核之间的接口,字符设备使用数据结构file_operations的成员函数与Linux内核通信,而块设备使用数据结构block_device_operations的成员函数。网络接口是由内核中的网络子系统驱动,负责数据包的发送和接收,因此网络驱动程序是围绕数据包的传输和接收而设计的[2]。内核主要调用数据结构net_device_ops的成员函数来实现内核和网络驱动之间的数据传输。而在数据结构net_device_ops中的成员函数中调用内核提供:netif_start_queue、netif_stop_queue、netif_wake_queue、netif_rx等函数。网络接口必须使用数据结构net_device来注册,在与外界进行数据包的交换时调用,网络设备既响应来自内核的发送数据的请求,也要异步地接收来外部的数据包,并向内核请求把从外部接收到的数据包传送给内核,网络驱动程序还支持管理任务比如设置MAC地址、修改传输参数以及维护流量和错误统计等[2]。

FPGA驱动程序需要实现一路无线信号的收发控制,为了实现有线网络和无线网络之间的路由转发,因此按照网络驱动来设计。FPGA网络驱动程序主要包括定义网络设备私有数据结构,网络设备访问方法和FPGA寄存器访问方法,驱动模块注册和注销函数,中断处理函数。其中网络设备访问方法的实现主要通过数据结构net_device的成员数据结构指针netdev_ops的成员函数来实现。

(1)定义网络设备私有数据结构。FPGA通过eLBC局部总线与MPC8536E通信,FPGA既是一个网络设备,也是一个局部总线上的设备。FPGA网络设备私有数据结构既包含网络设备数据结构net_device指针,也包含设备数据结构of_device指针,同时也要包含mii_if_info数据结构、自旋锁、信号量、sk_buff_head数据结构、work_struct数据结构等变量,定义如下:

2 实验测试

2.1 点对点测试

两台无线系统平台通过网络和串口分别连接两台Linux系统的计算机,两个无线系统平台之间通过空口连接,使用iperf命令进行数据接收和发送测试:测试结果显示:流量运行平稳,都在10Mbps以上,满足设计要求。

2.2 自组网测试

四台无线系统平台实现Ad hoc自组网,其中2台无线系统经过2跳进行流量测试:测试结果显示:流量运行平稳,都在1Mbps以上,满足设计要求。

3 结束语

本文设计的FPGA驱动程序合理高效,支持一路无线信号的发射和一路无线信号的接收,实现了无线系统之间点对点进行通信,四台无线系统实现了Ad hoc自组网络。在后续的研究中,优化FPGA网络驱动程序,支持四路无线信号的发射与接收。

参考文献:

[1]Grant Likely,Josh Boyer.A Symphony of Flavours:Using the device tree to describe embedded hardware[R].Ottawa,Canada:Linux Symposium,2008.

[2]Corbet J,Rubini A.魏永明,耿岳,译.Linux设备驱动程序[M].第3版.北京:中国电力出版社,2006.

[3]常关羽,许晴.Ad Hoc环境下基于稳定链路的语音通信系统设计与实现[J].小型微型计算机系统,2011(01):107-111.

[4]JeroenHoebeke,IngridMoerman,BartDhoedt and Piet Demeester,An Overview of Mobile Ad Hoc Networks:Applications and Challenges[J].Journal of the Communications Network,2004(07):60-66.

[5]Bernard Sklar.徐平平,宋铁生,叶芝慧,译.数字通信――基础与应用[M].北京:电子工业出版社,2010.

[6]MPC8536E PowerQUICC III Integrated Processor Hardware Specifications[M].Rev.5 05/2011 Freescale.

[7]MPC8536E PowerQUICC III? Integrated Processor Reference Manual[M].Rev.1 05/2009 Freescale.

[8] PowerPC? e500 Core Family Reference Manual[M].Rev.1,2005,Freescale.

[9]EREF 2.0:A Programmer’s Reference Manual for Freescale Power Architecture? Processors[M].Rev.0,2011,Freescale.

[10]SreekrishnanVenkateswaran.宋宝华,何韶然,史海滨,吴国成,译.精通Linux设备驱动程序开发[M].北京:人民邮电出版社,2010.

[11]王齐,Linux PowerPC详解[M].北京:机械工业出版社,2007.

[12]CHRISTIAAN BENVENUTI.夏宏,阎江毓,黄景昌,译.深入理解Linux网络技术内幕[M].北京:中国电力出版社,2009.

[13]DANIEL P.BOVET & MARCO CESATI.陈莉君,张琼声,张宏伟,译.深入理解Linux内核[M].北京:中国电力出版社,2007.

作者简介:杨柏松(1973-),男,天津人,本科,广电事业部嵌入式技术总监,助理工程师,研究方向:嵌入式系统。

驱动程序设计篇4

windows nt是一个功能全面的操作系统,具有完全集成式的连网能力,它的网络模型开始于mac子层,网络接口卡(network interface card以后简称网卡或nic)驱动程序驻留在其中。通过相关的网卡把windows nt与网络连接起来,但一直到80年代后期,许多传输协议的实现受限于mac层接口的独特实现,因为mac层定义了协议与网卡之间的转换机制。

1989年,microsoft和3com两公司提出了一个定义mac层与osi模型高层协议驱动程序之间的网络设备接口规范(network device interface specification : ndis),ndis给数据交换提出了一个灵活的环境,它规范了软件接口──称为ndis接口,传输协议可用它与网卡驱动程序进行通信。因此在windows nt环境下开发核心态网卡驱动程序应遵循ndis规范。

对于高速网络fddi(fiber distributed data interface)网卡驱动程序还需要smt(station management)站管理功能的实现,否则将不能作为一个fddi站连入环结构中,只能实现点到点间的数据通信。故有必要将smt软件移植到网卡驱动程序中,这将又导致对miniport nic驱动程序编程框架的破坏,于是有必要形成fddi网卡驱动程序(包含smt)与windows nt操作系统的良好接口──由逻辑网卡的注册和mac层驱动程序的初始化来完成。

所以,本课题旨在深入研究应用microsoft公司的ddk(device driver kit)将smt移植于windows nt的fddi网卡驱动程序过程中如何注册miniport nic驱动程序。即怎样正确注册逻辑网卡和mac驱动程序的初始化。着重讨论与初始化相关的上边缘函数的使用和调用关系以及初始化过程中遇到的各种问题的具体解决。

第一章windows nt环境下fddi网卡驱动程序

总体结构介绍

第一节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网络驱动程序设计》

【4】《windows nt核心内幕》

驱动程序设计篇5

关键词Windows CE;YAFFS;NAND;驱动开发

中图分类号 TP311.1文献标识码A文章编号 1674-6708(2009)05-0054-02

0 引言

Windows CE是微软公司设计的嵌入式操作系统,具有系统体积小、界面友好、可扩展、应用程序开发上手快等特点,目前,在手持式测量设备领域的应用越来越多。手持式振动信号测量仪是一种电池供电、便于现场或野外携带和使用的测量设备,主要功能是对振动信号进行实时连续的采集、显示、分析、处理和存储。

1 YAFFS文件系统简介

YAFFS是一种类似于JFFS/JFFS2的专为NAND Flash设计的嵌入式文件系统,适用于大容量的存储设备。和JFFS相比,YAFFS减少了一些功能,但是速度更快、占用的内存更少、NAND Flash的使用寿命也更长。YAFFS文件系统采用层次结构设计,可分为三层:文件系统管理接口层、YAFFS内部实现层和NAND Flash接口层。

2 YAFFS NAND Flash接口层

YAFFS NAND Flash接口层的主要功能就是为文件系统管理接口层、YAFFS内部实现层提供一个与具体NAND Flash硬件无关的访问服务,提高了代码的可移植性和通用性。在对NAND Flash接口层相关代码进行深入的分析后,我们发现为了使YAFFS能够对NAND Flash进行访问,必须为NAND Flash提供一个块设备驱动程序。与NAND Flash物理访问相关的代码全部由其实现,而YAFFS则是通过给该设备驱动程序发送IOControl请求来实现对NAND Flash的读、写、擦除等具体操作,具体来说,主要有以下几个操作请求:

1)IOCTL_DISK_NAND_INIT 功能是命令NAND Flash驱动程序对Flash芯片进行初始化。

2) IOCTL_DISK_NAND_GETSIZE 功能是获取NAND Flash的存储容量(磁盘空间)。

3) IOCTL_DISK_NAND_GETNAME 功能是获取设备在Windows CE中显示的文件夹名称。

4) IOCTL_DISK_NAND_GETPARTITIONS 功能是获取NAND Flash中的分区表。

5) IOCTL_DISK_NAND_WRITE 功能是将缓冲区中的数据写到NAND Flash中的指定页中。

6) IOCTL_DISK_NAND_READ 功能是读取指定的页的数据。

7) IOCTL_DISK_NAND_ERASE 功能是从NAND Flash中的指定块擦除。

3 Samsung K9K8G08U0A Flash

目前,在嵌入式系统领域广泛使用的Flash主要有两种:一种是采用NOR技术的NOR Flash,另一种是采用NAND技术的NAND Flash。这里重点介绍一下NAND Flash,首先,从内部存储器的组织形式上看,NAND Flash的内部可分为若干个块,块又分为页,页而由数据存储区和备用区两部分组成;其次,NAND Flash不能按照字节进行访问,而是以页为单位进行读、写,以块为单位进行擦除;第三,NAND Flash的地址、数据、命令端口复用,读、写、擦除等操作都是相应的命令来完成的。

SAMSUNG的K9K8G08U0A NAND Flash内部共有8192个块,每个块有64个页,每页包含2048字节的存储空间和64字节的备用空间,总容量为1G字节。K9K8G08U0A的以页为单位进行读和写,以块为单位擦除,其典型的随机页读时间为25us、顺序页读时间为25ns、页写时间为200us、块擦除时间为1.5ms。

4 K9K8G08U0A块设备驱动程序的实现

Windows 环境下的块设备驱动程序一般都实现为流接口驱动的形式,即流接口驱动需要的XXX_Close、XXX_Deinit、XXX_Init、XXX_IOControl、XXX_Open、XXX_PowerDown、XXX_PowerUp、XXX_Read、XXX_Seek 、XXX_Write都要实现,XXX表示设备名前缀,这里可以是“DSK”。由于YAFFS的NAND Flash接口主要是通过IOControl的形式实现的,所以,相应的与K9K8G08U0A读、写、擦除等操作相关代码也都在DSK_IOControl函数内实现。下面给出DSK_IOControl的部分程序代码:

DSK_IOControl的部分程序代码如下:

BOOL DSK_IOControl(……)

{

switch (dwIoControlCode)

{

case IOCTL_DISK_NAND_WRITE:

NandRePage(pDisk,pBufData,pBufSpare,ifData->chunk);break;

case IOCTL_DISK_NAND_READ:

NandReadPage(pDisk,pBufData,pBufSpare,ifData->chunk);break;

case IOCTL_DISK_NAND_ERASE:

NandEraseBlock(pDisk,*BlockNumber);break;

}

}

具体的读、写、擦除等操作分别由NandReadPage、NandWritePage、NandEraseBlock三个函数按照Samsung公司K9K8G08U0A的时序规范来实现。

5 结论

本文在深入研究YAFFS文件系统的NAND Flash接口后,给出了Windows 环境下Samsung的K9K8G08U0A NAND Flash块设备驱动的实现方法,并给出了关键程序代码。

驱动程序设计篇6

摘 要:本文主要介绍在Vxworks操作系统下网络设备驱动程序设计、调试方法以及将其加入系统内核的配置方法。

关键词:Vxworks 嵌入式操作系统 网络设备

引 言

VxWorks操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS),是嵌入式开发环境的关键组成部分。良好的持续发展能力、高性能的内核以及友好的用户开发环境,在嵌入式实时操作系统领域占据一席之地。它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。

1 嵌入式系统

嵌入式系统是以嵌入式计算机为技术核心,面向用户、面向产品、面向应用,软硬件可裁减的,适用于对功能、可靠性、成本、体积、功耗等综合性严格要求的专用计算机系统。和通用计算机不同,嵌入式系统是针对具体应用的专用系统,目的就是要把一切变得更简单、更方便、更普遍、更适用;它的硬件和软件都必须高效率地设计,量体裁衣、去除冗余,力争在同样的硅片面积上实现更高的性能。

嵌入式系统主要由嵌入式处理器、硬件设备、嵌入式操作系统以及特定的应用程序等四部分组成,是集软硬件于一体的可独立工作的“器件”;用于实现对其它设备的控制、监视或管理等功能。

嵌入式系统应具有的特点是:要求高可靠性;在恶劣的环境或突然断电的情况下,要求系统仍然能够正常工作;许多嵌入式应用要求实时处理能力,这就要求嵌入式操作系统(EOS)具有实时处理能力;嵌入式系统中的软件代码要求高质量、高可靠性,一般都固化在只读存储器中或闪存中,也就是说软件要求固态化存储,而不是存储在磁盘等载体中。

2 设备驱动程序

Vxworks5.4中驱动程序主要分为三种:字符、块以及网络驱动程序。本文所介绍的网卡驱动程序则属于网络设备驱动程序。

2.1 网络设备驱动程序设计

网络的各功能部件图1所示,网络设备驱动程序实际上是处理硬件和上层协议之间的接口程序。网络传输协议层分发数据在应用程序接口和网络接口之间。网络化网络协议(如IP协议)发送数据在网络主机之间。连接/接口层使能主机隶属于硬件到相同物理媒质的通信。

在Vxworks5.4中,网卡驱动程序又分为END(Enhanced Network Driver)和BSD两种。它们分别处于如图2所示结构中。

2.1.1 BSD驱动程序设计

在Vxworks5.4中,网络驱动程序都是基于BSD UNIX版本4.3基础上的,这些驱动程序都定义在一个全局例程中,那就是attach子程序,__attach( )子程序中包含5个函数指针,它们都被映射到ifnet结构中,这5个函数可见表1,它们在IP协议层任何地方被调用。

表1 网络接口处理

驱动程序指定函数

函数指针

功能

__Init( )

if_init

初始化接口

__Output( )

if_output

对要传输的输出分组进行排队

__Ioctl( )

if_ioctl

处理I/O控制命令

__Reset( )

if_reset

复位接口设备

__Watchdog( )

if_watchdog (optional)

周期性接口例程

驱动程序入口__attach( )调用ether_attach( )来把上述5个函数映射到ifnet结构中,ether_attach( )调用如下:

ether_attach(

(IFNET *) & pDrvCtrl->idr,

unit,

"__",

(FUNCPTR) NULL,

(FUNCPTR) __Ioctl,

(FUNCPTR) ether_output( ), /* generic ether_output */

(FUNCPTR) __Reset

);

pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)__TxStartup;

上述参数中,需要一个接口数据记录(Interface Data Record (idr)),unit号和设备名,下面四个参数就是相关驱动程序的函数指针。第一个函数指针指的是init( )例程,这个例程可要可不要,第二个函数指针指的是ioctl( )接口,它允许上层来控制设备状态;第三个函数指针指的是把数据包送到物理层;最后一个函数指针指的是如果TCP/IP堆栈决定需要复位的话,它就复位这个设备。

接着下面那一句代码表示添加数据传输例程到IDR,ether_output( )例程被调用后,传输开始例程就被TCP/IP协议堆栈调用。

在这个入口驱动程序中还包括设备的初始化、发送和接收描述符的初始化等。

2.1.2 END驱动程序设计

END驱动程序是基于MUX模式,网络驱动程序被划分为协议组件和硬件组件。MUX数据链路层和网络层之间的接口,它管理网络协议接口和低层硬件接口之间的交互;将硬件从网络协议的细节中隔离出来;删除使用输入钩例程来过滤接收从协议来的数据包,和删除了使用输出钩例程来过滤协议包的发送;并且链路层上的驱动程序需要访问网络层(IP或其他协议)时,也会调用相关的MUX例程。值得注意的是,网络层协议和数据链路层驱动程序不能直接通讯,它们必须通过MUX。如图3所示:

2.3

将驱动程序加载到Vxworks系统中要对所设计的驱动程序进行测试,首先就必须把驱动程序加载到Vxworks IMAGE中,并且给设备分配一个IP,这样才能有利于网间测试。

首先,修改configNet.h文件,添加如下代码:

#ifdef INCLUDE_DM_9102_END

#define DM_9102_BUFF_LOAN_0 1

#define DM_9102_LOAD_FUNC sysDm9102EndLoad

#define DM_9102_LOAD_STR_0 ""

IMPORT END_OBJ * DM_9102_LOAD_FUNC (char *, void *);

和END_TBL_ENTRY endDevTbl [] 中添加

#ifdef INCLUDE_DM_9102_END

{0, DM_9102_LOAD_FUNC, DM_9102_LOAD_STR_0, TRUE, NULL, FALSE},

#endif /* INCLUDE_DM_9102_END */

其次,编辑config.h文件,添加如下代码:

#define INCLUDE_DM_9102_END /* Davicom 9102 Fast Ethernet Controller */

最后,编辑sysLib.c文件,添加如下代码:

/* include dm9102 End driver support routines */

#ifdef INCLUDE_DM_9102_END

IMPORT STATUS sysDm9102PciInit (void);

#endif /* INCLUDE_DM_9102_END */

/* include dm9102End driver support routines */

#ifdef INCLUDE_DM_9102_END

#include "sysDm9102End.c"

#endif /* INCLUDE_DM_9102_END */

#ifdef INCLUDE_DM_9102_END

sysDm9102PciInit ();

#endif /* INCLUDE_DM_9102_END */

通过上述过程相应的添加程序,然后重新编译Vxworks,这样就将所设计的网卡驱动程序添加到Vxworks内核中了。

2.4 PCI设备检测

如果所设计的网卡是基于PCI总线的,那么在程序开始就需要对PCI设备进行检测,在Vxworks5.4中有专门的PCI函数来检测设备的总线号、设备号和功能号。首先利用pciFindDevice( )函数对给定VendorID和DeviceID的设备进行检测,检测完后同时给出了设备的总线号、设备号和功能号;接下来就是获得该设备的中断号、基地址(包括IO和内存)。Vxworks中pciConfigLib.h文件中定义PCI总线的常量。如中断号:PCI_CFG_BRG_INT_LINE,IO基地址:PCI_CFG_BASE_ADDRESS_0,内存基地址:PCI_CFG_BASE_ADDRESS_1等等。所以利用函数pciConfigInByte和pciConfigInLong就可以很容易地获得设备的中断号和基地址。

2.5 调试方法

为了方便调试网卡驱动程序,推荐利用串口对程序进行下载并将Vxworks image拷贝到软盘中以从软盘来加载它。调试的时候首先应该给网卡分配一个IP(利用usrNetIfConfig函数),然后利用ping来对网卡进行测试。

3 结语

驱动程序设计篇7

关键词:项目驱动;实践;解决问题

作者简介:胡萍(1978-),女,湖北黄冈人,浙江理工大学科技与艺术学院现代教育技术中心,讲师;蓝庆青(1982-),女,畲族,浙江丽水人,杭州市十三中教育集团(总校),讲师。(浙江 杭州 310000)

基金项目:本文系浙江理工大学科技与艺术学院高等教育教学改革与研究重点教改项目(项目编号:kyjg1207)、浙江理工大学科技与艺术学院专业建设项目(项目编号:Kyjgzy1302)的研究成果。

中图分类号:G642.0     文献标识码:A     文章编号:1007-0079(2014)14-0141-02

程序设计课程在计算机科学教育中的重要性是毋庸置疑。目前大部分高校在程序设计教学中多采用传统的讲授法和系统的学习,同时结合一些上机实践操作来巩固和熟悉课堂上所讲的知识点,但是这种讲授和系统学习有许多缺点,它以教师为中心,偏重向学生灌输知识,重理论轻实践。

项目教学法是以实现“项目”工程来进行教学的方法,在项目教学法中,教师根据课程教学目标和教学内容的需要,通过设置具体项目,引导学生参与分析、讨论、表达等活动。让学生在具体的问题情境中积极思考,主动探索,以提高教与学的质量与效果,从而使学生在解决问题的实践中理解知识,掌握技能,学会应用,培养学生提出问题、分析问题和解决问题的能力。

一、“.NET程序设计”课程的项目驱动教学

1.“.NET程序设计”课程教学现状

.NET是功能强大、应用广泛的程序设计技术,但是其概念多、实践性强、涉及面广 。传统的程序设计语言教学通常以知识点的层次递进为体系,按照语法、程序结构、数组、过程、控件、文件、数据库等知识点层次递进方式来展开教学。

学生在以往的学习过程中普遍存在以下问题:第一,学习难度大。学生一般在学习“.NET程序设计”前,对“面向对象程序设计”接触不多,存在着从结构化程序设计到面向对象程序设计思想的转变,传统的教学方式对面向对象和设计模式思想的培养关注不够,对一些复杂的概念如委托、反射等学生感觉不易接受,导致课程学习效果不佳。第二,学习缺乏主动性。学生对于学习长期处在被动接受过程中,缺乏主动性,无法满足教育的“自助式”学习目标。第三,实践动手能力差。“.NET程序设计”每次实验的章节知识针对性强,而应用价值不高,并且很难把课程的整体串联在一起。传统的教学只重视理论知识的教学,对学生自身实践动手能力的重视程度不足。另外,由于没有系统地经历软件项目的开发过程,知识容易淡化。

2.“项目驱动教学”思想的提出

项目驱动教学法是指通过实施一个完整的项目工作而进行的教学活动,通常采取小组讨论、协作学习的方式进行。项目驱动教学法是教育领域中一种比较新的教学方法,近年来很多程序设计方面的课程开始吸收并实践这一教学方法。

利用项目驱动教学模式来进行“.NET程序设计”这门课程的教学,紧紧围绕一个个项目任务,使学生在强烈的解决问题动机的驱动下,通过对学习资源的积极主动应用,进行自主探索的学习。项目驱动教学法重点强调学生动手能力和综合知识应用的培养,强调学生的主体作用,充分实现教与学的互动。教师运用项目驱动教学法引导学生自主地、探索性地学习,在完成任务的同时,使学生在实际参与和体验中感悟知识,并通过教师的总结把这些知识内容化为自身的程序设计能力。

项目驱动教学中所研究的项目,都来自于学生能够接触到的实际案例,一旦掌握就能够解决真正的项目开发中的实际问题。通过项目作为驱动的方式,学生能更好更快地掌握“.NET程序设计”所需要理解的知识,同时提高学生对语言的熟练程序和规范性,培养学生良好的软件职业素养,为将来真正的项目开发打下基础。

(1)通过案例项目提高学生学习程序设计的兴趣。一般而言,人学习的动力有两种,一种是兴趣,一种是目标。为兴趣而学习是学习的最高境界。[1]因此,教研教改的突破口在于发挥学生的主动能动性和培养提高学习兴趣。

“项目教学法”中的典型工作任务,从给出项目任务到项目分析,从项目准备到着手完成任务学生都是主体,完成任务所需要的知识是在教师的指导和提示下学生逐一学习完成的,这一特点改变了传统教学由老师主宰整个课堂而学生被动学习的弊端,能充分调动学生的学习主观能动性,解决了部分学生学习不主动,没兴趣,甚至是厌学或旷课的问题。显著的变化是绝大部分学生都参与到完成任务的学习中来,在学习实践中培养学习兴趣,享受成功的快乐。

(2)通过项目掌握教学中的重点和难点。“.NET程序设计”课程是实践性较强的一门重要的专业必修课。这门课程涉及到不少抽象的概念,有不少同学在学习的时候会碰到一些障碍。这个时候,如果能够将抽象的概念和难懂的概念融入到一些生动实际的模拟项目中,就可以使复杂问题简单化,抽象的理论具体化,从而有效地化解教学中的难点,加强学生对相关概念的理解。

(3)通过项目提高学生动手解决问题的能力。项目教学法是以自适应学习理论和探索性学习架构为基础,采用类似科学研究与实践的方法,促进学生自主学习、自主发展的一种新型教学方法。[3]在项目驱动的特定教学环境中,学生在实际项目的驱动下,带着问题进行理论知识和开发技术的学习,在项目实践中问题求解能力和处理复杂任务的能力得以锻炼。

二、“项目驱动”教学的实施探索

“.NET程序设计”涉及的内容广泛,在设置好项目后重点考虑如何将项目划分成多个功能模块,再将模块分解成子模块,直到每个小模块可通过各个知识点来讲解。“项目驱动教学”的目的是培养学生提出问题、分析问题、解决问题的能力。

1.精心设计模拟项目,提出问题

在项目驱动模式的实施过程中,首先是项目的设置,其要点如下:第一,项目内容应基本涵盖教学的知识点,并且是学生感兴趣的,激起学生掌握知识的兴趣;第二,项目的难度要适中,保证大部分学生能够在思考和尝试之后能完成;第三,项目完成应能看到具体的效果,学生经摸索完成后有成就感;第四,项目应该具有一定的实用价值,让学生感受到学习的意义。

在项目开始初期,教师可利用各种方法给学生提供参考学习资源。因此,需要针对每个项目整理所需的背景知识、参考案例、项目要求、开发规范等。

2.“项目模块”设计

通过功能模块分解将一个综合项目划分成相对容易实现的各个子模块,不仅可以使得各个知识点分阶段融入到模块中,学生在完成项目模块的同时也掌握了相关教学知识点,又可以树立学生完成任务的信心,了解项目实施方法和过程,充分调动学生的积极性和主观能动性。

3.“项目驱动”教学的实施

在项目的进行过程中,遵循尽量依靠学生自身的能力和团队的协作来解决遇到的困难。但由于学生的经验和知识有限,教师有必要在项目的关键阶段进行适当的指导,并对设计过程中出现的偏差进行及时的纠正。

三、“项目驱动”教学模式的特色与创新之处

第一,采用项目驱动教学法进行“.NET程序设计”课程的授课,把相关的知识点融入到项目的各个环节中去,从而达到在实践中学习知识、培养能力的目的。

第二,对课本上的知识点进行了重新组织和安排,而不是机械地按知识点从头讲到尾。根据知识点的难易程序、实用性以及与实践项目的关系密切程度,有针对性地进行讲解,强调学以致用。

第三,项目的完成主要依靠学生自身的能力,教师仅在一些关键阶段进行适当的指导。重点培养学生独立分析问题、解决问题的能力。

第四,在成绩评判过程中,把学习的实践能力的成绩纳入到课程的考核成绩中。要求学生撰写实践报告,在报告中要求学生对项目的分析、设计、测试等过程进行阐述。

第五,注重培养学生的团队合作精神。稍大一些的项目可以几个学生合作完成,要求学生自主探究与协作学习相结合,即要求学生发挥主动性与创造性,又要与小组成员充分的沟通交流。

四、结束语

“项目驱动”教学模式注重理论和实践的结合,激发学生的学习兴趣。另外,“项目教学”的分析过程能够帮助全面掌握课程知识点的难点和重点,起到事半功倍的效果。“项目驱动”教学给教师的教学能力提出了比传统教学方法更高的要求,要求不仅有扎实的理论知识,而且还要有丰富的实践经验,才能发挥教师在教学中的引导作用,从而提高教学质量。

参考文献:

[1]李萍.浅谈项目教学法[J].企业导报,2011,(10).

[2]秦绪玲.浅谈项目教学与研究性学习的整合[J].中国职业技术教育,2013,(7).

[3]荆伟.项目教学在计算机实践教学中的应用[J].学园,2013,(9).

[4]章晔.项目教学和任务驱动法在中职计算机基础教学中的应用[J].计算机光盘软件与应用,2013,(7).

驱动程序设计篇8

    cpci总线机械特性上有vme总线的坚固特性,在数据传输方面采取与pci一致的传输方法。高速数据采集系统中,总线数据传输能力要求强,数据采集系统采用cpci总线,极大提高了数据采集卡的数据传输能力。为了充分发挥cpci总线数据传输快、高可靠的优势,要解决好基于cpci总线的数据采集卡与计算机主机之间的通信问题。windows2000操作系统对cpci总线提供良好的支持,该操作系统下,驱动程序的编写基于一种新的驱动模型wdm(windows driver model),wdm为windows98/2000/xp操作系统的设备驱动程序的设计提供了统一的框架。本文介绍的基于cpci总线的高速数据采集卡用于某数字化仪(digitizer)中,借助用driverworks开发的wdm设备驱动程序,用户应用程序和数据采集卡之间相互通信,实现主机命令的即时传送和板卡采集数据的高速传输。

2  硬件系统设计     针对不同的应用要求,cpci接口卡设计采用的设计方案,一是使用pci专用接口芯片与fpga相结合的方案,专用接口芯片完成从pci总线到本地用户总线的转接;fpga灵活的转换逻辑时序,以适应不同的外设时序要求;二是采用可编程逻辑器件实现通用pci总线接口,很多生产可编程逻辑器件的厂商都提供经过严格测试的pci接口功能模块,由用户进行简单的组合设计即可。考虑到开发周期,本cpci数据采集卡采用前一种设计方法,用pci专用接口芯片实现。系统硬件组成如图1所示。     本数据采集卡pci接口芯片选用plx公司的pci9054, pci9054提供两个独立的可编程dma控制器,有两个dma通道,每个通道均支持block(块传输)和scatter/gather(散/集传输)的dma方式,pci总线端支持32位/33mhz;本地端可编程实现8、16、32位数据宽度,传输速率最高可达到132m字节/秒。本地总线端时钟最高可达50mhz,支持复用(j模式)和非复用的32位地址/数据(c模式)。pci9054工作方式有:直接主模式,直接从模式和dma模式。直接主模式由本地处理器访问pci总线上的i/o接口和计算机内存资源,本地处理器发起数据的传输。直接从模式指pci总线作为主控设备发起对本地总线资源的访问,包括对本地处理器的控制和对本地内存的访问。dma模式支持pci总线与本地总线之间的突发传输。pci9054实现了pci总线到局部端总线的转接,用该芯片做设计时,不必对pci规范作全面深入理解,方便用户在设计时专注于具体功能的实现。     本设计中pci9054设置为非复用的32位地址/数据,即c模式,采用直接从模式和dma方式分别传输主机命令和数据采集卡采集到的数据;可编程逻辑器件fpga里边配置一个fifo作为缓冲器,当主机向数据采集卡发送命令时,fifo作为命令数据的缓冲器,命令数据发送完毕,引起dsp的一个中断,dsp从fifo里读出命令数据,对命令解析,完成实际的硬件操作;当主机要读取数据采集卡采集到的数据时,dsp对sram中数据作预处理,上传到fpga里边配置的fifo中,这时fifo作为数据采集卡上传数据的缓冲器,当fifo数据满时,引起pci中断,通知上层应用程序读取数据。eeprom中存放设备号,厂商号以及本地总线的基地址空间,i/o空间,中断控制信号等信息,初始化时,系统将eeprom配置参数装入pci配置寄存器,并根据本地总线对内存,i/o端口和中断的需求统一划分,自动分配系统资源。 3  数据采集卡wdm驱动程序设计 3.1  wdm模型(windows driver model)简述     wdm模型(windows driver model) 是微软公司为windows98和windows2000的驱动程序设计的一种架构,在wdm驱动程序模型中,每个硬件设备至少有两个驱动程序。其中一个为功能驱动程序,它了解硬件工作的所有细节,负责初始化i/o操作,处理i/o操作完成时所带来的中断事件,为用户提供与设备相适合的控制方式;另一个驱动程序为总线驱动程序,它负责管理硬件与计算机的连接,总线驱动程序由操作系统提供。window2000 系统结构图如图2所示,应用程序调用windows子系统win32 api,这个调用由系统服务接口作用到i/ o 管理器,i/ o 管理器进行必要的参数匹配和操作安全性检查,然后由这个请求构造出合适的irp(i/o request package) 。irp是ddk定义的一个数据结构,具有丰富的成员,对于单层驱动程序,直接接受并执行这个请求包,完成对硬件的操作,从而完成i/ o请求工作,并将执行的结果通过i/ o 管理器返回应用程序;对于多层驱动则将驱动程序分成若干层,每层驱动再把i/ o 请求划分成更简单的请求,以传给更下层的驱动执行。

图2   windows2000 系统结构   3.2  驱动程序设计实现     该数据采集卡驱动程序完成以下功能:应用程序控制数据采集卡工作方式,向数据采集卡工作方式缓冲器发送工作方式控制字;应用程序查询数据采集卡工作状态,从数据采集卡工作状缓冲器读取工作状态字;为了使应用程序能实时处理数据采集卡上采集到的数据,sram与主机内存之间要实现dma方式的数据传输。     采用vc+ddk+driverworks进行驱动程序开发,driverworks为驱动程序开发提供向导,可以方便的建立一个驱动程序框架。下面分别说明控制命令和dma方式传输数据的实现方法。     1)主机发送数据采集卡控制命令实现     driverworks利用kmemoryrange和kiorange实现内存和i/o映射空间的读写,通过配置eeprom,将pci9054的base2空间设定为一个内存映射空间,局部端fpga上配置的fifo地址空间映射到该内存空间,这样对fifo的访问,就是访问base2空间。驱动程序中,创建对象kmemoryrange m_memoryrangeforb2,并在onstartdevice(kirp i)例程中对该对象初始化,使该对象与base2空间关联,初始化以后,驱动程序其他例程就可以使用对象

m_memoryrangeforb2,调用kmemoryrange类的成员函数ind、inw、inb、outd、outw、outb完成对pci9054 base2空间的双字、字、字节的输入输出操作,也就是对数据采集卡fpga里边fifo双字、字、字节的输入输出操作。对io端口的访问类似,只是使用的是kiorange类来完成。     需要注意的是pci9054 base0、base1固定设置为内存映射空间和i/o映射空间,用于pci9054内部寄存器的访问,base2、base3用户自己根据eeprom配置来设定为内存映射空间或者i/0映射空间。在驱动程序设计过程中,经常需要设置和查询pci9054内部寄存器,访问pci9054内部寄存器,要用到base0或base1空间,本设计中,对pci9054内部寄存器访问利用base1,即io映射空间,比如:pci9054 dma通道0传输字节数寄存器偏移为0x8c,若要设定dma通道0一次传输的字节数,可以通过初始化了的kiorange对象m_iorange0的成员函数outd来实现。     下面以主机由驱动程序向数据采集卡发送工作方式控制字为例,说明kmemoryrange成员函数访问硬件的方法,代码中m_memoryrangeforb2为kmemoryrange对象,用于base2空间的访问。 ntstatus dzdevice::dzdriver_ioctl_write_handler (kirp i)  {     ntstatus status = status_success;     pulong  pbuffer=(pulong)i.ioctlbuffer();//输入参数     ulong   m_offset=*pbuffer; //控制字寄存器在局部地址空间上的偏移     ulong     m_data=*(pbuffer+2) ;//控制字     m_memoryrangeforb2.outw(m_offset,m_data);//向寄存器写控制字     i.information() = sizeof(ulong); //本次操作传输的字节数     return status; }     驱动程序控制字写函数中,首先取得从应用程序传递的偏移地址和控制字的指针,偏移地址和控制字存储在irp的associatedirp域中systembuffer指针指向的缓冲区,驱动程序先取得指向该缓冲区的指针,然后分别取得偏移地址和控制字,最后向该偏移地址写控制字,程序执行后,即向硬件上的寄存器写入了相应的控制字。     2)dma方式读取fpga上fifo数据实现     driverworks提供了3个类kdmaadapter、kdmatransfer、kcommondmabuffer用于实现dma操作,kdmaadapter类用于建立一个dma适配器对象,说明dma通道特性和提供串行化访问的服务;kdmatransfer类用于启动,控制dma的传输以及dma传输结束后数据由公用缓冲区拷贝靠应用程序数据缓冲区;kcommondmabuffer类用于申请系统提供的公用缓冲区。driverworks中,实现dma传输过程如图3所示。

    首先在设备启动例程(onstartdevice)中创建一个kdmaadapter类实例且在适配器对象描述表中正确描述适配器对象;创建一个kcommondmabufer类实例,调用该类的成员函数initialize初始化公用缓冲区大小;创建一个kdmatransfer类实例,并初始化为使用公用缓冲区作为dma数据区。然后编写kdmatransfer回调函数ondamready,回调函数中,先调用成员函数byteremaining(),判断数据是否传输完成。若完成,则调用函数terminate()完成相应当irp;未完成,则调用gettransferdescripters(),获取当前传输数据的物理地址,传输字节数,然后进入startdma例程设置pci9054的dma寄存器,开始真正数据传输。当前段传输完成时,pci9054的dma中断控制器产生一个dma中断,进入中断服务例程(isr),中断服务例程中,首先判断是否为dma通道的中断,然后禁止本次中断,再清除本次中断,最后连接到延时过程调用(dpc)。延时过程调用(dpc)中,调用kdmatransfer类的continue()成员函数,继续下一个段传输,直到dma数据传输结束,完成该irp。

上一篇:外交思想论文范文 下一篇:体育保险范文