设备驱动

2024-07-04

设备驱动(精选十篇)

设备驱动 篇1

Solaris 10是一款多任务处理的分布式企业网络系统,最初运行在SUN公司的SPARC系列芯片之上。最多4万台Solaris 10网络操作系统组合成的企业网络计算环境可以集中用一台工作站来进行统一管理,Solaris操作系统一直以稳定和强健的特性在Unix多路计算机处理领域占有重要的地位。Solaris使用Motif图形用户接口以及NFS、NIS、ZFS等网络文件系统,目前版本的Solaris 10也可运行在x64处理器架构的计算机上。在Solaris和Linux系统中,设备驱动的用途和目的相同,就是为系统提供一种控制和连接设备的一种手段,通常情况下,使用者连接设备是通过标准的I/O命令进行系统调用:比如open,close,这些系统命令调用了设备驱动程序。另外,操作系统也会自动调用相关的程序去处理错误和连接那些可能存在于系统中的不同的总线结构。此外许多系统管理相关的命令也可能调用设备驱动程序。因此掌握Solaris的设备和设备驱动管理是在Solaris系统下编程必不可少的过程。

2 系统结构和设备树

Solaris使用设备树来表示它的设备。每一个设备树上的节点表示一个设备。设备树显示了设备在系统的物理位置。使用者和程序能够通/devices和prtconf命令显示设备驱动。下面就是一些例子。

在上面的例子中列出的就是设备的名字,比如/devices/pci@0,0/pci-ide@7,1表示了这是一个系统总线的(或者是主板的)PCI控制器,并且PCI总线是在一个PCI-IDE桥结构中。设备在的设备树上名字有2部分组成,@之前的部分表示设备的名字,@之后到‘:’的部分表示接口编号和设备在总线的位置。而设备驱动的名称在‘:’之后。Linux不管设备的位置和硬件都使用相同的名字表示。比如Linux不管硬盘是IDE还是SCSI接口都表示为/dev/hda,/dev/hdb,等等。Solaris以3种不同的方式表示物理和逻辑设备:物理设备名称,物理设备文件和逻辑设备文件。物理设备名称很容易识别,因为他们是一组很长的字符串,提供了与设备的物理安装相关的所有细节。而位于/dev目录下的物理设备文件是用物理设备名字的缩写得到的实例名,这个名字可以给内核解释。实例名到物理设备的映射关系不是固定的,在/etc/path_to_inst文件中总是会包含着他们之间的对应细节。实际上的设备驱动的文件存储在devices目录之下。

值得注意的是:无论是LINUX还是Solaris 10都使用了名为devfs的设备文件系统来管理设备。这意味着设备驱动自身就可以创建和删除节点。在Solaris中,驱动通过调用在attach(9f)h和detach(9f)设备驱动文件夹中的ddi_create-minor(9f)和ddi_remove_minor_node(9f)指令来完成创建和删除。与之相对应的在Linux初始命令中的devfs_mk_dir(),devfs_mk_cdev(),和devfs_mk_bdev()和清除命令中的devfs_remove()可以完成对节点的创建和删除。虽然Linux没有使用到devfs,但是它通过调用在驱动中的或在register_chrdev()中mknod()方法,或者其他相关的程序,或者手动创建了设备文件。在Solaris10之前的Solaris没有devfs,所以它的驱动通过使用ddi_create_minor_node(9f)来创建和删除节点,无论是硬盘驱动还是网络驱动。

这是一个例子:

“driver not attached”(“驱动未联接”表示)没有驱动,即该设备未被使用并且并且驱动没有载入。或者硬件已经给配置好了但是物理上不存在。可使用prtconf-D去为已存在的设备寻找合适的驱动。

Solaris对设备和总线分别驱动,以扩展传统的设备驱动程序管理的功能:一个设备驱动控制一个设备的硬件,一个总线连接驱动程序在两类不同的总线中控制和转换数据。那些设备可能附属有其他的设备(通常通过一个总线)使用连接驱动程序连接。举例说包括总线控制器,象PCI-Host总线桥,PCI-PCI桥等等。叶节点驱动主要是给没有额外的附加设备的设备准备的。包括虚拟设备,网络设备,显示卡和存储设备等等。大部分的系统中的设备都是叶节点设备。

叶节点设备驱动支持字符设备和块设备。比如说块设备是一些可寻址的可复用的数据硬盘。其他的一些设备能够以字符设备的形式执行。硬盘驱动既是字符设备也是块设备。一些关联的设备有一个字符设备可以像关联驱动一样执行。

3 设备和驱动类型

许多总线驱动允许ioctl(2)使用基础的叶节点驱动结构和整个程序。SCSI主机总线适配器(一个在系统中负责转换许多总线的设备,比如PCI等等)和一个SCSI是一个关联节点的格式,它们被开发用来处理SCSI HBA的问题,叫做SCSA(SUN通用SCSI结构)下面来简单的描述一下不同类型的设备和设备驱动结构是如何支持不同类型的设备。

3.1 总线适配器(SCSI,IDE等等)

网络驱动SCSA(SUN通用SCSI结构)使得开发者不需要知道HBA控制器的是如何管理SCSI的就可以进行驱动的开发(比如硬盘,磁带机,扫描仪,等等)。同样的HBA驱动也不需要知道目标设备在SCSI总线的情况。

下面是一个关于SCSA自适应目标和HBa驱动共同工作的例子。所有的工作从SCSA的CSSI_部分开始执行。注意:这里不是一个完整的过程。

3.2 网络驱动

SOLARIS使用流消息在不同的网络协议栈部分中转递数据包。值得注意的是SOLARIS10已重写了TCP/IP以至于TCP和IP已不是分开的流模块。这样做的目的主要是因为性能的原因。参看FIReengine在SOLARIS的描述得到更多的细节。

在SOLARIS中,一个网络驱动必须能认知流形式并且符合DLPI规格表。DLPI(数据连接提供者接口)是一个流数据连接的规格(网络控制器)驱动。因为流和DLPI添加了许多复杂的功能用于写一个网络驱动。SUN公司开发了通用局域网驱动用来屏蔽DLPI和大部分来自于网络驱动的流。

3.3 USB驱动

SOLARIS使用了一个类似于LINUX的方式来支持USB驱动。

4 编译和安装

我们可以使用SUN公司的编译器编译。步骤如下:

#cc-xarch=v9-D_KERNEL-O-c foo.c<---xarch=v9 needed for SPARC

#cc-xarch=v9-D_KERNEL-O-c bar.c<--compile each.c file for your driver

#ld-r-o foobar foo.o bar.o<--create a relocatable object,foobar

<--dependencies on other kernel modules

<--can be specified with-Ndrv/module

<--for example,ld-Nmisc/scsi...

<--for a scsa-compliant driver

在安装驱动的时候,拷贝可重定位的模块到相关的目录下面(通常是/usr/kernel/drv,/kernel/drv,or/kernel/`uname-m`/kernel drv。在SPARC中,驱动在SPARCV9的子目录中。如果你的驱动有DRIVE.CONF文件,则驱动文件在DRV目录下面。拷贝结束以后使用命令DEVFSADM(1M)或者ADD_DEV(1M)配置驱动)。

#cp foobar/usr/kernel/drv/sparcv9/foobar<--no sparcv9 for x86

#cp foobar.conf/usr/kernel/drv/foobar.conf

#

#add_drv foobar

#<--any output here is probably an error!

#

安装完驱动之后,你可以在设备树中找到设备文件。

5 调试

SOLARIS系统中有四种基本的调试工具:

MDB:模块调试器。它为调试程序提供了一个完整的可定制的环境,其中包括一个动态模块工具程序员可以使用它来实现自己的调试命令,从而完成对特定的程序的分析。每个MDB程序可以在在运行中或者故障后不同的上下文中检查程序。这一套内置的MDB模块可以帮助程序员调试Solaris内核和相关的设备驱动和内核模块。

KMDB:运行时的内核调试器。它允许你在运行的系统的内核中设置中断点断点并设置单步运行。它可以调试运行中的内核和内核系统崩溃转储。它也可以控制和调试运行中的用户进程和用户的核心转储。kmdb扩展了调试器的功能,增加了对内核执行指令的控制。而mdb只能观看内核的运行。我们可以在控制台的命令行上用mdb的-k选项启动kmdb。当我们遇到solris启动时的挂起或者是系统崩溃时就可以使用内核调试器来收集问题的资料。我们可以在启动时使用-k选项来调用内核调试器。但是它不是"安全"的,因为在kmdb工作的时候,它完全控制了系统,当它追踪时系统完全暂停了。它做微观分析,允许用户观察每条指令的执行,允许用户观察和改变处理器的状态。

DTRACE:动态追踪工具。它被设计在较高的层面上追踪它在函数层面工作,从而对运行中的系统的影响最小的。

CMN_ERR(9F):和Linux的printk()相似的输出功能。

6 总结

通过本文我们了解了SOLARIS是如何管理驱动,并且对使用相应的Solaris的服务器自带的工具包去编译和调试驱动有了认识,同时也比较了linux和Soalris在设备和设备驱动管理上的区别。这将在Solaris系统下编程有很大帮助。

摘要:通过对Solaris基本的驱动规格的研究,介绍了Solaris下的设备驱动器和设备配置,比较了Solaris10和linux2.6环境下设备驱动配置的异同。文章涉及的大部分内容可以在早期的版本中使用。

关键词:设备,设备驱动,Sun Solaris10,Linux

参考文献

[1]McDougall R,Mauro J.Solaris Internals[M].Beijing:China Machine Press,2007.

