您好,欢迎来到宝玛科技网。
搜索
您的当前位置:首页浅谈嵌入式Linux系统设备驱动的开发与设计

浅谈嵌入式Linux系统设备驱动的开发与设计

来源:宝玛科技网
InformationTechnology·信息技术·软硬件

浅谈嵌入式Linux系统设备驱动的开发与设计张玲玲

(大庆油田有限责任公司第十采油厂信息中心黑龙江大庆1605)

【摘

要】主要阐述了嵌入式Linux设备驱动程序的概念,归纳嵌入式Linux设备驱动程序的共性,探讨嵌入式Linux

设备驱动程序具体开发流程以及驱动程序的关键代码,总结嵌入式Linux设备驱动程序开发的主导思想。

【关键词】嵌入式系统;Linux;设备驱动程序;内核

OnLinuxEmbeddedEystemDeviceDriverDevelopmentandDesign

ZhangLing-ling(ITCenteroftheDaqingOilfieldLimitedCompany'sNo.10OilProductionCompanyHeilongjiangDaqing1605)【Abstract】thepaperpresentstheconceptofembeddedLinuxdevicedriverprogram,summarizedintheembeddedLinuxdevicedriver

ofgenerality,embeddedLinuxdevicedriverspecificdevelopmentprocessaswellasthedriverofthekeycode,sumuptheembeddedLinuxdevicedriverdevelopmentofthedominantideology.

【Keywords】embeddedsystem;linux;devicedriver;kernel

0引言

嵌入式系统被广泛运用到消费、汽车、电子、微控制、

动程序来完成。内核必须包括与系统中的每个外部设备对应的驱动程序。否则设备就无法在Linux下正常工作。这就是驱动程序开发成为Linux内核开发的主要工作的原因。从内核源码的代码分布可以看出,设备驱动源码至少占据了一半的内核源码量,更能说明设备驱动程序对操作系统的意义和价值。

无线通信、数码产品、网络设备、安全系统等领域。越来越多的公司、研究单位、大专院校、以及个人开始进行嵌入式系统的研究,嵌入式系统设计将是未来相当长一段时间内研究的热点。

1Linux设备驱动程序概述

嵌入式Linux以其可应用于多种硬件平台、内核高效

2嵌入式Linux设备驱动程序开发

在Linux操作系统下有3类主要的设备文件类型:

2.1设备驱动程序工作原理

块设备、字符设备和网络设备。这种分类方法可以将控制不同输入/输出设备的驱动程序与其它操作系统软件分离开来。字符设备与块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般紧接着发生。块设备则不然,它利用一块系统内存作缓冲区,若用户进程对设备的请求能满足用户的要求,就返回请求的数据;否则,就调用请求函数来进行实际的I/O操作。网络设备可以通过BSD套接口访问数据。所有嵌入式Linux设备驱动程序都有一些共性,是编写所有类型的驱动程序都通用的,操作系统提供给驱动程序的支持也大致相同。这些特性包括:

稳定、源码开放、软件丰富、网络通信和文件管理机制完善等优良特性,成为嵌入式系统领域中的一个研究热点。嵌入式Linux系统中,内核提供保护机制,用户空间的进程一般不能直接访问硬件。进行嵌入式系统的开发,很大的工作量是为各种设备编写驱动程序,除非系统不使用操作系统。Linux设备驱动程序在Linux内核源代码中占有很大比例,从2.0、2.2到2.4版本的内核,源代码的长度日益增加,其实主要是设备驱动程序在增加。

设备驱动程序在Linux内核中占有极其重要的位置,它是内核用于完成对物理设备的控制操作的功能模块。除了CPU、内存以及其他很少的几个部分之外,所有的设备控制操作都必须由与被控设备相关的代码,也就是驱·52·2012年2月·www.infosting.org

软硬件·信息技术·Information

(1)读/写

几乎所有设备都有输入和输出。每个驱动程序都要负责本设备的读/写操作,操作系统的其它部分不需要知道对设备的具体读/写操作是怎样进行的,这些都由驱动程序屏蔽掉了。操作系统定义好一些读/写接口,由驱动程序完成具体的功能。在驱动程序初始化时,需要把具有这种接口的读/写函数注册到操作系统。

Technology

的定义如下:structfile_operations{structmodule*owner;

loft_t(*llseek)(structfile*,loff_t,int);

ssize_t(*read)(structfile*,char*,size_t,loft_t);ssize_t(*write)(structfile*,constchar*,size_t,1off_t*);int(readdirstructinode*,structfile*,void*,filldir_t);int(*select)(structinode*,structfile*,int,selecttable*);int(*ioct1)(structinode*,structfile*,unsignedint,unsignedint);

int

(*mmap)

(struct

inode*,struct

file*,struct

vm_area_struct*);

int(*open)(structinode*,structfile*);void(*release)(structinode*,structfile*);int(*fsync)(structinode*,structfile*);};

2.2.2注册和注销模块2.2.2.1设备注册模块

staticint_nitIOdriver_init(void){intret=0:

ret=register_chrdv

&IOdriv

if(ret)

{printk(KERN_ALERT“IOdriverregisterfailure!”)}else

{printk(KERN_ALERT“IOdriverregistersuccess!”)}

returnret;}

2.2.2.2设备注销模块

staticint_exitIOdriver_exit(void){intret=0;

ret=unregister_chrdv(MAJOR_NUM,“IOdriver”);if(ret)

{printk(KERN_ALERT“IOdriverunregister

failure!”);}

else

{printk(KERN_ALERT“IOdriverunregister

success!”);}

returnret;}

·53·信息安全与技术·2012年2月

(2)中断

中断在现代计算机结构中有重要的地位,操作系统必须提供驱动程序响应中断的能力。一般是把一个中断处理程序注册到系统中,操作系统在硬件中断发生后,调用驱动程序的处理程序。Linux支持中断的共享,即多个设备共享一个中断。

(3)时钟

在实现驱动程序时,很多地方会用到时钟,例如某些协议里的超时处理,没有中断机制的硬件的轮询等。操作系统应为驱动程序提供定时机制,一般是在预定的时间过了以后,回调注册的时钟函数。

嵌入式Linux系统驱动程序开发与普通Linux没有太多区别。嵌入式设备由于硬件种类非常丰富,在缺省的内核发布版中不可能包括所有驱动程序。可以在硬件生产厂家或者Intemet上寻找驱动程序,如果找不到,可以根据一个相近硬件的驱动程序来改写。实现一个嵌入式

(MAJOR_NUM,“IOdriver”,

Linux设备驱动的大致流程如下:(1)定义主、次设备号,

也可以动态获取;(2)实现驱动初始化和清除函数,如果驱动程序采用模块方式,则要实现模块初始化和清除函数;

(3)设计所要实现的文件操作,定义file_operations结构;(4)实现所需的文件操作调用,如read、write等;(5)实现中

断服务函数,并用requestirq向内核注册;(6)将驱动编译到内核或编译成模块,用insmod命令加载;(7)生成设备节点文件。

与普通文件相比,设备文件的操作要复杂得多,不可能简单地通过read、write和llseek等来实现。所有其它类型的操作都可以通过VFS的ioctl调用来执行,为此,只需要在驱动程序中实现ioctl函数,并在其中添加相应的

case即可。通过cmd区分操作,通过arg传递参数和结果。

2.2设备驱动程序的开发流程

2.2.1设备驱动接口

Structfile_operationIOdriver_fops={read:1Odriver_read,write:IOdriver_write,};

字符设备驱动接口中关键的file_operations结构:

InformationTechnology·信息技术·软硬件

2.2.3基本入口点设备函数的具体实现2.2.3.1设备读取模块

staticssize_tIOdriver_read(structfile*file,char*buf,size_tlen,loft_t*off)

{if(__copy_to_user(bur,&IOdriver_var,sizeof(int))){retum_EFAULT;}retumsizeof(int);}

2.2.3.2设备写入模块staticssize_tIOdriver_writechar*buf,size_tlen,loff_t*off)

{if(__copy_from_user(&IOdriver_var,buf,sizeof(int)))

{retum__EFAULT;}retumsizeof(int);}

2.2.4module_init和module_exit宏module_init(IOdriver_init);module_exit(IOdriver_exit);

(structfile*file,const

(4)重新编译内核,并更新嵌入式目标系统的内核。(5)创建设备文件,重新启动嵌入式目标系统的Linux,进入目录/proc,查看devices文件,在devices文件

列出了当前系统所有的字符设备和块设备,包括设备号和设备名称,在Characterdevices的最后移行的设备是:

254IOdriver,这说明IOdriver设备已经正确地加载到了

内核。

(6)添加设备文件节点,执行如下命令,添加设备文

件节点,在此创建的设备名称用于在应用程序中访问对应的设备。如果为字符设备,设备号类型用c表示,块设备则用b表示;主设备号就是/proc/devices中的IOdriver的设备号,由于该类设备只有一个,因此次设备号为0,如果还有该类型的其他设备,则一次为1、2、3等。

4结束语

设备驱动程序是操作系统内核和机器硬件之间的接

口。内核利用驱动程序的接口完成对设备的初始化和释放,在系统内核和硬件之间传送数据,并时刻检测和处理设备出现的错误。它是操作系统最基本的组成部分,因此熟悉驱动的编写是很重要的。

3设备驱动程序编译到内核的过程

把驱动程序编译进内核的步骤如下:

参考文献

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

[2]赵炯.Linux内核完全剖析--基于0.12内核[M].上海:机械工业

出版社,2009.

(1)把IOdriver.c复制到Linux-2.4.20-8/drivers/char

下,并修改该目录下的config.in文件,config.in是每个模块的配置脚本,在这个文件当中定义配置那些模块、怎样配置等,因此当添加了IO的配置后,会在内核配置时出现这个模块的配置选项。

[3]魏永明.Linux设备驱动程序[M].北京:中国电力出版社,2006.[4]吴迪.嵌入式系统原理、设计与应用[M].北京:机械工业出版社,2004.

[5]罗苑棠.嵌入式Linux应用系统开发实例精讲[M].北京:电子

工业出版社,2007.

(2)修改当前目录下的Makefile,在每个模块的Makefile中包括该模块所包含的子模块,在chardevices

中,要包括IO设备,就要告诉Makefile编译IOdriver.c并包含编译出的IOdriver.c文件,这样最后内核做链接时,才会链接进这个模块。

作者简介:

张玲玲(1985-),女,软件开发助理工程师;主要研究方向:软件设计。

(3)重新配置内核,选中IO模块执行命令makemenuconfig,进入内核配置菜单。

·54·2012年2月·www.infosting.org

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- baomayou.com 版权所有 赣ICP备2024042794号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务