您的位置 首页 FPGA

根据嵌入式Linux内核的体系设备驱动程序开发规划

基于嵌入式Linux内核的系统设备驱动程序开发设计-Linux是一个遵循POSIX标准的免费操作系统。具有BSD和SYSV的扩展特性。与其他操作系统相比,嵌入式Linux系统以其可应用于多种硬件平台、内核高效稳定、源码开放、软件丰富、网络通信和文件管理机制完善等优良特性而正被作为研究热点,越来越多的研究人员采用Linux平台来开发自己的产品。Linux设备驱动程序在Linux内核源代码中占有很大比例,从2.0、2.2到 2.4版本的内核,源代码的长度日益增加,其实主要是设备驱动程序在增加。

导言

Linux是一个遵从POSIX规范的免费操作体系。具有BSD和SYSV的扩展特性。与其他操作体系比较,嵌入式Linux体系以其可应用于多种硬件渠道、内核高效安稳、源码敞开、软件丰厚、网络通信和文件办理机制完善等优秀特性而正被作为研讨热门,越来越多的研讨人员选用Linux渠道来开发自己的产品。Linux设备驱动程序在Linux内核源代码中占有很大份额,从2.0、2.2到 2.4版别的内核,源代码的长度日益添加,其实首要是设备驱动程序在添加。

依据嵌入式Linux内核的体系设备驱动程序开发规划

设备驱动程序的编写

设备驱动程序是linux内核的一部分,是操作体系内核和机器硬件之间的接口,它由一组函数和一些私有数据组成,是衔接应用程序与详细硬件的桥梁。Linux的一个根本特点是它对硬件设备的办理抽象化,体系中的每一个设备都用一个特别的文件来表明。一切的硬件设备都像一般的文件相同看待,运用与操作体系相同的规范体系来进行翻开、读写和封闭。

在Linux 操作体系下有3类首要的设备文件类型:块设备、字符设备、网络设备。字符设备是指存取时没有缓存的设备。可像文件相同拜访字符设备,字符设备驱动程序担任完成这些行为。体系的控制台和并口便是字符设备的比方,它们能够很好地用“流”来描绘。块设备是文件体系的宿主,如磁盘。 Linux答应像字符设备那样读取块设备——答应一次传输恣意数目的字节。成果是,字符设备和块设备读取数方法共同。而网络设备不同于字符设备和块设备, 它面向的上一层不是文件体系而是网络协议层,是经过BSD套接口拜访数据。与设备相对应的是三类设备驱动程序,字符设备驱动程序、块设备驱动程序、网络设备驱动程序。

字符设备驱动程序、块设备驱动程序与网络设备驱动程序的结构体是不同的。

在linux 源代码linux/ include / linux/ fs. h中界说了字符设备和块设备驱动程序中有必要运用的file_operations结构,每个设备驱动都完成这个接口所界说的部分或悉数函数。跟着内核的不断晋级, file_operaTIons结构也越来越大,不同的版别的内核会稍有不同。file_operaTIons界说如下:

struct file_operaTIons{

int( * lseek) ( struct inode * , struct file * , off_t , int) ; int( *release) ( struct inode * , struct file * ) ;

int( * read) ( struct inode * , struct file * , char * , int) ; int( * fsync) ( struct inode *, struct file * ) ;

int( *write) ( struct inode * , struct file * , const char *, int) ; int( * fasync) ( struct inode * , struct file *, int) ;

int( * readdir) ( struct inode , struct file , void * , dilldir) ; int( *check_media_change) ( kdev_t dev) ;

int(*select) ( struct inode *, struct file * , int, select_table * ) ; int( * revalidate) ( kdev_t dev) ; };

int ( * ioctl) ( struct inode * , struct file *, unsigned int, unsigned long) ;

int( *mmap) ( struct inode * , struct file * , struct vm_area_struct * ) ;

int( * open) ( struct inode *, struct file *) ;

应用程序只要经过对设备文件的open、release、read、write、ioctl等才干拜访字符设备和块设备。用户自己界说好 file_operaTIons结构后,编写出设备实践所需求的各操作函数,关于不需求的操作函数用NULL初始化,这些操作函数将被注册到内核,当应用程序对设备相应的设备文件进行文件操作时,内核会找到相应的操作函数,并进行调用。假如操作函数运用NULL,操作函数就进行默许处理。

关于字符设备而言,llseek( ),read( ),write(),ioctl( ),open( ),release( )这些函数是不行缺的;关于块设备,open( ),release( ),ioctl(),check_media_change( ),revalidate( )是不行短少的。

网络设备结构体 net_device 界说在 includelinuxnetdevice.h 里,如下所示:

struct net_device