[2]McDougall R,Mauro J,Gregg B.Solaris性能与工具[M].北京:机械工业出版社,2007.

[3]Winsor J.Solaris参考手册[M].北京:人民邮电出版社,2000.

linux设备驱动程序开发总结 篇2

学习驱动程序也不例外,我学的第一个驱动程序就是“hello world!” 具体的程序代码如下:

#include

#include

MODULE_LICENSE(“Dual BSD/GPL”);

static int hello_init(void)

{

printk(KERN_ALERT“Hello, world!n”);

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT“byby FriendyARM mini2440!n”);

}

module_init(hello_init);

module_exit(hello_exit);

将其复制到工作目录下,并编写一个简单的Makefile文件:

由于每个人使用的Linux系统不一样且每个人内核源代码所存放的位置也不是一样的。所以编写Makefile文件的时候,参考别人的进行修改是一个很不错的的学习Makefile文件的方法。当然你能把Linux内核的Makefile文件了解一下,对你了解Linux内核有很大的帮助的。

学习心得:

1、驱动模块运行在内核空间,运行是不能依赖任何函数库和模块连接,所以在写驱动程序的时候

所调用的函数只能是作为内核一部分的函数。

2、驱动模块和应用程序的一个重要不同是:应用程序退出时可不管资源释放或者其他的清除

工作,但模块的退出啊哈念书必须仔细撤销初始化函数所做的一切,否则,在系统想重新引导之前某些

东西就会残留在系统中。

3、处理器的多种工作模式其实就是为了操作系统的用户空间和内核空间设计的,在Unix类的操作系统

中只是用到了两个级别:最高级别和最低级别。

4、要十分注意驱动程序的并发处理。在Linux驱动程序中必须解决的一个问题就是多个进程对共享资源的并发访问.Linux对解决并发访问可能导致的竟态问题提供了几种机制:中断屏蔽、原子操作、自旋锁、信号量等机制。

5、内核API中具有下划线(__)的函数,通常是接口的底层组件,应该慎用。

6、内核代码不能实现浮点运算。内核中没有提供一套进行浮点运算的完整的环境。

7、Makefile文件的分析:

obj-m := hello.o 代表了我们要构建的模块名为hello.ko,make会子啊该目录下自动找到hello.c文件进行编译。如果hello.o文件是有其他的源文件生成(比如file.1和file1.c)的,则在下面加上:

hello-objs := file.o file1.o......(其中用红色标志的是对应关系)$(MAKE)-C $(KERNELDIR)M=$(PWD)modules

其中-C $(KERNELDIR)指定了内核源代码的位置,其中保存有内核的顶层makefile文件。

M=$(PWD)指定了模块源代码的位置

modules 目标指向obj-m变量中设定的模块

8、insmod使用公共内核符号表来解析模块中未定义的符号,公共内核符号表中包含了的、所有的全局内核项(即函数和变量的地址),这是实现模块化驱动程序所必须的。

9、Linux使用模块层叠技术,我们可以将模块划分为多个层次,通过简化每个层可以缩短开发周期。如果一个模块需要向其他模块导出符号,则使用下面宏:

EXPORT_SYMBOL(name);

EXPORT_SYMBOL_GPL(name);

符号必须子啊模块文件的全局变量部分导出,因为这两个宏将被扩展为一个特殊变量的声明,而该变量必须是全局的。

10、所有的模块代码都必须包含下面两个头文件:

#include

#include

11、所有模块代码都应指定所使用的许可证:

MODULE_LICENSE(“Dual BSD/GPL”);

12、初始化和关闭

初始化的实际定义通常是:

staticint _ _init initialization_function(void)

{

/*初始化代码*/

}

module_init(initialization_function)

清除函数的实际定义是:

static int _ _exit cleanup_function(void)

{

/*清除代码*/

}

module_exit(cleanup_function)

13、还有一些是可选的其他的描述型的定义:

