首页 [哲学/历史]Linux设备驱动程序框架

[哲学/历史]Linux设备驱动程序框架

举报
开通vip

[哲学/历史]Linux设备驱动程序框架[哲学/历史]Linux设备驱动程序框架 Linux设备驱动程序框架 一、linux的设备驱动程序与外界的接口可以分为三个部分: 1(驱动程序与操作系统内核的接口。通过file_operations(include/linux/fs.h)数据结构来完成的。 2(驱动程序与系统引导的接口。这部分利用驱动程序对设备进行初始化。 3(驱动程序与设备的接口。这部分描述了驱动程序如何与设备进行交互,与具体的设备密切相关。 二、根据功能划分,设备驱动程序的代码有以下几部分: 1(驱动程序的注册和注销。 2(设备...

[哲学/历史]Linux设备驱动程序框架
[哲学/历史]Linux设备驱动程序框架 Linux设备驱动程序框架 一、linux的设备驱动程序与外界的接口可以分为三个部分: 1(驱动程序与操作系统内核的接口。通过file_operations(include/linux/fs.h)数据结构来完成的。 2(驱动程序与系统引导的接口。这部分利用驱动程序对设备进行初始化。 3(驱动程序与设备的接口。这部分描述了驱动程序如何与设备进行交互,与具体的设备密切相关。 二、根据功能划分,设备驱动程序的代码有以下几部分: 1(驱动程序的注册和注销。 2(设备的打开和释放。 3(设备的读写操作。 4(设备的控制操作。 5(设备的中断和轮询处理。 三、驱动程序的注册和注销: 设备驱动程序可以在系统启动的时候初始化,也可以在需要的时候动态加载。字符设备的初始化由chr_dev_init()完成,包括对内存 (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops)),终端(tty_init()),打印机(lp_init()),鼠标(misc_init())等字符设备的初始化。 块设备初始化由blk_dev_init()完成,这包括对IDE硬盘(ide_init()),软盘(floppy_init()),光驱等块设备的初始化。 每个字符设备或是块设备的初始化都是通过devfs_register_chrdev()或是devfs_register_blkdev()向内核注册。在关闭字符设备或是块设备时,还需要通过devfs_unregister_chrdev()或是devfs_unregister_blkdev()从内核中注销设备。 四、设备的打开和释放: 打开设备是由open()来完成的。例如,打印机是用lp_open()打开的,而硬盘是用hd_open()打开的。在大部分设备驱动程序中,open完成如下工作: 1(增加设备的是用计数。 2(检查设备的相关错误,如设备尚未准备好或是类似硬件的问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 。 3(检查是首次打开,则初始化设备。 4(识别次设备号,如有必要则更新f_op指针。 5(如果需要,分配且设置要放在filp->private_data里的数据结构。 释放设备由release()来完成,例如释放打印机是用lp_release(),而释放终端设备是用tty_release()。释放设备的一般步骤包括: 1(释放在filp->private_data中的open分配的内存。 2(如果是最后一次释放,则关闭设备。 3(递减设别的使用计数。 五、设备的读写操作: 字符设备使用各自的read()和write()来进行数据读写。例如,对虚拟终端的读写是通过vcs_read()和vcs_write()来进行数据读写的。 块设备使用通用的generic_file_read()和generic_file_write()来进行数据读写。这两个通用函数向请求 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 添加读写请求,内核可以通过ll_rw_block()优化请求顺序。由于是对内存缓冲区而不是设备进行操作的,因而可以加快读写请求。如果内存缓冲区内没有要读入的数据或是要将写请求写入设备,那么就要真正的执行数据传输。这是通过数据结构request_queue和request_fn()来完成(include/linux/blkdev.h)。 六、设备的控制操作: 除了读写操作,有时还要控制设备。这可以通过设备驱动程序中的ioctl()来完成。例如IDE硬盘的控制可以通过hd_ioctl(),对光驱的控制可以通过cdrom_ioctl()。 与读写操作不同,ioctl()的用法与具体设备密切相关。以软驱的floppy_ioctl()为例(drivers/block/floppy.c): static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param); 其中,cmd的取值及含义都是与软驱有关的,比如,FDEJECT表示弹出软盘。 除了ioctl(),设备驱动程序还可能有其他控制函数,比如llseek()等。 七、设备的轮询和中断处理: 对于不支持中断的设备,读写时需要轮询设备状态,以及是否需要继续进行数据传输。例如,打印机。如果设备支持中断,则可按照中断方式进行。 由于嵌入式设备由于硬件种类非常丰富,在默认的内核发布版中不一定包括所有驱动程序。所以进行嵌入式Linux系统的开发,很大的工作量是为各种设备编写驱动程序。除非系统不使用操作系统,程序直接操纵硬件。嵌入式Linux系统驱动程序开发与普通Linux开发没有区别。可以在硬件生产厂家或者Internet上寻找驱动程序,也可以根据相近的硬件驱动程序来改写,这样可以加快开发速度。实现一个嵌入式Linux设备驱动的大致流程如下: (1)查看原理图,理解设备的工作原理。一般嵌入式处理器的生产商提供参考电路,也可以根据需要自行 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 。 (2)定义设备号。设备由一个主设备号和一个次设备号来标识。主设备号惟一标识了设备类型,即设备驱动程序类型,它是块设备表或字符设备表中设备表项的索引。次设备号仅由设备驱动程序解释,区分被一个设备驱动控制下的某个独立的设备。 (3)实现初始化函数。在驱动程序中实现驱动的注册和卸载。 (4)设计所要实现的文件操作,定义file_operations结构。 (5)实现所需的文件操作调用,如read、write等。 (6)实现中断服务,并用request_irq向内核注册,中断并不是每个设备驱动所必需的。 (7)编译该驱动程序到内核中,或者用insmod命令加载模块。 (8)测试该设备,编写应用程序,对驱动程序进行测试 包括设备注册在内,设备驱动的初始化函数主要完成的功能是有以下5项。 (1)对驱动程序管理的硬件进行必要的初始化。 对硬件寄存器进行设置。比如,设置中断掩码,设置串口的工作方式、并口的数据方向等。 (2)初始化设备驱动相关的参数。 一般说来,每个设备都要定义一个设备变量,用以保存设备相关的参数。在这一步骤里对设备变量中的项进行初始化。 (3)在内核注册设备。 调用register_chrdev()函数来注册设备。 (4)注册中断。 如果设备需要IRQ支持,则要使用request_irq()函数注册中断。 (5)其他初始化工作。 初始化部分一般还负责给设备驱动程序申请包括内存、时钟、I/O端口等在内的系统资源,这些资源也可以在open子程序或者其他地方申请。这些资源不用时,应该释放,以利于资源的共享。 若驱动程序是内核的一部分,初始化函数则要按如下方式声明: int __init chr_driver_init(void); 其中__init是必不可少的,在系统启动时会由内核调用chr_driver_init,完成驱动程序的初始化。 当驱动程序是以模块的形式编写时,则要按照如下方式声明: int init_module(void) 当运行后面介绍的insmod命令插入模块时,会调用init_module函数完成初始化工作。 设备驱动开发的基本函数: 1(I/O口函数 无论驱动程序多么复杂,归根结底,无非还是向某个端口或者某个寄存器位赋值,这个值只能是0或1。接收值的就是I/O口。与中断和内存不同,使用一个没有申请的I/O端口不会使处理器产生异常,也就不会导致诸如“segmentation fault”一类的错误发生。由于任何进程都可以访问任何一个I/O端口,此时系统无法保证对I/O端口的操作不会发生冲突,甚至因此而使系统崩溃。因此,在使用I/O端口前,也应该检查此I/O端口是否已有别的程序在使用,若没有,再把此端口标记为正在使用,在使用完以后释放它。 这样需要用到如下几个函数: int check_region(unsigned int from, unsigned int extent); void request_region(unsigned int from, unsigned int extent,const char *name); void release_region(unsigned int from, unsigned int extent); 调用这些函数时的参数为: ? from表示所申请的I/O端口的起始地址; ? extent为所要申请的从from开始的端口数; ? name为设备名,将会出现在/proc/ioports文件里; ? check_region返回0表示I/O端口空闲,否则为正在被使用。 在申请了I/O端口之后,可以借助asm/io.h中的如下几个函数来访问I/O端口: inline unsigned int inb(unsigned short port); inline unsigned int inb_p(unsigned short port); inline void outb(char value, unsigned short port); inline void outb_p(char?value, unsigned short port); 其中inb_p和outb_p插入了一定的延时以适应某些低速的I/O端口。 2(时钟函数 在设备驱动程序中,一般都需要用到计时机制。在Linux系统中,时钟是由系统接管的,设备驱动程序可以向系统申请时钟。与时钟有关的系统调用有: #include #include void add_timer(struct timer_list * timer); int del_timer(struct timer_list * timer); inline void init_timer(struct timer_list * timer); struct timer_list的定义为: struct timer_list { struct timer_list *next; struct timer_list *prev; unsigned long expires; unsigned long data; void (*function)(unsigned long d); }; 其中,expires是要执行function的时间。系统核心有一个全局变量jiffies表示当前时间,一般在调用add_timer时jiffies=JIFFIES+num,表示在num个系统最小时间间隔后执行function函数。系统最小时间间隔与所用的硬件平台有关,在核心里定义了常数HZ表示一秒内最小时间间隔的数目,则num*HZ表示num秒。系统计时到预定时间就调用function,并把此子程序从定时队列里删除,可见,如果想要每隔一定时间间隔执行一次的话,就必须在function里再一次调用add_timer。function的参数d即为timer里面的data项。 3(内存操作函数 作为系统核心的一部分,设备驱动程序在申请和释放内存时不是调用malloc和free,而代之以调用kmalloc和kfree,它们在linux/kernel.h中被定义为: void * kmalloc(unsigned int len, int priority); void kfree(void * obj); 参数len为希望申请的字节数,obj为要释放的内存指针。priority为分配内存操作的优先级,即在没有足够空闲内存时如何操作,一般由取值GFP_KERNEL解决即可。 4(复制函数 在用户程序调用read、write时,因为进程的运行状态由用户态变为核心态,地址空间也变为核心地址空间。由于read、write中参数buf是指向用户程序的私有地址空间的,所以不能直接访问,必须通过下面两个系统函数来访问用户程序的私有地址空间。 #include void memcpy_fromfs(void * to,const void * from,unsigned long n); void memcpy_tofs(void * to,const void * from,unsigned long n); memcpy_fromfs由用户程序地址空间往核心地址空间复制,memcpy_tofs则反之。参数to为复制的目的指针,from为源指针,n为要复制的字节数。 在设备驱动程序里,可以调用printk来打印一些调试信息,printk的用法与printf类似。printk打印的信息不仅出现在屏幕上,同时还 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 在文件syslog里。
本文档为【[哲学/历史]Linux设备驱动程序框架】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_792768
暂无简介~
格式:doc
大小:23KB
软件:Word
页数:0
分类:互联网
上传时间:2017-10-20
浏览量:15