{

char name ; int (*init)(struct

net_device *dev);

unsigned short flags ; int (*open)

(struct net_device *dev);

unsigned long base_addr; int

(*stop)(struct net_device *dev)

unsigned int irq ; int

(*hard_start_xmit)(struct sk_buff *skb,

unsigned char dev_addr; struct

net_device *dev);

unsigned char addr_len; int

(*set_mac_address)( struct net_device

unsigned long trans_start; *dev,void* addr);

……

}

界说好net_device结构体后,依据实践情况编写操作函数,其间hard_start_xmit()函数是用来发送数据的,set_mac_address()是进行网络参数设置的。

当linux初始化时将调用初始化函数int device_init( ),该函数包含以下内容:

注册所用设备。linux用设备号来标识字符设备和块设备。设备号分为主设备号和从设备号,终究构成设备接点。设备节点在拜访字符设备和块设备的设备驱动程序时将运用。一般主设备号标识设备对应的驱动程序,大多数设备是“一个主设备号对应一个驱动程序”,如:虚拟控制台和串口终端由驱动程序4办理。次设备号由内核运用,用于确认设备文件所指的设备。字符设备和块设备注册时有必要先界说好设备号。

字符设备注册函数如下:

int register_chrdev(unsigned int major ,const char *name, struct file_oprations *fops);

其间 major是主设备号。

由于对网络设备驱动程序的拜访不需求设备节点,它的注册函数如下:

int register_netdev(struct net_device *dev)

注册设备所用的中止。中止在现代计算机结构中有重要的位置,操作体系有必要供给程序呼应中止的才能。一般是把一个中止处理程序注册到体系中去。操作体系在硬件中止发生后调用驱动程序的处理程序。

注册中止所用的函数如下:

int request_irq (unsigned irq,void(*handler)(int,void*,struct pt_regs*),unsigned long flags,const char*device,void* dev_id);

其间,irq是中止向量;handler是中止处理函数;flags是中止处理中的掩码;devices是设备名;dev_id是在中止同享运用的id。

当linux不运用该设备时,就要调用铲除函数void_devicie_exit ( ),它同初始化函数相对应的,首要是:

刊出设备,字符设备刊出函数如下:

int unregister_chrdev(unsigned int major ,const char *name, struct file_oprations *fops);

刊出中止,刊出中止所用的函数如下:

int free_irq (unsigned irq,void(*handler)(int,void*,struct pt_regs*),unsigned long flags,const char*device,void* dev_id);

开释资源,模块初始化和铲除函数选用module_init(device_init),module_exit(device_exit) 方式

编写服务子程序

服务于I/O恳求的子程序,又称为驱动程序的上半部分。调用这部分是由于体系调用的成果。这部分程序在履行的时分.体系仍认为是和进行调用的进程归于同一个进程. 仅仅用户态变成了核心态,具有进行此体系调用的用户程序的运转环境.因而能够在其间调用sleep等与进程运转环境有关的函数。

中止服务子程序,又称为驱动程序的下半部分。在Linux体系中.并不是直接从中止向量表中调用设备驱动程序的中止服务子程序,而是由Linux体系来接纳硬件中止,再由体系调用中止服务子程序。中止能够发生在任何一个进程运转的时分,因而在中止服务程序被调用的时分.不能依赖于仟何进程的状况,也就不能调用任何与进程运转环境相关的函数。由于设备驱动程序一般支撑同一类型的若干设备,所以一般在体系调用中止服务程序的时分,都带有一个或多个参数,以仅有标识恳求服务的设备。

设备驱动程序的运用

直接将驱动程序编译进linux内核

将设备驱动程序复制到 linux/drivers相关的子目录下,比方字符设备驱动程序 就放在linux/drivers/char下。

修正linux/drivers相关的子目录的Makefile,

如obj-$(config_dev_driver) +=dev_driver.o,这样在编译内核时将会编译dev_driver.c,生成 dev_driver.o.

对内核进行从头编译时,进行相关的装备,比方要运用AT91RM9200的UART,就要如下装备:

Character devices -》 Serial drivers -》AT91RM9200 serial port support

将驱动程序编译成驱动模块

在设备驱动程序中要有两个重要函数:

module_init(dev_init),module_exit(dev_exit)

运用相应的穿插编译器以及编译指令将驱动程序dev_driver.c编译成dev_driver.o 这样的动态驱动模块。运用insmod指令给体系装置驱动模块,假如在/dev目录下没有相应的设备文件,就能够运用mknod创立一个设备文件。运用 rmmod指令卸载驱动模块,设备文件的删去能够用rm指令。

结语

设备驱动程序的开发是在Linux环境中最杂乱的编程使命之一 。它需求和硬件打交道,简单引起体系溃散,并且很难调试。把握设备驱动程序的开发技能,将使得开发嵌入式Linux的体系更为敏捷和有用。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/fpga/100622.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部