MODULE_AUTHOR(“");

MODULE_DESCRIPTION(”“);

MODULE_VERSION(”“);

MODULE_ALIAS(”“);

MODULE_DEVICE_TABLE(”");

这些模块的声明习惯性的放在模块程序的最后面。

14、Linux内核模块的初始化出错处理一般使用“goto”语句,通常情况下很少使用“goto”,但是出错处理是(可能是唯一的情况),它却非常的有用。

在大一学习C语言的时候,老师就建议不要使用“goto”语句,并说很少会用到,在这里遇到第一个建议使用“goto”语句的。在追求效率的代码中使用goto语句一直是最好的错误恢复机制。下面是我截下来的一段关于使用goto语句实现错误处理的程序:

struct something*item1;

struct somethingelse*item2;

int stuff_ok;

void my_cleanup(void)

{

if(item1)

release_thing(item1);

if(item2)

release_thing2(item2);

if(stuff_ok)

unregister_stuff();

return;

}

int __init my_init(void)

{

int err=-ENOMEM;

item1= allocate_thing(arguments);item2= allocate_thing2(arguments2);if(!item2||!item2)

goto fail;

err= register_stuff(item1, item2);if(!err)

stuff_ok= 1;

else

goto fail;

return 0;/* success*/

fail:

my_cleanup();

return err;

内容驱动还是语言驱动 篇3

【关键词】内容驱动 语言驱动 高校大学英语教学 思考分析

英语教学在我国高等院校开展时间较长,但是总体教学质量较低,随着教育制度的改革,在高校英语教学方面的改革力度较大,这些改革都是为了进一步提高高校英语教学水平,在高校英语教学中,有些院校采用的是内容驱动,而有些高校则采用的是语言驱动,对于这两种不同教学模式,不同的学者有不同观点,而如何正确处理高校英语教学中的内容驱动还是语言驱动,成为了影响高校英语教学效果的重要因素。本文主要就我国高校大学英语教学中的内容驱动以及语言驱动等问题进行相关分析,具体如下:

一、高校大学英语教学现状分析

在上个世纪90年代后期,大部分高校在英语教学中采用了双语教学,同时教育部也颁发了相关的规章制度,这些都是为了进一步的提高高等院校英语教学效果,从而培养出综合性的人才。早期高校的英语教学中,英语作为一门语言工具,实际教学中高度重视英语教学的实际应用能力,也就是重视英语本身语言的学习。而双语教学的提出,要求在传统英语语言教学基础上,进一步强化英语内容的学习,实现两者的完美融合,尽管如此,但是现阶段大学英语教学仍然存在着较多的问题,具体分析如下:

1.没有明确的英语教学目标。高等院校英语教学目标是进行英语教学的前提,而且在明确英语教学目标的基础上才能根据实际要求不断的完善教学方法,调整教学内容。实际大学英语教学中对于英语教学目标的列举并不是很明确,缺乏具体性的以及针对性的要求。虽然高等院校的英语教学大纲经历了多次的修改,而且每次修改有明显改变的地方,但是对于教学大纲的认识仍然存在着不足,早期的教学大纲中对于教学目标的描述重点在学生学习阶段的听说读写能力,而后期的教学大纲中对于教学目标要求学生具备英语方面的综合应用能力。综合能力的具体内涵并没有给出明确的描述,不明确的目标如何保证英语教学效果。

2.教学与考试要求的混淆。高校英语教学效果主要是通过考试进行检测的,但是仅仅依靠考试并不能完全真实的反映出学生的学习效果。从单纯的考试方面分析,大学生普遍认为的就是六十分万岁,而且从学生角度分析,学生更看中的是考试要求,教师看中的是教学要求,学生在英语学习中绝大多数学生的思想都是能顺利通过考试,通过国家统一的四六级考试就可以了,教师在教学中则是按照教学要求进行实际的教学,对此,从不同的角度分析,高校英语教学中的教学要求与考试要求存在较大的差异,在这种情况下,往往是各有偏倚,造成实际高校英语教学效果较差。

3.英语教学内容以及要求的衔接不紧密。英语教学经历了小学英语教学、初中英语教学、高中英语教学以及大学英语教学,甚至还有后期的继续深造英语教学学习。每一个英语教学阶段结束后,需要与下一阶段的英语教学有效衔接,但是实际上英语教学过程中的衔接不紧密,高中阶段的英语教学重点在与词汇量的积累、各种语法语态的学习以及基本的英语表达等。大学阶段的英语教学更加重视的是文化意识、学习策略以及文化交流等。此外,在课程设置上也出现了差异,高中英语教学课时较多,但是大学英语教学课时减少,而且对于学生自主学习的要求较高,自主性较差的学生,起学习效果较差,相对于高中阶段的英语教学,设置出现了退步的表现。这些都是英语教学中不同时间段衔接不紧密造成的。

二、高校英语教学中的语言驱动以及内容驱动

1.英语教学的语言驱动。高校英语教学中采用语言驱动教学具有教学效率低,花费时间长等特点。当前条件下,我国的高校英语教学中仍然是是按照基础英语教学要求进行教学,在这种教学模式下,学生的独立自主性难以形成,而且在英语教学中逐步使其向应试教育方面发展,使得应试教育弊端明显显现出来,大学生在英语学习中,自我感觉良好,没有明确的教学目标,课外没有使用一定的时间用于英语学习,甚至部分学生在英语教学课堂都没有充分的利用课堂时间,而这些都是因为教学要求与考试要求之间存在差异,大部分学生认为英语学习实际用途不多,学习英语的目的只是为了能够在考试中顺利过关,从这个角度去分析,高校英语教学中采用的语言驱动导致实际教学效果较差,不利于学生在英语学习中培养综合能力,沿用的仍然是早期的应试教育思想。

2.英语教学的内容驱动。英语教学过程中的内容驱动主要是根据英语学习的某一要求开展的教学,该教学模式是为语言教学服务的,在英语教学中突出的是专门用途英语,在这类英语教学中,学生能够在学习英语内容的同时,提高对英语的实际应用,相对于语言驱动教学,内容驱动教学的教学理念以及教学模式都存在着差异,内容驱动教学与实际的双语教学模式具有一致性,在内容驱动教学中能够根据教学内容创设情境,使得英语教学与实际生活相关联,既能提高学生在英语学习中的兴趣,而且还能让学生感觉到学习英语意义重大。尤其是一些关于东西方文化差异、国外地理信息等内容的教学,能够从内容上对英语学习进行延伸。

相对于语言驱动,内容驱动具有更多的优势,比如:提高学生学习兴趣、延伸学生的知识面、了解东西方文化差异等。这些既能巩固语言教学,而且能够极大地促进学生对英语的实际应用能力。

三、高校英语教学中的几点建议

1.明确英语教学目的。高校英语教学经过多次改革,其教学目标应以培养高素质人才为目标,而不是单纯的英语知识积累,在英语教学中需要重视学生综合能力的培养,一方面在教学以及生活中将英语作为一门语言工具进行运用,另一方面,在学习中通过对英语的扩展了解更多的外国文化,丰富学生的语言内容,从而真正的达到运用英语的目的。比如:在教学中可让学生观看《刮痧》这一电影,该电影中既有我国传统中医刮痧的描述,而且极大程度的反映出东西方文化方面的差异以及冲突,在英语教学中通过扩展该内容,能够让学生更进一步的了解东西方文化差异,以明确的目的完成英语教学与学习。

2.语言教学模式与内容教学模式的结合。在英语教学中由于语言教学模式使用时间较长,对此,可以语言教学模式为基础,逐步的实现语言教学模式向内容教学模式的转变,重视不同教学模式中优点的使用,不断地增加英语教学中内容教学模式的比例,通过内容教学提高高校英语教学效果,而语言驱动教学模式可作为内容教学模式的补充,两者的结合能够实现高校英语教学的质变。

3.调动学生学习英语的积极性。大学教学内容较多,而且课外时间较为充裕,在这种情况下,需要调动学生学习英语的积极性,依靠学生自主对英语的学习,提高英语教学效果,在这方面,需要让学生意识到英语学习的重要性,英语不仅是一门语言,更是一种文化,这种文化与我国的文化存在较大差异,通过不同的教学方法以及正确引导,不断地调动学生对英语学习的积极性。比如在课外组织学生进行丰富多彩的教学活动,使用英语进行演讲比赛,或者是观看纯英文无翻译的电影,然后让学生总结电影的内容等。

四、结束语

大学英语教学具有十分重要作用,尤其是在现阶段综合性人才培养方面,需要不断地对教学模式进行改革,协调好语言驱动与内容驱动的关系。以多元化的教学方法提高高校英语教学质量。

参考文献:

[1]邬菊艳.从“学习英语”到“用英语学习”——普通高校大学英语课程框架构建[J].嘉兴学院学报,2014(05).

[2]孔德亮.大学英语教学的动力机制构建——研究现状与理论思考[J].外语界,2014(05).

[3]蔡基刚.再论我国大学英语教学发展方向:通用英语和学术英语[J].浙江大学学报(人文社会科学版),2015(04).

浅谈Linux设备驱动 篇4

1 Linux操作系统。

Linux是芬兰人写的基于linux kernel (即, linux内核) 的操作系统。[1]linux内核是一个小程序, 用来管理最核心的计算机硬件, 如管理硬盘、内存、网络、CPU等, 它是计算机的核心。另外一些程序通过调用管理内核API来写外核的程序, 即编写一些外围工具, 如网络的, 类似office的, 数据库的等, 这样才形成了以linux kernel为核心具有很多应用程序的linux操作系统。[2]

2 设备驱动及Linux设备驱动。

设备驱动是一个小程序, 包含有关硬件设备的信息。有了此信息, 计算机就可以与设备进行通信。[3]驱动程序是硬件厂商根据操作系统编写的配置文件, 可以说没有驱动程序, 计算机中的硬件就无法工作。操作系统不同, 硬件的驱动程序也不同, 各个硬件厂商为了保证硬件的兼容性及增强硬件的功能会不断地升级驱动程序。驱动程序扮演沟通的角色, 把硬件的功能告诉电脑系统, 并且也将系统的指令传达给硬件, 让它开始工作。[4]系统调用是操作系统内核和应用程序之间的接口, 设备驱动是操作系统内核和机器硬件之间的接口。[5]设备驱动程序为应用程序屏蔽了硬件的细节, 这样在应用程序看来, 硬件设备只是一个设备文件, 应用程序可以象操作普通文件一样对硬件设备进行操作, 设备驱动程序是内核的一部分, 它完成以下的功能:

2.1 对设备初始化和释放。2.2把数据从内核送到硬件和从硬件读取数据。2.3读取应用程序传送给设备文件的数据和回送应用程序请求的数据。2.4 检测和处理设备出现的错误。[6]

在linux操作系统下有三类主要的设备文件类型, 一是字符设备, 二是块设备, 三是网络设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时, 实际的硬件I/O一般就紧接着发生了, 块设备则不然, 它利用一块系统内存作缓冲区, 当用户进程对设备请求函数来进行实际的I/O操作。块设备是主要针对磁盘等慢速设备设计的, 以免费过多的CPU时间来等待。[7]用户进程是通过设备文件来与实际的硬件打交道。第个设备文件都有其文件属性 (c/b) , 表示是字符设备还是块设备?另外, 每个文件都有两个设备号, 第一个是主设备号, 标识驱动程序, 第二个是从设备号, 标识使用同一个设备驱动程序的不同硬件设备, 比如有两个软盘, 就可以用从设备号来区分他们。设备文件的主设备号必须与设备驱动程序在登记时申请的主设备号一致, 否则用户进程将无法访问到驱动程序。

在用户进程调用驱动程序时, 系统进入核心态, 这时不是抢先式调度。也就是说, 系统必须在你的驱动程序的子函数返回后才能进行其他的工作。

3 linux操作系统下的设备驱动程序解析。

staticint__devinitrtl8139_init_one (struct pci_dev*pdev, const struct pci_device_id*ent) 函数功能描述:赋给pci_driver结构体中的probe函数指针, 用于当PCI核心检测到一个需要控制的pci_dev时, 对相应的设备进行始化工作。[8]

附注:本函数的主要任务是创建并初始化net_device结构, 该结构是网卡设备的抽象。

函数流程:a.调用alloc_etherdev函数, 创建以太网类型的网卡设备。它是对alloc_netdev函数的封装, 内核中给出了用于设置以太网通用属性的setup函数。b.使能当前PCI设备, 包括唤醒、热插拔等功能的建立。c.读取PCI配置空间中的Base Address Register。PCI local bus specification规定, PCI配置空间有6个32位寄存器保存基地址 (即bar0-bar5) 。8139too网卡驱动程序使用了其中的两个来分别表示I/O空间基地址映射和内存空间基地址映射。d.接下来调用pci_request_regions函数申请资源。该函数实际上调用了request_region和request_mem_region, 它们分别负责分配I/O端口和内存资源。 (内核中资源一般分成四类, 分别是I/O端口, 内存, DMA通道和中断线, 它们都由resource结构描述, 不同的是每一类资源拥有共同的基类对象, 这一点上体现出了内核设计上的OO思想。典型的面向对象思想如封装、继承、多态在内核中都有体现。每一类资源都以树状结构进行组织, 源码显示, 这种树状结构实际上是一种“双亲表示法”和“孩子、兄弟表示法”的融合) 。e.设置dev->base_addr字段, 它视驱动程序采用I/O空间抑或内存空间而定。如果采用I/O空间, 还要将I/O端口地址映射成内存地址 (这是一种比较好的做法) ;否则, 把PCI配置空间中bar1寄存器中的内存地址进行重映射, 只有经过重映射, 驱动程序才能够访问该内存区域, 这里涉及到页表项的添加。f.复位芯片。g.初始化net_device结构中的部分回掉函数, 它们负责完成数据包的接收和传输等任务。

static int rtl8139_open (struct net_device*dev)

函数功能描述:申请资源, 启动硬件和开启监控线程。[8]

函数流程:a.调用request_irq函数, 以可共享的方式 (IRQF_SHARED) 分配给网卡设备中断线, 中断号存放在dev->irq中。b.申请用于DMA的设备内存。调用pci_alloc_consistent函数, 它返回两个地址, 一个是供设备驱动程序使用的内核虚地址;另一个是供DMA控制器使用的总线地址 (它在某些体系结构下等同与物理地址) 。用该函数申请到的设备内存物理上必须是连续的, 因为这里DMA操作是将成块物理上连续的数据在主存与网卡的FIFO缓存间传输。pci_alloc_consistent函数实际上是调用__get_free_pages函数获取内存页, 并使用vrit_to_phys函数将得到的内存页虚地址转换成物理地址。c.初始化ring buffer.。d.启动硬件。首先复位网卡设备, 接着将从EEPROM设备中读取的硬件地址写入相应的寄存器, 然后把第三步中获得的输入输出DMA缓冲区的总线地址赋予相应的寄存器, 最后设置组播列表、使能所有已知的中断。e.启动传输队列, 接受来自网络层的数据包。d.启动监控线程, 该线程负责在传输超时的情况下做相应处理。该监控线程用工作队列实现。通过使用schedule_delayed_work函数, 该线程函数可以在规定的时间点上被执行。

static int rtl8139_start_xmit (struct sk_buff*skb, struct net_device*dev)

函数功能描述:将网络层获得数据拷贝到DMA缓冲区[8]

函数流程:a.将sk_buf结构中的数据拷贝到四路DMA输出缓冲区中的一个, 保证包的大小至少为ETH_ZLEN。b.判断四路缓冲区是否已被用完, 如果是, 则调用netif_stop_queue函数来暂停网络层传输队列。这里要注意的是, 完成sk_buf结构的拷贝后, 要更新tp->rx_curr指针, 它是一个unsigned long类型, 同时, 驱动程序还维护tp->rx_dirty指针。这两个指针负责四路DMA输出缓冲区的数据同步。它们都是不断递增的, 当二者之差等于NUM_TX_DESC的时候, 意味着四路DMA输出缓冲区都已被填满而且尚未被传输, 这时候要做的自然是停止网络层继续向驱动程序发送skb。

static irqreturn_t rtl8139_interrupt (int irq, void*dev_instance, struct pt_regs*regs)

函数功能描述:中断处理[8]

附注:通常情况下, 中断的来临意味着FIFO中的数据已发送或DMA已将接受到的数据由FI-FO拷贝到DMA缓冲区。更具体的来说, 在禁止early mode的前提下, 中断的发生表示一个完整的数据包被发送到了网络介质或者一个完整的数据包已通过DMA的传送到了内存缓冲区。为了不致使大量小数据包的接收给系统带来的频繁中断降低系统性能, Linux内核中提供了NAPI, 即在关闭接收中断的状态下, 以轮循的方式接收数据。

函数流程:a.读取中断状态寄存器, 检查该中断是否属于当前网卡设备。由于以可共享的方式使用中断线, 这一步是必须的。b.如果接收中断位被设置, 首先调用netif_rx_schedule_prep函数, 将设备对象的dev->poll方法加入到网络层的poll队列, 如果函数执行成功, 则清除中断状态寄存器的相应位 (方法是在要清除的位写1) , 接着在设备对象上调用__netif_rx_schedule函数, 它会在必要的时候出发一个软中断, 从而通知网络层开始接受数据包 (即调用dev->poll函数) 。c.如果传输中断被位设置, 则对已传送的数据包进行确认。具体的讲, 就是通过读取相应的传输状态寄存器, 获取传送的信息。芯片手册中规定, 当驱动程序将数据包大小写入该寄存器的低12位的同时必须将其13位置0, 而当传输DMA操作完成时, 该位被自动置1, 由此看来, 这是与DMA控制器之间的握手操作。这里要明确指出的是, 数据包由网络层传递给驱动程序并放置在DMA传输缓冲区的操作由上面谈到的rtl8139_start_xmit函数负责, 中断处理函数中仅仅是对已发送的数据包的确认, 同时记录一些信息, 如发送的数据总量、发送的总数据包数、丢弃的总数据包数等等。d.步骤a、b、c都应在自旋锁的保护下进行。

static int rtl8139_poll (struct net_device*dev, int*budget)

函数功能描述:以轮循的方式将DMA输入缓冲区中的数据拷贝到sk_buf结构中并交付给网络层做进一步处理。[8]

附注:本函数被赋值给net_device结构中的poll字段, 它由软中断出发并不断被调用直到数据处理完毕。整个过程在输入自旋锁的保护下进行。

函数流程:a.清除中断状态寄存器的相应位。b.从rx_ring输入DMA缓冲区中读取数据包, 申请并初始化sk_buf结构, 同时用rx_ring中的数据包填充之, 接着调用netif_receive_skb函数把sk_buf结构交付给网络层。这里应该注意的是, 驱动程序通过在rtl8139_private结构中的unsigned int变量cur_rx来维护rx_ring中多个数据包的处理序列。独立于每个包的头4个字节放置的是接收数据包的状态和长度。c.更新CAPR (Current Address of Packet Read) 寄存器, 地址要双字对齐, 应此, 在计算cur_rx值时, 使用表达式cur_rx= (cur_rx+rx_size+4+3) &~3。d.重复步骤2中的操作直到处理完rx_ring中的所有数据包。e.使用__netif_rx_complete函数将当前设备在poll队列中清除, 接着使能接收数据中断。由于接收中断和__netif_rx_complete函数间存在竞争, 即将设备从poll队列中清除的同时可能会有新的接收中断到来, 应此这两个操作要在屏蔽本地cpu中断的状态下进行。

结束语。本人使用了linux操作系统后, 对linux操作系统产生了兴趣, 并且阅读了一些书籍和网络评论, 谈了一些感言与大家共享, 希望指正。

参考文献

[1]Bar, Moshe.Linux Internals[M].McGraw-Hill.2000., 1-2.

[2]Daniel P.Bovet, Marco Cesati Understanding the Linux Kernel[M].O'Reilly&Associates, 2000:26-49.

[3]Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman.Linux Device Drivers[M].O'Reilly Media, Inc, 2005:120-130.

[4] (美) Robert Love著, 陈莉君, 康华, 张波译.Linux内核设计与实现[M].北京:机械工业出版社, 2006:52-69.

[5]倪继利著, Linux内核分析及编程[M].北京:电子工业出版社, 2006, 102-119.

[6]李玉波, 朱自强, 郭军著.Linux C编程/程序员书库[M].北京:清华大学出版社, 2005:221-229.

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

设备驱动 篇5

本范本3333))))

