Linux字符设备驱动机制探索论文精品由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“基于linux驱动论文”。
Linux字符设备驱动机制探索论文
课程名称 Linux内核设计与实现
姓 名 王 华 山
班 级 10计科(嵌入式)
学 号 1031301224
院 系 数计学院
专 业 计算机科学与技术
目录„„„„„„„„„„„„„„„„„„„„„„„„„1 一.字符设备概述„„„„„„„„„„„„„„„„„„..2
二.相关数据结构之间的关系说明………………………………10
三.字符设备驱动实例„„„„„„„„„„„„„„..12
四.字符设备驱动中的并发控制„„„„„„„„„„..19
五.字符设备的阻塞与非阻塞操作„„„„„„„„„„„.21
六.参考文献„„„„„„„„„„„„„„„„„„„„.23
七.心得体会„„„„„„„„„„„„„„„„„„„..24
一.字符设备概述
1.字符设备是指在I/O传输过程中以字符为单位进行传输的设备,例如键盘,打印机等。但以字符为单位并不一定是指以字节为单位。
字符设备驱动程序中会涉及到许多有关设备的概念,如什么是设备文件、什么是主次设备号、如何注销设备号、字符设备中有哪些主要的数据结构及它们的作用各是什么、各种函数调用方法等等,下面介绍部分相关概念。(1)设备文件及其作用
概念:linux 设备文件就是一个实实在在看得见的文件,只不过这个文件是“设备类型”,它是用来代表一个设备的,一般在设备驱动加载之后创建,在设备驱动卸载后移除。有了设备文件,如果想对设备进行等操作。只需对设备文件进行等操作即可。实现流程:设备文件操作----->系统内核----->设备驱动----->硬件设备,设备文件也是一个文件,c 库中对文件的操作包括打开、写、读、定位等,分别是通过fopen、fwrite、fread、fseek 等c 库函数实现的。
作用:设备驱动的作用就是将这些对设备文件的打开、读、写、定位等操作转化为对硬件设备的打开、读、写、定位等操作。创建设备文件的方法:1.手工创建mknod 方法:mknok filename type major minor(major-主设备号;minor-次设备号;type-设备类型可取:c(字符设备),b(块设备))执行此命令 之后就可以看到在当前目录下生成了一个名为filename 的文件。2.自动创建
(2)主次设备号及其作用
概念:设备号就是系统为设备分配的一个编号。在/dev 目录下-ll,可以看到有每个设备文件都有两个号,他们就是主次设备号。
作用:主设备号是用来标识与设备文件相连的驱动程序,主设备号用来反映设备类型;次设备号被驱动程序用来辨别操作的是哪个设备,次设备号用来区分同类型的设备。设备文件需要设备号才能创建;设备驱动也需要设备号才能装载。设备文件正是通过主设备号找到它的驱动;设备驱动正是利用次设备号才知道他要操作的具体是哪个设备。内核中描述设备号的方法:
内核中用dev_t 类型来描述,其实质是是unsigned int 32位整数,其中高12位为主设备号,低20位为次设备号用宏MAJOR(dev_t dev)解出主设备号,MINOR(dev_t dev)分解出次设备号。(3)linux内核分配主次设备号的静态申请:1.根据/documentation/devices.txt,确定一个没有使用的主设备号 2.使用register_chrdev_region 函数注册设备号:int register_chrdev_region(dev_t from,unsigned count,const char *name)(from-希望使用的设备号;count-望申请使用的设备号数目;nanme-shebeiming(体现在/proc/devices))静态注册的缺点是移植时容易发生冲突,但是简单。
动态分配:使用allo_chrdev_region 分配设备号:int allo_chrdev_region(dev_t *dev,unsigned baseminor, unsigned count,const char name)(dev 非配到的设备号)
baseminor-起始次设备号count-需要分配的设备号数目;name-设备名)(4)注销设备号的方法
设备号是宝贵的资源,都应该在不再使用它们时释放这些设备号
void unregister_chrdev_region(dev_t from,unsigned cout|):释放从from 开始的count 个设备号
2.在linux系统中,字符设备以特别文件方式在文件目录树中占据位置并拥有相应的i结点。i结点中的文件类型指明该文件是字符设备文件。可以使用与普通文件相同的文件操作命令对字符设备文件进行操作,例如打开、关闭、读、写等。字符设备是最基本、最常用的设备。概括的说,字符设备驱动主要要做三件事:
1、定义一个结构体static struct file_operations变量,其内定义一些设备的打开、关闭、读、写、控制函数;
2、在结构体外分别实现结构体中定义的这些函数;
3、向内核中注册或删除驱动模块。
下面我们来假设一个非常简单的虚拟字符设备:这个设备中只有一个4 个字节的全局变量int global_var,而这个设备的名字叫做“simchr”。对“simchr”设备的读写等操作即是对其中全局变量global_var 的操作。驱动程序是内核的一部分,因此我们需要给其添加模块初始化函数,该函数用来完成对 所控设备的初始化工作,并调用register_chrdev()函数注册字符设备: static int __init gobalvar_init(void){ if(register_chrdev(MAJOR_NUM, “ simchr ”, &gobalvar_fops)){ //„注册失败 } else { //„注册成功 } } 其中,register_chrdev 函数中的参数MAJOR_NUM 为主设备号,“simchr”为设备名,gobalvar_fops 为包含基本函数入口点的结构体,类型file_operations。当simchr 模块被加载时,gobalvar_init 被执行,它将调用内核函数register_chrdev,把驱动程序的基本入口点指针存放在内核的字符设备地址表中,在用户进程对该设备执行系统调用时提供入口地址。与模块初始化函数对应的就是模块卸载函数,需要调用 register_chrdev()的“反函数” unregister_chrdev():
static void __exit gobalvar_exit(void){ if(unregister_chrdev(MAJOR_NUM, “ simchr ”)){ //„卸载失败 } else { //„卸载成功 } }
随着内核不断增加新的功能,file_operations 结构体已逐渐变得越来越大,但是大多数的驱动程序只是利用了其中的一部分。对于字符设备来说,要提供的主要入口有:open()、release()、read()、write()、ioctl()、llseek()、poll()等。open()函数 对设备特殊文件进行open()系统调用时,将调用驱动程序的open()函数:int(*open)(struct inode * ,struct file *);其中参数inode 为设备特殊文件的inode(索引结点)结构的指针,参数file 是指向这一 设备的文件结构的指针。open()的主要任务是确定硬件处在就绪状态、验证次设备号的合法性(次设备号可以用MINOR(inode-> iERESTARTSYS;} if(down_interruptible(&sem)){ returnEFAULT;} up(&sem);return sizeof(int);} static ize_t simchr_write(struct file *filp, const char *buf, size_t len, loff_t *off)19 { if(down_interruptible(&sem)){ returnEFAULT;} up(&sem);flag = 1;//通知数据可获得
wake_up_interruptible(&outq);return sizeof(int);} module_init(simchr_init);module_exit(simchr_exit);编写两个用户态的程序来测试,第一个用于阻塞地读/dev/simchr,另一个用于写/dev/simchr。只有当后一个对/dev/simchr 进行了输入之后,前者的read 才能返回。打开两个终端,分别运行上述两个应用程序,发现当在第二个终端中没有输入数据时,第一个终端没有输出(阻塞),每当我们在第二个终端中给simchr输入一个值,第一个终端就会输出这个值
六.参考文献
《linux设备驱动第三版》(第一章 设备驱动简介、第三章 字符驱动、第四章并发和竞争情况、第十一章 内核中的数据类型、第十四章 Linux设备模型《linux内核设计与实现》、百度文库(Linux字符设备驱动程序设计概述、Linux字符设备驱动实例、字符设备驱动基本编程、深入浅出Linux设备驱动编程、Linux字符设备驱动学习笔记等)
七.心得体会
通过这次论文设计,对Linux系统的字符设备驱动有了初步的认识:Linux下的设备驱动程序分为字符设备驱动、快设备驱动和网络设备驱动程序。驱动程序在硬件和软件之间起纽带的作用,用户进程是通过设备文件来与实际的硬件打交
道.每个设备文件都有其文件属性,表示是字符设备还是块设备。每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备。