[精选]Linux字符设备驱动程序培训教材.pptx
《[精选]Linux字符设备驱动程序培训教材.pptx》由会员分享,可在线阅读,更多相关《[精选]Linux字符设备驱动程序培训教材.pptx(43页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、 LinuxLinuxLinuxLinux字符设备驱动程序字符设备驱动程序字符设备驱动程序字符设备驱动程序Linux驱动程序的分类驱动程序的分类p字符设备驱动:用于驱动能够像字节流文件一样被访问的设备。应用程序通常可以利用open、close、read、write等系统调用访问字符设备驱动。p块设备驱动:块设备和字符设备只在系统内核内部的管理上有所区别。应用程序对于字符设备的每一个I/O操作都会被内核直接传递给对应的驱动程序;而应用程序对于块设备的操作要经过虚拟文件系统VFS和缓冲区管理系统间接地传递给驱动程序处理。p网络设备驱动:应用程序必须利用套接字socket接口访问网络设备。网络设备驱
2、动程序网络设备驱动程序字符设备驱动程序基本结构字符设备驱动程序基本结构 字符设备开发的基本步骤确定主设备号和次设备号实现字符驱动程序实现file_operations结构体构造字符设备结构体cdev在模块加载函数中注册字符设备在模块卸载函数中注销字符设备创立设备文件节点设备文件与设备号设备文件与设备号p为了表达“一切都是文件的设计思想,linux将每个已安装的设备都表示为一个设备文件。p设备文件通常位于/dev子目录。p对于字符设备,应用程序可以利用open、close、read、write等系统调用访问其设备文件,这些I/O操作都被直接传递给该设备文件所对应的设备。p每个设备文件中都存储了该
3、设备的“主设备号和“次设备号。p一般由同一个内核模块管理的多个设备占用同一个主设备号,具体设备用次设备号标识。p用mknodfilenamecmajorminor命令创立设备文件p用rmfilename命令删除设备文件。注意删除设备文件并不会影响驱动模块。应用程序如何访问设备应用程序如何访问设备fd1=open“/dev/ttyS1,O_RDWR;/阻塞fd2=open“/dev/ttyS1,O_RDWR|O_NONBLOCK;/非阻塞intreadintfd,constvoid*buf,size_tlength;intwriteintfd,constvoid*buf,size_tlength
4、;intlseekintfd,offset_toffset,intwhence;intioctlintfd,intcmd,void*arg;intcloseintfd;设备号的内部表达设备号的内部表达设备编号的内部表达设备编号的内部表达dev_t类型32位:用来保存设备编号包括主设备号12位和次设备号20位从dev_t获得主设备号和次设备号:MAJORdev_t;MINORdev_t;将主设备号和次设备号转换成dev_t类型:MKDEVint major,int minor;主设备号与次设备号主设备号与次设备号分配主设备号分配主设备号手工分配主设备号:找一个内核没有使用的主设备号来使用。#in
5、clude int register_chrdev_region dev_t first,unsigned int count,char*name;要分配的设备编要分配的设备编号范围的起始值,号范围的起始值,次设备号经常为次设备号经常为0所请求的连续设所请求的连续设备编号的个数备编号的个数和该编号范围关和该编号范围关联的设备名称联的设备名称主设备号与次设备号主设备号与次设备号动态分配主设备号:#include int alloc_chrdev_resiondev_t*dev,unsigned int firstminor,unsigned int count,char*name;输出的设备号要
6、使用的被请求的第一个次设备号主设备号与次设备号主设备号与次设备号释放设备号void unregister_chrdev_regiondev_t first,unsigned int count;通常在模块的去通常在模块的去除函数中调用。除函数中调用。记录字符设备的结构体记录字符设备的结构体cdev实现字符驱动程序实现字符驱动程序cdev 结构体结构体structcdevstructkobjectkobj;/*内嵌的kobject对象*/structmodule*owner;/*所属模块*/structfile_operations*ops;/*文件操作结构体*/structlist_headl
7、ist;dev_tdev;/*设备号*/unsignedintcount;cdev的的kobj、list、count字段不用我们关系和维护内核代字段不用我们关系和维护内核代劳,我们只需将其劳,我们只需将其ops字段指向为我们自己的字段指向为我们自己的file operations结构。结构。对cdev结构体的操作操作操作cdev的函数的函数voidcdev_initstructcdev*,structfile_operations*;structcdev*cdev_allocvoid;intcdev_addstructcdev*,dev_t,unsigned;voidcdev_delstruc
8、tcdev*;用于初始化cdev的成员,并建立cdev和file_operations之间的连接分别向系统删除一个cdev,完成字符设备的注销,通常在模块的卸载函数中调用分别向系统添加一个cdev,完成字符设备的注册,通常在模块加载函数中调用函数用于动态申请一个cdev内存file_operations 结构体结构体file_operations 结构体结构体字符驱动和内核的接口:在include/linux/fs.h定义字符驱动只要实现一个file_operations结构体并注册到内核中,内核就有了操作此设备的能力。struct file_operations struct module*
9、owner;loff_t*llseek struct file*,loff_t,int;ssize_t*read struct file*,char _user*,size_t,loff_t*;ssize_t*write struct file*,const char _user*,size_t,loff_t*;unsigned int*poll struct file*,struct poll_table_struct*;int*ioctl struct inode*,struct file*,unsigned int,unsigned long;int*open struct inode*
10、,struct file*;int*flush struct file*,fl_owner_t id;int*release struct inode*,struct file*;/;file_operations 结构体结构体file_operations的主要成员:的主要成员:struct module*owner:指向模块自身open:翻开设备release:关闭设备read:从设备上读数据write:向设备上写数据ioctl:I/O控制函数llseek:定位读写指针mmap:映射设备空间到进程的地址空间file operations的初始化的初始化struct file_operati
11、ons my_fops=.owner=THIS_MODULE,.llseek=my_llseek,.read=my_read,.write=my_write,.ioctl=my_ioctl,.open=my_open,.release=my_release,;file结构体结构体pfile结构代表一个翻开的文件,它由内核在应用程序open时创立,并将该文件所对应的fileoperations记录在file结构中。p在应用程序调用close函数,内核会释放该数据结构。struct file struct file_operations*f_op;unsigned int f_flags;fmod
12、e_tf_mode;loff_tf_pos;structdentry*f_dentryvoid*private_data;file结构体结构体file 结构体结构体file结构:结构:file_operations结构相关的一个结构体。描述一个正在翻开的设备文件。成员:loff_t f_pos:当前读/写位置unsigned int f_flags标识文件翻开时,是否可读或可写O_RDONLYO_NONBLOCKO_SYNCstruct file_operations*f_op文件相关的操作,指向所实现的structfile_operationsvoid*private_data:私有数据指针
13、。驱动程序可以将这个字段用于任何目的或者忽略这个字段。inode结构体结构体p内核用inode结构在内部表示文件,用于存储文件访问权限、属主、组、大小、生产时间等VFS关心的信息。p其字段中我们只关心i_rdev设备号,和i_cdev和该文件所对应的cdev结构p我们在创立设备文件时,内核会自动创立一个对应的inode结构体,并将其i_cdev字段指向对应的字符设备结构体cdev事先已经在内核中注册过。pInode与file的区别:file表示翻开的文件描述符,多个file结构,可以指向单个inode结构。struct inode dev_t i_rdev;struct cdev*i_cdev
14、;/;Inode结构体结构体Inode结构中的两个主要字段:结构中的两个主要字段:dev_t i_rdev;对表示设备文件的inode结构,该字段包含了真正的设备编号。struct cdev*i_cdev;structcdev是表示字符设备的内核的内部结构。当inode指向一个字符设备文件时,该字段包含了指向structcdev结构的指针从一个从一个inode中获得主设备号和次设备号:中获得主设备号和次设备号:unsignedintiminorstructinode*inode;unsignedintimajorstructinode*inode;字符设备驱动程序基本结构字符设备驱动程序基本结
15、构 注册设备注册设备,在模块或驱动初始化时调用Linux-2.4及之前Linux-2.6intregister_chrdevunsignedintmajor,constchar*name,structfile_operations*fops如何操作字符设如何操作字符设备的接口备的接口voidcdev_initstructcdev*,structfile_operations*;intcdev_addstructcdev*,dev_t,unsigned;字符设备驱动程序基本结构字符设备驱动程序基本结构 注销设备:在模块卸载时调用Linux-2.4及之前Linux-2.6intunregister
16、_chrdevunsignedintmajor,constchar*name;voidcdev_del structcdev*;字符设备驱动程序基本结构字符设备驱动程序基本结构/设备驱动模块加载函数设备驱动模块加载函数static int _init xxx_initvoid .cdev_init&xxx_dev.cdev,&xxx_fops;/初始化初始化cdevxxx_dev.cdev.owner=THIS_MODULE;/获取字符设备号获取字符设备号if xxx_major register_chrdev_regionxxx_dev_no,1,DEV_NAME;elsealloc_chr
17、dev_region&xxx_dev_no,0,1,DEV_NAME;ret=cdev_add&xxx_dev.cdev,xxx_dev_no,1 ;/注册设备注册设备.字符设备驱动程序基本结构字符设备驱动程序基本结构/*设备驱动模块卸载函数*/staticvoid_exitxxx_exitvoidunregister_chrdev_regionxxx_dev_no,1;/释放占用的设备号cdev_del&xxx_dev.cdev;/注销设备.字符设备驱动程序基本结构字符设备驱动程序基本结构 翻开翻开模块使用计数加1识别次设备号硬件操作:检查设备相关错误诸如设备未就绪或类似的硬件问题;如果设备
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 精选 Linux 字符 设备 驱动程序 培训教材
限制150内