




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux字符设备驱动程序第1页Linux驱动程序分类字符设备驱动:用于驱动能够像字节流(文献)同样被访问设备。应用程序一般能够利用open、close、read、write等系统调用访问字符设备驱动。块设备驱动:块设备和字符设备只在系统内核内部管理上有所区分。应用程序对于字符设备每一种I/O操作都会被内核直接传递给对应驱动程序;而应用程序对于块设备操作要通过虚拟文献系统(VFS)和缓冲区管理系统间接地传递给驱动程序处理。网络设备驱动:应用程序必须利用套接字(socket)接口访问网络设备。第2页第3页网络设备驱动程序第4页字符设备驱动程序基本构造字符设备开发基本步骤确定主设备号和次设备号实现字符驱动程序实现file_operations构造体构造字符设备构造体cdev在模块加载函数中注册字符设备在模块卸载函数中注销字符设备创建设备文献节点第5页设备文献与设备号为了体现“一切都是文献”设计思想,linux将每个已安装设备都表达为一种设备文献。设备文献一般位于/dev子目录。对于字符设备,应用程序能够利用open、close、read、write等系统调用访问其设备文献,这些I/O操作都被直接传递给该设备文献所对应设备。每个设备文献中都存放了该设备“主设备号”和“次设备号”。一般由同一种内核模块管理多种设备占用同一种主设备号,详细设备用次设备号标识。用mknodfilenamecmajorminor命令创建设备文献用rmfilename命令删除设备文献。注意删除设备文献并不会影响驱动模块。第6页应用程序如何访问设备fd1=open(“/dev/ttyS1”,O_RDWR);//阻塞fd2=open(“/dev/ttyS1”,O_RDWR|O_NONBLOCK);//非阻塞intread(intfd,constvoid*buf,size_tlength);intwrite(intfd,constvoid*buf,size_tlength);intlseek(intfd,offset_toffset,intwhence);intioctl(intfd,intcmd,void*arg);intclose(intfd);第7页设备号内部体现设备编号内部体现dev_t类型(32位):用来保存设备编号(包括主设备号(12位)和次设备号(20位))从dev_t取得主设备号和次设备号:MAJOR(dev_t);MINOR(dev_t);将主设备号和次设备号转换成dev_t类型:MKDEV(intmajor,intminor);
第8页主设备号与次设备号分派主设备号手工分派主设备号:找一种内核没有使用主设备号来使用。#include<linux/fs.h>intregister_chrdev_region(dev_tfirst,unsignedintcount,char*name);要分派设备编号范围起始值,次设备号经常为0所祈求连续设备编号个数和该编号范围关联设备名称第9页主设备号与次设备号动态分派主设备号:#include<linux/fs.h>intalloc_chrdev_resion(dev_t*dev,unsignedintfirstminor,unsignedintcount,char*name);输出设备号要使用被祈求第一种次设备号第10页主设备号与次设备号释放设备号voidunregister_chrdev_region(dev_tfirst,unsignedintcount);一般在模块清除函数中调用。第11页统计字符设备构造体cdev实现字符驱动程序cdev构造体structcdev{ structkobjectkobj;/*内嵌kobject对象*/ structmodule*owner;/*所属模块*/ structfile_operations*ops;/*文献操作构造体*/ structlist_headlist; dev_tdev;/*设备号*/ unsignedintcount;};cdevkobj、list、count字段不用我们关系和维护(内核代劳),我们只需将其ops字段指向为我们自己fileoperations构造。第12页对cdev构造体操作操作cdev函数voidcdev_init(structcdev*,structfile_operations*);structcdev*cdev_alloc(void);intcdev_add(structcdev*,dev_t,unsigned);voidcdev_del(structcdev*);用于初始化cdev组员,并建立cdev和file_operations之间连接分别向系统删除一种cdev,完成字符设备注销,一般在模块卸载函数中调用分别向系统添加一种cdev,完成字符设备注册,一般在模块加载函数中调用函数用于动态申请一种cdev内存第13页file_operations构造体file_operations构造体字符驱动和内核接口:在include/linux/fs.h定义字符驱动只要实现一种file_operations构造体并注册到内核中,内核就有了操作此设备能力。structfile_operations{
structmodule*owner; loff_t(*llseek)(structfile*,loff_t,int); ssize_t(*read)(structfile*,char__user*,size_t,loff_t*); ssize_t(*write)(structfile*,const
char__user*,size_t,loff_t*);
unsigned
int(*poll)(structfile*,structpoll_table_struct*);
int(*ioctl)(structinode*,structfile*,unsigned
int,unsigned
long);
int(*open)(structinode*,structfile*);
int(*flush)(structfile*,fl_owner_tid);
int(*release)(structinode*,structfile*);//………};第14页file_operations构造体
file_operations主要组员:structmodule*owner:
指向模块本身open:打开设备release:关闭设备read:从设备上读数据write:向设备上写数据ioctl:I/O控制函数llseek:定位读写指针mmap:映射设备空间到进程地址空间第15页fileoperations初始化structfile_operationsmy_fops={.owner=THIS_MODULE,.llseek=my_llseek,.read=my_read,.write=my_write,.ioctl=my_ioctl,.open=my_open,.release=my_release,};第16页file构造体file构造代表一种打开文献,它由内核在应用程序open时创建,并将该文献所对应fileoperations统计在file构造中。在应用程序调用close函数,内核会释放该数据构造。structfile{ structfile_operations *f_op; unsignedint f_flags; fmode_t f_mode; loff_t f_pos;struct dentry *f_dentry void* private_data;};第17页file构造体file构造体
file构造:file_operations构造有关一种构造体。描述一种正在打开设备文献。组员:loff_tf_pos:
目前读/写位置unsignedintf_flags标识文献打开时,是否可读或可写O_RDONLYO_NONBLOCKO_SYNCstructfile_operations*f_op文献有关操作,指向所实现structfile_operationsvoid*private_data:
私有数据指针。驱动程序能够将这个字段用于任何目标或者忽视这个字段。第18页inode构造体内核用inode构造在内部表达文献,用于存放文献访问权限、属主、组、大小、生产时间等VFS关怀信息。其字段中我们只关怀i_rdev(设备号),和i_cdev(和该文献所对应cdev构造)我们在创建设备文献时,内核会自动创建一种对应inode构造体,并将其i_cdev字段指向对应字符设备构造体cdev(事先已经在内核中注册过)。Inode与file区分:file表达打开文献描述符,多种file构造,能够指向单个inode构造。structinode{ dev_ti_rdev; structcdev*i_cdev; //………};第19页Inode构造体Inode构造中两个主要字段:dev_ti_rdev;对表达设备文献inode构造,该字段包括了真正设备编号。structcdev*i_cdev;structcdev是表达字符设备内核内部构造。当inode指向一种字符设备文献时,该字段包括了指向structcdev构造指针从一种inode中取得主设备号和次设备号:unsignedintiminor(structinode*inode);unsignedintimajor(structinode*inode);第20页字符设备驱动程序基本构造注册设备
,在模块或驱动初始化时调用Linux-2.4及之前Linux-2.6intregister_chrdev(unsignedintmajor,constchar*name, structfile_operations*fops)如何操作字符设备接口voidcdev_init(structcdev*,structfile_operations*);intcdev_add(structcdev*,dev_t,unsigned);第21页字符设备驱动程序基本构造注销设备:在模块卸载时调用Linux-2.4及之前Linux-2.6intunregister_chrdev(unsignedintmajor, constchar*name);voidcdev_del(structcdev*);第22页字符设备驱动程序基本构造//设备驱动模块加载函数staticint__initxxx_init(void){ ... cdev_init(&xxx_dev.cdev,&xxx_fops);//初始化cdev xxx_dev.cdev.owner=THIS_MODULE; //获取字符设备号 if(xxx_major) { register_chrdev_region(xxx_dev_no,1,DEV_NAME); } else { alloc_chrdev_region(&xxx_dev_no,0,1,DEV_NAME); } ret=cdev_add(&xxx_dev.cdev,xxx_dev_no,1);//注册设备 ...}第23页字符设备驱动程序基本构造/*设备驱动模块卸载函数*/staticvoid__exitxxx_exit(void){ unregister_chrdev_region(xxx_dev_no,1);//释放占用设备号
cdev_del(&xxx_dev.cdev);//注销设备 ...}第24页字符设备驱动程序基本构造打开模块使用计数加1识别次设备号硬件操作:检查设备有关错误(诸如设备未就绪或类似硬件问题);假如设备是初次打开,则对其初始化;假如有中断操作,申请中断处理程序;intopen(structinode*inode,structfile*filp);第25页字符设备驱动程序基本构造关闭模块使用计数减1释放由open分派,保存在filp>private_data里所有内容。硬件操作:假如申请了中断,则释放中断处理程序。在最后一次关闭操作时关闭设备。intrelease(structinode*inode,structfile*filp);第26页字符设备驱动程序基本构造
read/writessize_tread(structfile*filp,char__user*buff,size_tcount,loff_t*offp);ssize_twrite(structfile*filp,constchar__user*buff,size_tcount,loff_t*offp);指向顾客空间缓冲区,这个缓冲区或者保存将写入数据,或者是一种寄存新读入数据空缓冲区。顾客在文献中存取操作位置第27页字符设备驱动程序基本构造
顾客空间和内核空间之间数据拷贝过程,不能简单用指针操作或者memcpy来进行数据拷贝顾客空间数据是能够被换出,会产生一种页面失效异常。顾客空间地址无法在内核空间中使用。顾客空间和内核空间之间进行数据拷贝函数:假如要复制内存是简单类型,如char、int、long等,put_user()和get_user()unsignedlongcopy_from_user(void*to,constvoid__user*from,unsignedlongcount);unsignedlongcopy_to_user(void__user*to,constvoid*from,unsignedlongcount);第28页字符设备驱动程序基本构造读设备模板ssize_txxx_read(structfile*filp,char__user*buf, size_tcount,loff_t*f_pos){ ... copy_to_user(buf,...,...); ...}写设备模板ssize_txxx_write(structfile*filp,constchar__user*buf, size_tcount,loff_t*f_pos){ ... copy_from_user(...,buf,...); ...}第29页字符设备驱动程序基本构造
ioctl函数为设备驱动程序执行“命令”提供了一种特有入口点用来设置或者读取设备属性信息。intioctl(structinode*inode,structfile*filp, unsignedintcmd,unsignedlongarg);事先定义IO控制命令代码arg为对应于cmd命令参数第30页字符设备驱动程序基本构造cmd参数定义不推荐用0x1,0x2,0x3之类值Linux对ioctl()cmd参数有特殊定义构造命令编号宏:_IO(type,nr)用于构造无参数命令编号;_IOR(type,nr,datatype)用于构造从驱动程序中读取数据命令编号;_IOW(type,nr,datatype)用于写入数据命令;_IOWR(type,nr,datatype)用于双向传输。type和number位字段通过参数传入,而size位字段通过对datatype参数取sizeof取得。
设备类型(type)
序列号(number)方向(direction)
数据尺寸(size)
8bit
8bit
2bit13/14bit第31页字符设备驱动程序基本构造Ioctl函数模板intxxx_ioctl(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg){ ... switch(cmd) { caseXXX_CMD1: ... break; caseXXX_CMD2: ... break; default:///*不能支持命令*/ return-ENOTTY; } return0;}第32页阶段总结第33页阶段总结第34页添加驱动程序到内核配备内核编译内核添加驱动程序到内核中第35页添加驱动程序到内核配备内核配备命令包括: makeconfig makemenuconfig makexconfig makegconfig
可通过“上”、“下”、“左”、“右”键移动菜单,选择某项按“Y”,取消选择按“N”,假如选择某项编译为模块按“M”,进入子菜单按“Enter”,返回上一级菜单按“Esc”使用makeconfig、makemenuconfig等命令后,会生成一种.config配备文献(是隐身文献,通过ls–a才能看到)
第36页添加驱动程序到内核编译内核可用如下命令编译内核:makeARC=armCROSS_COMPILE=arm-linux-zImage源代码根目录Makefile中将ARCH和CROSS_COMPILE直接指定为arm和arm-linux-,如:
这样就没有必要每次编译时候都指定体系构造和交叉编译器了,只须使用下面命令就能够了:
makezImageARCH ?=armCROSS_COMPILE ?=arm-linux-第37页添加驱动程序到内核添加驱动程序到内核Linux2.6内核配备系统由下列3个部分组成。Makefile:分布在Linux内核源代码中Makefite定义Linux内核编译规则配备文献(Kconfig):给顾客提供配备选择功能。配备工具:包括配备命令解释器(对配备脚本中使用配备命令进行解释)配备顾客界面(提供字符界面和图形界面)。这些配备工具都是使用脚本语言编写,如Tcl/TK、Perl等。在Linux内核中增加程序需要完成下列3项工作。将编写源代码复制到Linux内核源代码对应目录。在目录Kconfig文献中增加新源代码对应项目标编译配备选项。在目录Makefile文献中增加对新源代码编译条目。第38页添加驱动程序到内核实例:在内核源代码drivers目录下为ARM体系构造新增testdrivertestdriver树形目录:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025有关办公室租赁合同
- 2025重型机械租赁合同范文
- 2025上海写字楼租赁合同范本
- 2025商务住宅买卖合同模板
- 2025办公室租赁合同标准范本
- 2025实验中学安全岗位承包合同
- 2025合同签署的授权委托书
- 2025年《企业试用合同协议》范本
- 2025年付里叶红外分光光度计合作协议书
- 防水投标施工方案
- 2025年第三届天扬杯建筑业财税知识竞赛题库附答案(201-300题)
- T-NKFA 015-2024 中小学午休课桌椅
- 课题开题报告:推进家校社协同育人研究
- 拒绝校园霸凌守护美好校园
- 不要慌太阳下山有月光二部合唱简谱
- 2025春新七年级道德与法治下册全册知识点
- Unit 9 Active learning 教学设计-2023-2024学年高中英语北师大版(2019)必修第三册
- 渔场基地建设实施方案
- 《食源性病原体》课件
- 《药品泡罩包装应用指南(征求意见稿)》
- Unit 6 Beautiful landscapes Integration 说课稿 -2024-2025学年译林版英语七年级下册001
评论
0/150
提交评论