签订日期:________年________月________日编 号:________________

承租方:(以下简称乙方)________________________________________________________

出租方:(以下简称甲方)________________________________________________________

甲、乙双方根据《中华人民共和国合同法》的有关规定,按照平等互利的原则,经过双

方协商,就乙方向甲方承租设备特签订本合同。

一、租赁设备概况

二、设备使用地点及工程项目:本租赁设备仅限于在_____________________________,用于________________________工程。

三、租赁设备的所有权和使用权:

1、甲方拥有对租赁设备的所有权。

2、乙方仅在租赁期内在本合同规定的范围内拥有该租赁设备的使用权。

四、甲方为该设备配备操作手______人,由____方负

责工资,工资每人每月__________元。

五、租赁期限及租金结算方式:

1、自________

年________月________日至________年________月________日止,租赁期满,乙方将设备完

好交给甲方办理退场手续,若乙方继续使用,应在本合同期满前五日内重新签定续租合同。

2、租赁期间原则上每天平均工作时间不超过8小时(折合一个台班),每月累计不得超过____

小时,确因工作所需超出_____小时部分应视为加班,按超出工作小时数计收加班租赁费。设

备的租赁费按月结算____________元/月/台,_________元/天/台,如设备租赁期不足一个月,租赁费按实际天数乘以8小时结算,超出工作小时加班部分,另计收加班费。

3、经甲

乙双方协商,甲方收取乙方设备预付租金______________元,作为履行本合同的保证。

4、乙方向甲方交纳租金及保证金后,办理提货手续,自租日期,每30天向甲方交付一次租

金,租赁期满,扣除应付设备赔偿金后,甲方应将保证金余额退还乙方。

六、租赁设备的运输、使用、维修、保养和费用:

1、设备的进场费由_______方负担,退场费由______

方负担,乙方应在设备退场前七天通知甲方。

2、设备在租赁期间所需的各种油料由乙

方负担。

3、在租赁过程中,乙方承担设备易损件(如刀头、刀库等)的所有更换费用。

4、设备在租赁期间内由乙方使用,乙方应协助甲方机手做好设备的日常维修、保养,使设

备保持良好状态,维修和配料费用在________元以下的由乙方负担,维修费用在_______元

以上的由甲方负担,所付费用以甲方机手签字为准,由甲方负担的部分从甲方收取设备租赁

费中扣除。

5、在工作过程中,乙方若不能对设备故障进行排除,应及时通知甲方进行

维修,设备因故障造成每月累计停工三天(维修时累计十二小时折合一天)以上的部分乙方

浅析设备驱动程序通知应用 篇6

关键词:设备驱动;应用程序;移植;程序

为了保证操作系统的平安性和稳定性以及应用程序的可移植性,Windows操作系统不答应应用程序直接访问系统的硬件资源,而是必须借助于相应的设备驱动程序。设备驱动程序可以直接操作硬件,假如应用程序和设备驱动程序之间实现了双向通信,也就达到了应用程序控制底层硬件设备的目的。

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

一、异步过程调用(APC)

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

二、事件方式(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应用程序的辅助线程就对这个消息进行相应的处理。

三、消息方式

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

四、异步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的处理结果。

五、 事件方式(WDM)

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

六、 结语

在目前流行的Windows操作系统中,设备驱动程序是操纵硬件的最底层软件接口。为了共享在设备驱动程序设计过程中的经验,给出设备驱动程序通知应用程序的5种方法,具体说明每种方法的原理和实现过程,希望能够给设备驱动程序的设计者提供一些帮助。

参考文献:

[1](美)Chris Cant. Windows WDM设备驱动程序开发指南. 孙义, 马莉波, 国雪飞等译. 北京摘要: 机械工业出版社 2000.

设备驱动 篇7

1 DSP/BIOS设备驱动模型

1.1 类/微型驱动模型

DSP/BIOS是TI公司所设计开发的一个尺寸可裁剪的实时多任务操作系统内核,通过使用DSP/BIOS提供的丰富的内核服务,开发者能快速地创建满足实时性能要求的精细复杂的多任务应用程序。为了使开发设备驱动更加简单方便,提出了DSP/BIOS Device Driver Kit,定义了标准的设备驱动模型,一种将设备驱动分为与硬件无关和与硬件相关的双层结构,这样就使开发驱动程序不像以前那样复杂了,为开发者提供了便利。这两层结构称为“类/微型驱动模型”[1],它们每一层都有各自通用的接口,所以相似设备驱动程序的主要部分可以复用,驱动代码的移植成为可能,使开发驱动的过程大大简化。

与硬件无关的层称为类驱动(Class Driver),它处在应用程序与微型驱动之间,提供对多线程I/O请求的串行化和同步,并且维护设备数据缓冲区,向上提供API接口供应用程序调用,向下通过适配层与微型驱动相连,实现API接口函数到微型驱动层的映射。

与硬件相关的层称为微型驱动(Mini-driver),它处在类驱动与芯片支持库(Chip Support Library)之间,对于类驱动的接口是统一的,即每一个微型驱动都为类驱动和DSP/BIOS设备驱动管理提供了标准接口。微型驱动采用芯片支持库(CSL)管理外围设备的寄存器、内存和中断资源[2]。但由于硬件是千差万别的,所以微型驱动对底层硬件的操作是根据硬件的不同而不同的。对于完成同样功能的不同外设,只需稍加修改微型驱动,而不需重新编写驱动程序,就可以实现驱动程序的移植与复用,使驱动程序的开发过程大大简化。类/微型驱动模型结构如图1所示。

1.2 类驱动

通过将应用软件,驱动程序分层之后,可以看到,位于顶层的应用程序并不直接与微型驱动产生联系,而是通过类驱动与微型驱动连接。每一种类驱动向上层应用程序提供一个API接口,并且与微型驱动接口进行通信。

DSP/BIOS定义了三种类驱动:流输入输出模块(SIO),管道管理模块(PIP),通用输入输出模块(GIO)。其中,SIO和PIP分别需要使用适配器DIO和PIO来与微型驱动进行通信。SIO/DIO是基于流的I/O模型,使用异步方式来操作I/O,对于数据的读写、处理可以同时进行。PIP/PIO是基于管道的I/O模型,每个管道维护着一个被划分为多个大小相同的帧的缓冲区。GIO类驱动采用基于流的同步I/O数据传输模式,适合大流量数据的传输,更适合文件系统。与SIO/DIO和PIP/PIO不同,GIO包含内置的IOM(I/O Manager输入输出管理)适配层,可以直接与微型驱动进行通信。

GIO模块与其他两个模块相比,有一个很重要的特性,就是可以扩展API函数支持新的应用领域,这样就实现了对GIO类驱动的扩展。这种可扩展API的特性正好可以用在视频驱动开发方面。例如这种扩展可以满足视频设备存储区的需要。另外,在提供了视频驱动和应用程序之间的视频数据同步机制之后,这种扩展也能够允许使用一个单独的调用来“交换”视频缓冲区。这种交换缓冲区的机制对于实时视频信号的采集与显示是十分重要的。所以,在视频驱动中,我们采用通用输入输出模块GIO。应用程序可以直接地调用GIO API函数和IOM微型驱动程序进行交互,这些GIO API就可以看作是类驱动。GIO类驱动接口如图2所示。

GIOcreate会为一个特定的IOM通道实例创建一个GIO对象,这是类驱动使用微型驱动的第一步,首先创建对象及IOM通道,然后在此通道上进行数据传输工作。其结构体类型为GIO_Obj:

1.3 微型驱动

微型驱动主要通过一些函数来完成对外部设备的直接控制。只要微型驱动创建了规定的函数,应用程序就可以方便地通过DIO适配模块、PIO适配模块或(和)GIO类驱动调用[2]。

例如:GIOcreate被调用时,会运行mdCreateChan来创建一个通道。

这些微型驱动函数包括:mdBindDev/mdUBindDev(绑定/删除通道函数):在程序建立接口时调用,完成设备的初始化硬件设备/在程序结束时调用,卸载设备。mdCreateChan/mdDeleteChan(创建/删除通道):需要在应用程序与设备实例之间创建一个逻辑通信通道,用于交换驱动数据。应用程序可创建一个或多个逻辑通道,微型驱动用通道对象来代表这些通道。这两个函数就是用来分配和释放通道对象。mdSubmitChan(递交I/O请求):该函数处理传递给它的IOMPacket结构体中的命令代码(cmd),根据命令代码,完成相应的处理或返回错误代码。ISR(服务设备中断并完成I/O操作):IOM微型驱动在中断的ISR中将以处理完的IOMPacket请求出队,启动下一次传输或服务请求,调用类驱动的回调函数与应用程序进行同步,并返回出队的IOMPacket。mdControlChan(控制设备):用来操作外部设备。

这些微型驱动的函数入口放在接口表(IOMFxns)中,供适配模块或GIO类驱动调用。

2 TMS320DM642视频驱动

下面以TMS320DM642芯片为例,介绍有关TMS320DM642视频采集与显示的驱动程序的开发。通过编写驱动程序,完成视频信号的实时采集与显示功能。TMS320DM642是TI公司推出的一款专门用于视频/图像处理的定点数字信号处理器,它基于C64x内核,带有3个可配置的视频端口,与视频采集芯片直接相连,无需外加逻辑电路或FIFO缓存,只需编写相关解编码芯片的驱动程序,就可以完成视频信号的采集与显示。在这里使用的解码、编码芯片分别为PHILIPS SAA7115和SAA7105。

2.1 视频类驱动

在视频驱动程序结构中,为了最大程度地提高视频驱动代码的复用性和通用性,将类驱动又划分为两层结构[3],其中上层为FVID模型,它是在DSP/BIOS GIO类驱动之上的简单封装,下层是GIO类驱动程序。GIO类驱动提供独立的、一般的API函数集并且为微型驱动提供广泛的服务,而上层的FVID模型向上层的视频采集、显示结构提供定制的API函数。

在视频驱动中,主要是通过调用FVID模块函数来完成类驱动代码的编写工作。FVID主要有以下几个API函数:FVIDcreate:分配并初始化通道对象;FVIDcontrol:向微型驱动发送控制命令;FVIDalloc:向应用程序分配视频端口缓冲区;FVIDexchange:交换缓冲区;FVIDfree:释放缓冲区;FVIDdelete:删除通道对象。

在配备视频接口的设备驱动时,至少指定它要开设3个以上的视频缓冲区(FVID模型中,默认分配3个缓冲区)[4],帧缓冲区通过FVIDalloc(),FVIDfree(),FVIDexchange()三个函数在应用程序与驱动之间交换。

2.2 视频微型驱动

视频微型驱动也分为两层结构[3],上层为通用视频端口层部分,下层为指定编解码芯片微驱动层部分,它们通过外部设备控制接口(External Device Control,EDC)实现对外围芯片的操作。这种微驱动结构的好处是,当使用不同的芯片时,只需修改指定编解码芯片微驱动那一部分,不需将整个微驱动重新编写,使得驱动的复用性大大增强。

视频驱动程序模型如图3所示。

2.3 TMS320DM642视频驱动设计步骤

2.3.1 注册微型驱动

由于应用程序、类驱动最终都是要通过微型驱动的函数来完成对外部设备的直接控制,所以驱动程序设计的第一步就是要在DSP/BIOS Config中的Input/Output->Device Drivers->User-Defined Devices项目添加设备并注册微驱动,进行属性的设置[5],并指明IOMFxns函数表地址和设备参数地址,如图4所示。

DSP/BIOS会在内部维护一个“设备表”,其中包含User-Defined Devices对象进行配置的设备实例。

2.3.2 编写类驱动代码

FVID函数会在设备表中查找已注册的微驱动,并调用微驱动函数完成对外部设备的操作控制。

通常,首先利用FVIDcreate函数完成分配并初始化通道对象,返回值为设备实例句柄,这个句柄用于后续其他FVID函数调用这个已经创建的通道。然后调用FVIDcontrol函数向微型驱动发送控制命令,如配置编解码器,发送开始采集或显示图像的控制命令。然后利用FVIDalloc分配缓冲区,接着应用程序将缓冲区的数据进行复制的搬移工作,当应用程序完成对缓冲区数据的采集后,调用FVIDexchange来交换缓冲区,保证视频数据能够实时地、源源不断地供应用程序使用。

过程的流程图如图5所示。

下面是简单的视频采集显示驱动的部分实现代码:

3 结 语

本文介绍了基于TI公司的类/微型驱动模型进行视频驱动设计的原理及主要方法,利用这两层的驱动模型不仅简化了驱动程序的编写过程,缩短了开发时间,而且使代码的复用性和可移植性大大提高,稍加改动相应的底层接口就可以用于其他的DSP系统中,真正使视频驱动的开发过程得到简化。

参考文献

[1]Texas Instrument.DSP/BIOS Driver Developer′s Guide,Lit-erature Number:SPRU616,2002.

[2]陈彬,魏丹,邓德祥,等.C64x系列DSP/BIOS中设备驱动程序的设计[J].电子技术应用,2004,30(11):67-70,73.

[3]Texas Instrument.The TMS320DM642 Video Port Mini-Driver,Literature Number:SPRA918A,2003.

[4]臧博,吴裕斌,曹丹华.基于GIO/FVID的DSP视频处理驱动程序[J].单片机与嵌入式系统应用,2006(8):27-29,42.

设备驱动 篇8

1 Linux中设备驱动程序的作用

在Linux系统中,对所有设备的操作很好地体现了“一切皆是文件”的思想:将所有设备以文件的形式存放在/dev下,这样应用程序就可以用使用文件的方法使用它。设备驱动程序与硬件交互,完成硬件相关参数的设置,实现设备的各种功能。如最基本的LED灯,设备驱动程序可完成的功能有:某LED灯的亮、灭以及所有LED灯轮流闪烁等。这样,应用程序在实现相应功能时只需调用设备驱动程序而不用关心硬件上是如何实现的。应用程序调用驱动程序的过程如图1所示。从图1可以看出,设备驱动与内核、硬件都要进行交互。设备驱动与内核中文件系统交互接口称之为独立于设备的接口,在下文中会介绍;设备驱动程序在与硬件的交互中,有些函数已经被定义了。这就是为什么把设备驱动单独划分出来放在内核中,而不放在应用程序中的原因。驱动程序与应用程序的主要区别如下:

(1)应用程序的使用体现在进程或线程;而驱动程序作为内核的一部分,它主要是被需要的应用程序调用,不可能成为一个进程或线程。

(2)两种程序的编写方法截然不同(后面将会详细介绍)。

2 常见的设备驱动模型编写方法

本文主要介绍以下3种驱动模型:字符设备驱动模型,平台设备总线驱动模型,input子系统驱动模型[8]。学习最常用的驱动模型,从中掌握驱动程序的规律,这样编写驱动程序就会有事半功倍的效果。

2.1 字符设备驱动模型

所谓字符设备,就是一个顺序的数据流设备,并且对这些设备的读写是按照字符进行的。常见的字符设备有LED,ADC等。

2.1.1 设备驱动加载函数模块

2.1.2 设备驱动卸载函数模块

上面的2个函数中,主要有以下几个重要的结构体:

(1)struct cdev用来描述字符设备,它包含了加载设备的信息:

(1)设备号,文件系统就是根据该设备号找到设备文件;

(2)struct file_operations结构,这个结构体定义了字符设备驱动提供给虚拟文件系统的接口函数,也就是驱动程序的接口,和系统调用接口有类似的功能。应用程序进行的Linux调用,如open(),write()等,最终会调用该结构体内的函数。在字符设备驱动程序中,最主要的工作就是填充该结构体内的成员函数。

(2)设备文件节点struct inode,每一种文件系统都有它组织以及查找文件的方式,一个设备文件节点代表一个设备。设备文件节点的具体体现为存放在/dev目录下的文件。

从上面的字符设备驱动程序的框架可以看出驱动程序与应用程序的编写方法有很大差异。字符设备驱动程序编写的流程如下:

加载函数中:

(1)初始化cdev结构体,并向内核申请该设备的设备号;

(2)向内核注册cdev结构体,表示要在内核中添加一个字符设备;

(3)根据应用程序的需求填充file_operations结构体中的成员函数;卸载函数中释放设备号,注销该设备。

2.2 平台设备总线驱动模型

因为设备越来越复杂,原来的设备模型就不再满足需求,于是在Linux 2.6内核中引入了一套新的驱动管理和注册模型,这就是平台设备总线驱动模型。在介绍这种模型时,首先应明确以下3个概念,即平台设备总线platform_bus,平台设备platform_device和平台驱动platform_driver。总线是处理器和一个或多个设备之间的通道。在平台设备模型中,所有的设备都与总线相连。平台设备是指处理器上集成的额外功能的附加设备,平台设备并不是与字符设备、块设备和网络设备并列的概念,而是一种平行的概念,它从另一个角度对设备进行了概括。如果从内核开发者的角度来看,平台设备的引入是为了更容易地开发设备驱动。在这种模型中,由总线将设备和驱动进行匹配:在系统注册设备时,总线就会寻找与之匹配的驱动;同样的,在系统注册驱动时,总线就会寻找与之匹配的设备。

下面以看门狗的驱动程序为例,解释平台设备总线的驱动模型,其中开发环境为Linux-2.3.32和S3C2440A。

2.2.1 向系统注册平台设备platform_device

在arch/arm/plat-s3c24xx/devs.c中有很多平台设备的定义,结构体是struct platform_device。该结构体中最为重要的是struct resource,根据硬件资源对其进行填充。看门狗的平台设备可以定义为struct platform_device s3c_device_wtd。定义了平台设备,就可以使用它了。

在系统人口文件中(arch/arm/mach-s3c2440/machsmdk2440.c),可以看到系统的初始化函数是smdk2440_machine_init(),在这个初始化函数中,有platform_add_device()函数,系统在初始化时,会使用该函数将平台设备添加到总线中,这样便完成了平台设备的注册。

2.2.2 设备驱动加载函数模块

2.2.3 wtd平台驱动结构体

在模块加载函数中,注册了看门狗驱动,该结构体为struct platform_drive类型,在该结构体中,.driver定义了另一层驱动,这种思想在很多驱动模型中都会用到,即定义两层结构体:第一层是最原始的驱动以及设备结构体,即struct driver和struct device;第二层就是和驱动模型相关的驱动和设备结构体,在平台设备驱动模型中,就是struct platform_device和struct platform_driver。

2.2.4 实现probe函数

在probe函数中,对硬件相关参数进行设置,其中要注意的是地址的操作:I/O端口和I/O空间,不同的地址空间操作函数不同,但最后都要映射到内存空间[9,10]。

2.2.5 mise设备体结构实现

wtd_fops在字符设备中已详细介绍了,在平台设备模型中仍然用该接口函数,即便是两层模型,最终的操作都是对原始设备的操作。这里,可将.probe,.remove等函数看成第二层模型的接口的成员函数。

2.2.6 设备驱动卸载函数模块

从以上模块可以看出平台设备的驱动程序编写流程如下:

(1)定义平台设备驱动并初始化;

(2)指定其prove,remove等成员函数,并初始化其中的driver变量,它的主要作用就是为了和相关的platform_device联系起来;

(3)实现第二层驱动接口的成员函数;

(4)将设备注册成misc设备,并实现字符设备的相关操作,wtd_fops就是驱动程序的接口函数。按应用程序的读写需求填充该接口函数;

(5)释放资源,注销设备。

2.3 输入子系统

输入子系统又叫input子系统。模式固定,实现起来比较简单,调用一些简单的函数,就可以完成设备功能。

2.3.1 设备驱动加载函数模块

在设备驱动加载函数模块,设置了事件信息,事件类型在内核中都有定义,常见的有按键,坐标,压力等。

2.3.2 中断处理函数

中断函数的主要作用就是向input子系统报告事件的发生,当所有事件全部报告给系统后,还要通知系统,没有事件了,报告完毕。

2.3.3 设备驱动卸载函数模块

上面的函数中,有以下几个重点:input_dev结构体,也就是输入设备结构体,同样是属于两层模型。输入子系统驱动模型中,核心工作就是向输入子系统系统报告输入事件,在中断函数中完成。

这种模型中不需要关心文件函数接口,因为这种模型与应用程序的交互中使用固定的结构体,这是和前面两种驱动模型的最大区别。

输入子系统模型驱动程序编写流程:

在加载函数中:申请中断函数;注册设备结构体;设置事件信息;

在卸载函数中:释放资源,注销设备。

3 结语

本文从层次结构入手,对常见的3种驱动模型分别进行了详细的阐述,逐步分析。从这3种模型中总结出了写驱动程序的经验:

(1)对于任何一种设备,不管采用哪种设备驱动模型,都有一个相应的设备结构体,该结构体对设备特性进行了描述。在设备驱动加载函数模块中对设备结构体的初始化、注册等,这样系统就可以准确地找到该设备。

(2)在驱动程序中,要注意各种地址的分配,不同地址的操作方式会不同。

(3)驱动程序的最终目的就是完成与内核及应用程序的交互:在与内核的交互中,已有相应的库函数;而与应用程序的交互,如果系统没有定义固定的结构体,则根据应用程序需求定义驱动程序中接口函数。

(4)在驱动程序卸载函数模块中,要释放一切在加载函数中申请的资源,注销该设备结构体。

通过以上经验的总结,使读者了解写驱动规律,掌握写驱动程序的重难点,完成本文提出的任务。按照以上编写经验,编写的led,adc,wtd,rtc,ts等设备驱动,均能良好运行。

参考文献

[1]李忠儒.嵌入式系统的发展趋势[J].办公自动化,2011(5):53-55.

[2]陈年.嵌入式Linux设备驱动程序的构建方法[J].计算机科学,2006(12):172-174.

[3]朱园.Linux驱动程序的研究与开发[J].仪表技术,2008(2):32-34.

[4]梁金千,张跃,甄诚.Linux设备驱动程序架构的研究[J].计算机工程与应用,2002(8):119-122.

[5]李桥.嵌入式Linux设备驱动程序的开发研究[J].计算机与数字工程,2009(2):87-89.

[6]李桦,高飞,孙磊.嵌入式Linux设备驱动程序研究[J].微计算机信息,2010(6):68-70.

[7]郑伟,王钦若.Linux内核空间设备驱动程序的开发[J].微计算机信息,2003(12):85-87.

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

[9]BOVET D P.深入理解Linux内核[M].北京:中国电力出版社,2008.

环保机械设备驱动装置应用的探讨 篇9

在环保水处理领域, 水处理机械设备的功能要求是针对整个污水处理工艺进行设计的。污水处理工艺中, 常见的环节如溶药、混凝、气浮、浓缩及污泥脱水等都与动力驱动机械设备密不可分。这几个常见环节中, 以下三类机械设备的应用相当广泛:机械搅拌设备、桁架驱动式机械设备及污泥脱水设备。

1 机械搅拌设备的驱动装置

水处理中的搅拌设备, 分为溶药搅拌、混合搅拌、絮凝搅拌和水下推流搅拌等。这些搅拌设备的设计具有共性又有各自的特点。但从机械设计上来说, 抓住一种类型的设计要点, 即可举一反三地优化设计其余类型的设计。

1.1 选用原则。

机械搅拌驱动装置含电动机与减速器, 归纳各设备类型, 其选用应遵循以下原则:

a.机械效率高、传动比适当、合理功率裕量、转速贴进工作要求。b.减速机输出轴旋转方向的单向性或双向性与实际使用要求相结合。c.工作的平稳性, 如是否含振动和荷载变化。d.外形尺寸应满足装配空间及检修方便的要求。e.讲究设备整体的经济性。f.无特殊情况选用普通的异步电动机, 按实际需求配套励磁调速电机或防爆电机。g.有防爆要求时一般不采用链传动, 要求正反双向传动时一般不选用蜗轮传动。

1.2 设计计算。

机械搅拌驱动装置的设计主要是其功率、减速比的设计。这里以典型的混合搅拌中的桨式搅拌叶为例, 在选用时, 为提高设备工作效率、满足混合工艺的要求, 根据行业经验数据, 其搅拌器外缘线速度ν应满足1.0~5.0m/s, 搅拌器直径选用范围应满足其中D为池形内径。按要求将以上两参数确定后, 驱动装置的功率和减速比按以下方式进行计算。

1.2.1 减速机输出轴转速n

按计算转速即可配置电动机的级速 (及输出转速) 和减速器的减速比i。当计算出的参数在选用标准设备时出现困难, 可在ν和d的允许范围内进行调整选用, 以便于选用标准件。

1.2.2 电动机驱动功率N

式中C3-阻力系数, C3≈0.2~0.5;ρ-水的密度, ρ=1000 (kg/m3) ;ω-搅拌器旋转角速度Z-搅拌器桨叶数 (片) ;e-搅拌器层数;b-搅拌器桨叶宽度 (m) ;R-搅拌器半径 (m) ;g-重力加速度9.81 (m/s2) ;θ-桨板折角 (°) 。

通过计算、校核后的参数还需进行机械效率的计算, 机械效率的融入是设备延长使用寿命的保证, 其选用可按标准将每个传动环节进行累积。

2 桁架驱动式机械设备的驱动装置

按环保水处理工艺进行区分, 桁架驱动式机械设备可分为平流式驱动和周边驱动两大类。平流式的特点是工作桁架呈直线行走, 周边驱动的特点是工作桁架一端或两端呈圆弧状轨迹行走, 在驱动装置设计上, 两者的要求大致是相同的。

2.1 选用原则。

桁架驱动式机械设备的驱动装置主要含电动机、减速器、二级减速机构 (链传动系统或皮带传动系统) 及行车轮等, 根据设备结构特点, 归纳其设计、选用原则如下:

a.呈单轴中心驱动时, 驱动机构的设置应在沿主动轮轴轴线一边的桁架中央。b.对于桁架跨度超过10m以上者, 可以采用双边驱动, 以降低传动轴的加工难度, 配合市场标准材料的选用, 同时也减少桁架两侧行走轮的不同步误差。c.无特殊情况选用普通的异步电动机, 涉及易燃物时应选用防爆电动机。d.减速器要求具有体积小、传动比大、寿命长、传动效率高等特点。选用时可结合设备的实际工作制度、传递功率、传动速比及布置形式等条件选用行星摆线针轮减速机或两级蜗轮减速器, 特殊情况再考虑选用其他形式或自行设计减速系统。e.减速器在出轴后可用链轮、联轴器和齿轮等传动, 以满足减速比和连接尺寸的要求。如减速比还满足不了传动要求可在减速器进轴端采用皮带传动减速, 但双边传动的进轴端不允许采用皮带传动, 以保证两端驱动轮的同步。

2.2 设计计算。

桁架驱动式机械设备的驱动装置设计主要有:驱动电机功率的制定、减速器减速比的配置、二级减速机构的选定及减速比的制定。以平流式刮吸泥机为例, 进行驱动装置的设计计算分析。

2.2.1 驱动电机功率及减速器减速比的制定。

根据选用原则, 设备工作场合无特殊要求, 且设备运行负荷不大, 选择普通电动机和行星摆线针轮减速机。

设备行走阻力P1

式中:K-单位宽度阻力 (N/m) , 一般取800~1000 N/m, 按实际介质选定;L-刮泥机构有效工作长度 (m) 。

驱动功率N

式中:ΣP-阻力累积之和 (N) ;v-设备行驶速度 (m/min) ;η-总机械效率 (%) ;m-电动机台数 (在采用分别驱动时, 应除以电动机的台数) 。

结合以上计算公式, 算得电机功率, 再根据功率及减速机工作要求按标准选取减速机。步骤虽然简单, 但考虑却要全面。为减小设备桁架的负荷, 在选用减速机时应尽量降低减速机分取的减速比, 将余出速比分配至二级传动机构中。

2.2.2 二级减速机构的速比分配。

总传动比i

式中:n-电动机转数 (r/min) ;D-驱动轮直径 (m) , 结合使用要求按标准设计;v-行车速度 (m/min) 。

速比分配:

式中:i1-一级减速机构减速比, 这里为摆线针轮减速机;i2-二级减速机构减速比, 按使用要求选用链传动或带传动。

在二级减速机构的选用中, 出于使用寿命的考虑, 在环保水处理中优待选用链传动机构。在速比确定、链传动机构选定后, 即可对链条、链轮及大小链轮齿数进行制定。制定时, 其规格应在满足使用要求的前提按市场供应情况进行选取。减速机构的级数不宜过多, 否则不但易复杂化设备主体结构的加工, 还会降低驱动机构的机构效率, 引起不必要的浪费。

3污泥脱水设备的驱动装置

污泥脱水设备种类较少, 目前国内涉及主要有四种:带式压榨过虑脱水机、离心脱水机、板框压滤机及螺压脱水机。应用最广的属板框压滤机和带式压榨过虑脱水机, 板框压滤机结构较简单, 驱动系统为液压机构, 工作效率也比较低, 呈间歇运行。带式压榨过虑脱水机工作呈连续运行, 驱动装置性能要求比其它脱水设备较高。本节以带式压榨过滤脱水机为例进行分析。

带式压榨过滤脱水机较通用的驱动机构是电动机、励磁调速机构、摆线针轮减速机、链传动机构、齿轮传动构。电动机是设备运行的动力源;励磁调速机构满足滤带0.5~5m/min的行走速度要求, 实现结合工艺处理量进行实际污泥处理量的调整;摆线针减速机满足一级减速比的要求;链传动机构满足二级减速比的要求;齿轮机构满足不同滤带间的动力传递。其间的组合形成了最普遍的带式压榨过滤脱水机的驱动装置。

该结构确实实现了设备的正常运行, 其驱动装置的参数设计也与桁架驱动式机械设备的驱动装置类同。但在此脱水设备中, 其结构之复杂、机械效率之低却是不容忽视。

首先, 该驱动系统中的励磁调速机构属重量较大部分, 它的加入不但使设备整体更加笨重, 还增加其配套主体结构的负荷, 再加上其调速仪表不宜操作、使用寿命短, 对其进行改进很有必要。将机械与电气有效结合是设备改进、更新的一个发展方向, 在这里建议把励磁调速部分更换为PLC中心控制及触摸屏人性化操作, 其优点分析如下:a.降低设备自身重量, 减小产品加工难度, 便于设备现场安装。b.降低设备主体结构负荷, 延长设备使用寿命。c.降低机械传动损耗, 有效提高能源的利用率。d.人性化操作平台, 使设备更美观、操作更方便。e.虽然一次投入费用略高于改进前, 但其技术含量提高, 后续维修费用很低。

其次, 不同滤带间的动力传递需通过齿轮机构来满足, 使得整个驱动装置结构变得较为复杂, 增加了加工工序、提高了加工难度, 且在后续使用时提高设备的维护费用。通过改变各传动辊筒的摩擦系数, 提高两滤带间的摩擦阻力, 直接由上滤带将动力传递至下滤带, 即不影响使用性能, 又减少了复杂的机械结构。其优点分析如下:a.减少机械传递机构, 降低能源损耗。b.减少产品加工工序, 降低投入成本, 提高经济效益。c.结构的简化可大大降低设备后续的维护费用。

4结论

我国环保水处理机械设备的技术还较为薄弱, 随着环保问题的日渐突出, 环境保护必需引起人们的重视。以上对部分环保水处理机械设备驱动装置的设计进行探讨, 针对一些实用、核心的细节进行分析, 总结了部分水处理机械设备驱动装置的设计及改进建议, 希望能为环保水处理机械设备技术注入一份力量。

参考文献

[1]林选才, 刘慈慰.给水排水设计手册专用机械[M].北京:中国建筑工业出版社, 2000.

[2]成大先.机械设计手册[M].北京:化学工业出版社, 1994.

基于ARM的无线网卡设备驱动设计 篇10

随着移动通信和便携通信的发展, 无线局域网WLAN日渐普及。嵌入式系统中无线局域网的接入, 既可以实现对嵌入式系统的无线控制和数据传输, 又可以满足一些特殊应用的场合。这里通过对USB无线网卡的Linux设备驱动的深入理解和分析, 成功地移植在Atmel 9261 ARM处理器上。实现了嵌入式系统的无线局域网接入。利用该平台, 可以进一步设计完善医用伽马相机和小型SPECT设备的手持数据采集系统, 使得控制人员能够远离数据采集现场, 而通过远程终端来控制现场数据和各种控制信号, 较好地解决了安全性问题。

1硬件系统构成

1.1 USB无线网卡介绍

无线网卡是无线局域网 (WLAN) 的重要组成部分, WLAN的物理层及MAC层是用无线网卡的硬件及其软件完成的, 而LLC层以上各层均由计算机软件来实现。WLAN包括进行通信的网络接口卡 (简称无线网卡) 和接入点/桥接器 (AP/网桥) 。其中, 无线网卡提供了最终用户设备 (手持设备) 与接入点/桥接器之间的接口。目前, 无线网卡主要以PCMCIA, Compact Flash (CF) 卡的形式广泛应用。大多数可用的无线网卡都是基于Intersil Prism或Lucent Hermes芯片组的, 其中USB设备的无线网卡则由Ateml芯片组支持。该系统采用D-Link的WLG-122无线网卡, 芯片组为Prism2, 它通过USB host port接入。

1.2 系统构成

主控制器采用Atmel 9261, 工作频率180 MHz, 具有16 KB数据cache和16 KB指令cache, 外接64 MB NAND FLASH和64 MB SDRAM, 外围接口由10/100 Mb/s自适应以太网卡, 3个USB 2.0接口, 2个通用异步收发器 (UART) , LCD接口以及串行外围接口 (SPI) 等组成, 可以方便地外接工作设备。

操作系统采用Linux 2.6.15;Bootloader采用U-boot;根文件系统采用ramdisk。系统启动后挂载yaffs文件系统, 该系统采用Ateml公司的Atmel 9261开发板, 外围接口包括2个USB host接口, 其中一个外接USB无线网卡。无线路由器采用Cisco-Linksys的WRT160N, 支持802.11g标准、TCP协议和TFTP协议, 如图1所示。

2USB无线网卡驱动

2.1 Linux USB驱动模块结构

对于接入系统中的USB无线网卡, 从CPU的角度首先看到的是USB总线, 然后才是网卡芯片, 所以USB驱动要先于网卡驱动实现。USB设备接口有主机端与设备端区别, 因而USB驱动程序也有USB主机端驱动程序与USB设备端驱动程序之分。在主控机方面, 主要有UHCI和OHCI两种规范。

上层的应用软件对系统的USB设备进行访问是通过文件系统的形式进行的。每个连接到系统总线上的USB设备可以同时对应一个或多个驱动程序, 即每个USB设备可以在Linux系统上设置一个或多个节点供应用程序使用。

由于USB接口为主从方式和多设备连接的树状网络结构, 所以USB主机必须具备对所有连接在总线上不同类型的USB设备进行配置管理的功能。Linux USB主机驱动程序可以同时支持多路USB总线功能, 每路USB总线独立工作。USB主机驱动由USB主机控制器驱动 (HCD) , USB驱动 (USBD) 和不同的USB设备类型驱动三部分组成。图2描述了Linux USB驱动程序的结构。Linux定义了通用请求块 (Universal Request Block, URB) , 用来在USB设备类驱动程序与USBD, USBD与HCD间进行数据传输。

2.2 Linux网络驱动程序结构

所有的Linux网络驱动程序都遵循通用的接口。设计时采用面向对象的方法, 即一个设备就是一个对象 (net_device结构) , 它内部有自己的数据和方法。一个网络设备最基本的方法有初始化、发送和接收。Linux网络驱动程序的结构可以划分为网络协议接口、网络设备接口、设备驱动功能和网络媒介四层。网络驱动程序中最主要的工作就是完成设备驱动层功能, 使其满足所需要的功能。

2.2.1 USB无线网卡驱动设备的访问和控制

与PCI, ISA等设备不同, USB, 1394等新一代总线没有IO/MEM映射、中断和DMA硬件资源, 取而代之的是抽象出来的硬件资源概念。对USB设备来说, 资源主要包括配置 (configuration) 、接口 (interface) 和端点 (endpoint) 。这些资源中, 端点对于USB设备有着最重要的意义, 实际的数据传输就是通过端点的读写实现的。驱动程序通过描述符来获取这些资源。在初始化时, USB驱动程序从设备端点0读取描述符, 经过解析后保存这些资源的属性, 为传输数据做准备。

2.2.2 USB网络设备驱动程序设计

USB无线网卡驱动程序首先向USB子系统注册自己, 然后通过vendor id和device id来判断硬件设备是否已经插入总线, 摄像头驱动程序需要创建一个usb_driver数据结构:

Struct usb_driver rtusb_driver={

.name=“rt73”,

.probe=usb_rtusb_probe,

.disconnect=usb_rtusb_disconnect,

.id_table=rtusb_usb_id,

};

当无线网卡插入USB总线时, USB core就会调用Probe方法来检测被传递进来的信息, 以确定无线网卡设备是不是与驱动程序匹配, 同时填充struct net_device完成对该网络设备的初始化。当无线网卡被拔出时, USB core就会调用Disconnect方法来完成清除工作。驱动程序通过显示模块的初始化和消除函数注册与注销模块调用module_init来初始化一个模块, 并在卸载时调用moduel_exit函数。

Probe函数主要代码如下:

netdev->open=usb_rtusb_open; //设定open函数

netdev->hard_start_xmit=RTMPSendPackets; //设定发送函数

netdev->stop=usb_rtusb_close; //设定close函数

netdev->priv=pAd; //设定私有数据指针

netdev->get_start=rt73_get_ether_start; //设定状态统计函数

其中, open函数主要完成对描述网卡硬件数据结构pAd的初始化, 包括urb包接收函数、接口配置函数、初始化发送接收数据结构和MAC地址拷贝函数, 以及最后开始的net_dev数据发送接收函数。RTMPSendPackets函数负责发送包装好的网络数据包。无线网卡驱动与USB core的通信则通过中断/批量的方式来传送。

3编译与测试

3.1 无线网卡驱动编译

该系统的Linux内核版本为2.6.15, 在宿主机上进行内核配置, 通过“make menuconfig”将内核中不必要的功能去掉, 增加对WLAN的支持。依次点击Device Drivers→Network device support→Wireless LAN (non-hamradio) →选中Wireless Lan driners (non-hamradio) &Wireless Extensions;然后进入通用USB-WLAN驱动程序源码, 修改makefile, 将内核文件夹选项重新定位在刚才编译好的Linux内核下, 通过“make”在该文件夹下编译生成rt73.ko驱动模块。

在ARM嵌入式Linux开发中文件的传输方式有多种, 比如TFTP服务和NFS文件系统。在此采用将rt73.ko驱动模块下载至开发板, 由于Linux支持模块的动态加载, 所以可以很方便地将该模块用“insmod”加载至内核, 通过“lsmod”查看加载的模块, 之后rt73模块已经被成功加载。

在开发板文件系统中添加无线管理应用程序, 和iwconfig, iwapy, iwlist等, 用于配置频率、网络、ID、ESSID、接受灵敏度、接入模式、无线网络标准、加密开关。

最后编写无线网络启动和自配置程序, 实现自动配置IP地址和无线网卡。至此整个无线网卡驱动程序全部编译完成。

3.2 测试结果及分析

启动无线网络, 编写测试带宽程序。该测试程序采用C/S设计模式, 客户端运行在ARM开发板上, 服务器运行在局域网内一台Linux PC上。改测试程序的工作流程主要如下, 客户端分别发送不同大小的字节流, 经服务器处理计算出对应的带宽, 可以得到一条宽带曲线, 进而得到网络实际能够达到的最大带宽。经反复测试, 该无线网卡能够稳定工作, 在距离AP 50 m的半径内下带宽为6 Mb/s, 距离理论值54 Mb/s还有一定距离, 具体原因正在分析中。测试结果如图3所示。

4结语

Linux作为当今市场上嵌入式系统使用比例最高的操作系统, 其驱动模式支持模块堆叠技术, 内核开发者已提供了一些通用模块。现从工程应用出发, 研究并移植了Linux下USB无线网卡的设备驱动, 以此为基础既可以构建嵌入式无线局域网, 又可以用于有线网络无法延伸或难以安装, 以及有可灵活移动和临时性使用等要求的、诸如外加摄像头和图像处理芯片的场合, 还可以用于工业现场中的远程无线视频监控。

摘要:介绍了D-Link无线网卡在嵌入式Linux下的驱动设计与实现。该系统主要应用于医用伽马相机和小型SPECT设备的手持数据采集系统。首先搭建嵌入式开发的软硬件环境, 对Linux内核进行剪裁, 然后研究网络驱动工作原理, 利用D-Link无线网卡对通用无线网卡的驱动进行修改和交叉编译, 最终移植到ARM平台上, 建立嵌入式无线局域网。

关键词:ARM,嵌入式Linux,无线网卡,802.11g,设备驱动

参考文献

[1][美]Corbet J.Linux设备驱动程序[M].3版.北京:中国电力出版社, 2006.

[2][英]Stevenson WT.Unix网络编程[M].北京:清华大学出版社, 2002.

[3]叶梅, 赵京纬, 初元萍.嵌入式Linux系统在PowerPC上的实现[J].核电子学与探测技术, 2006, 26 (5) :614-618.

[4]于明, 范书瑞, 曾祥烨.ARM9嵌入式系统设计与开发教程[M].北京:电子工业出版社, 2006.

[5]杜春雷.ARM体系结构与编程[M].北京:清华大学出版社, 2003.

[6]吴明晖.基于ARM的嵌入式系统开发与应用[M].北京:人民邮电出版社, 2004.

[7]钱晓华, 郭继红.基于嵌入式Linux的无线网卡驱动程序[J].辽宁大学学报, 2008, 35 (1) :55-57.

[8]刘亨杰, 汪敏, 潘志浩.USB无线网络适配器在嵌入式系统中的应用[J].微计算机信息, 2004, 20 (5) :51-53.

[9]杨旭, 沈大林.Visual C++编程篇[M].北京:电子工业出版社, 2004.

上一篇:创新智力化能力下一篇:网络表达自由