欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    字符设备驱动程序.ppt

    • 资源ID:6268060       资源大小:1.36MB        全文页数:44页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    字符设备驱动程序.ppt

    上章回顾,Linux设备驱动的简介,以及分类字符设备块设备网络接口模块的应用如何编写模块模块相关的宏模块和应用程序的区别编译和装载内核模块,字符设备驱动程序,第2章,预习检查,什么是主设备号和次设备号?字符设备驱动程序的基本成员函数有哪些?,本章目标,掌握字符设备驱动程序的基本结构和开发方法 掌握用户空间调用设备驱动程序的方法,本章结构,字符设备驱动基本结构,字符设备驱动程序,用户空间调用设备驱动程序,添加驱动程序到内核,内核配置和编译方法,添加驱动程序到内核中,主要概念和结构体,实例,字符驱动的主要组成,2-1 字符设备驱动程序基本结构,字符设备开发的基本步骤确定主设备号和次设备号实现字符驱动程序实现file_operations结构体实现初始化函数,注册字符设备实现销毁函数,释放字符设备创建设备文件节点,2-1 字符设备驱动程序基本结构,什么是主设备号/次设备号主设备号是内核识别一个设备的标识。整数(占12bits),范围从0到4095,通常使用1到255次设备号由内核使用,用于正确确定设备文件所指的设备。整数(占20bits),范围从0到1048575,一般使用0到255,2-1 字符设备驱动程序基本结构,设备编号的内部表达dev_t类型(32位):用来保存设备编号(包括主设备号(12位)和次设备号(20位)从dev_t获得主设备号和次设备号:MAJOR(dev_t);MINOR(dev_t);将主设备号和次设备号转换成dev_t类型:MKDEV(int major,int minor);,2-1 字符设备驱动程序基本结构,分配主设备号手工分配主设备号:找一个内核没有使用的主设备号来使用。,#include int register_chrdev_region(dev_t first,unsigned int count,char*name);,要分配的设备编号范围的起始值,次设备号经常为0,所请求的连续设备编号的个数,和该编号范围关联的设备名称,2-1 字符设备驱动程序基本结构,动态分配主设备号:,#include int alloc_chrdev_resion(dev_t*dev,unsigned int firstminor,unsigned int count,char*name);,输出的设备号,要使用的被请求的第一个次设备号,2-1 字符设备驱动程序基本结构,释放设备号,void unregister_chrdev_region(dev_t first,unsigned int count);,通常在模块的清除函数中调用。,2-1 字符设备驱动程序基本结构,实现字符驱动程序cdev 结构体,struct cdev struct kobject kobj;/*内嵌的kobject 对象*/struct module*owner;/*所属模块*/struct file_operations*ops;/*文件操作结构体*/struct list_head list;dev_t dev;/*设备号*/unsigned int count;,2-1 字符设备驱动程序基本结构,操作cdev的函数,void cdev_init(struct cdev*,struc t file_operations*);struct cdev*cdev_alloc(void);int cdev_add(st ruct cdev*,dev_t,unsigned);void cdev_del(struct cdev*);,用于初始化cdev的成员,并建立cdev和file_operations之间的连接,分别向系统删除一个cdev,完成字符设备的注销,通常在模块的卸载函数中调用,分别向系统添加一个cdev,完成字符设备的注册,通常在模块加载函数中调用,函数用于动态申请一个cdev 内存,2-1 字符设备驱动程序基本结构,file_operations 结构体字符驱动和内核的接口:在include/linux/fs.h定义字符驱动只要实现一个file_operations结构体并注册到内核中,内核就有了操作此设备的能力。,2-1 字符设备驱动程序基本结构,file_operations的主要成员:struct module*owner:指向模块自身open:打开设备release:关闭设备read:从设备上读数据write:向设备上写数据ioctl:I/O控制函数llseek:定位读写指针mmap:映射设备空间到进程的地址空间,2-1 字符设备驱动程序基本结构,file 结构体 file结构:file_operations结构相关的一个结构体。描述一个正在打开的设备文件。成员:loff_t f_pos:当前读/写位置unsigned int f_flags标识文件打开时,是否可读或可写O_RDONLYO_NONBLOCKO_SYNCstruct file_operations*f_op文件相关的操作,指向所实现的struct file_operations void*private_data:私有数据指针。驱动程序可以将这个字段用于任何目的或者忽略这个字段。,2-1 字符设备驱动程序基本结构,inode 结构体内核用inode结构在内部表示文件Inode与file的区别file表示打开的文件描述符多个表示打开的文件描述符的file结构,可以指向单个inode结构。,2-1 字符设备驱动程序基本结构,Inode结构中的两个主要字段:dev_t i_rdev;对表示设备文件的inode结构,该字段包含了真正的设备编号。struct cdev*i_cdev;struct cdev是表示字符设备的内核的内部结构。当inode指向一个字符设备文件时,该字段包含了指向struct cdev结构的指针从一个inode中获得主设备号和次设备号:,unsigned int iminor(struct inode*inode);unsigned int imajor(struct inode*inode);,2-1 字符设备驱动程序基本结构,注册设备,在模块或驱动初始化时调用Linux-2.4 及之前Linux-2.6,int register_chrdev(unsigned int major,const char*name,struct file_operations*fops),如何操作字符设备的接口,void cdev_init(struct cdev*,struc t file_operations*);int cdev_add(st ruct cdev*,dev_t,unsigned);,2-1 字符设备驱动程序基本结构,注销设备:在模块卸载时调用Linux-2.4及之前Linux-2.6,int unregister_chrdev(unsigned int major,const char*name);,void cdev_del(struct cdev*);,2-1 字符设备驱动程序基本结构,/设备驱动模块加载函数static int _init xxx_init(void).cdev_init(/注册设备.,2-1 字符设备驱动程序基本结构,/*设备驱动模块卸载函数*/static void _exit xxx_exit(void)unregister_chrdev_region(xxx_dev_no,1);/释放占用的设备号 cdev_del(/注销设备.,2-1 字符设备驱动程序基本结构,打开模块使用计数加1识别次设备号硬件操作:检查设备相关错误(诸如设备未就绪或类似的硬件问题);如果设备是首次打开,则对其初始化;如果有中断操作,申请中断处理程序;,int open(struct inode*inode,struct file*filp);,2-1 字符设备驱动程序基本结构,关闭 模块使用计数减1释放由open分配的,保存在filpprivate_data里的所有内容。硬件操作:如果申请了中断,则释放中断处理程序。在最后一次关闭操作时关闭设备。,int release(struct inode*inode,struct file*filp);,2-1 字符设备驱动程序基本结构,read/write,ssize_t read(struct file*filp,char _user*buff,size_t count,loff_t*offp);ssize_t write(struct file*filp,const char _user*buff,size_t count,loff_t*offp);,指向用户空间的缓冲区,这个缓冲区或者保存将写入的数据,或者是一个存放新读入数据的空缓冲区。,用户在文件中存取操作的位置,2-1 字符设备驱动程序基本结构,用户空间和内核空间之间的数据拷贝过程,不能简单的用指针操作或者memcpy来进行数据拷贝用户空间的数据是可以被换出的,会产生一个页面失效异常。用户空间的地址无法在内核空间中使用。用户空间和内核空间之间进行数据拷贝的函数:如果要复制的内存是简单类型,如char、int、long 等,put_user()和get_user(),unsigned long copy_from_user(void*to,const void _user*from,unsigned long count);unsigned long copy_to_user(void _user*to,const void*from,unsigned long count);,2-1 字符设备驱动程序基本结构,读设备模板ssize_t xxx_read(struct file*filp,char _user*buf,size_t count,loff_t*f_pos).copy_to_user(buf,.,.);.写设备模板 ssize_t xxx_write(struct file*fil p,const char _user*buf,size_t count,loff_t*f_pos).copy_from_user(.,buf,.);.,2-1 字符设备驱动程序基本结构,ioctl函数为设备驱动程序执行“命令”提供了一个特有的入口点用来设置或者读取设备的属性信息。,int ioctl(struct inode*inode,struct file*filp,unsigned int cmd,unsigned long arg);,事先定义的IO控制命令 代码,arg为对应于cmd命令的参数,2-1 字符设备驱动程序基本结构,cmd 参数的定义不推荐用0 x1,0 x2,0 x3之类的值Linux对ioctl()的cmd参数有特殊的定义构造命令编号的宏:_IO(type,nr)用于构造无参数的命令编号;_IOR(type,nr,datatype)用于构造从驱动程序中读取数据的命令编号;_IOW(type,nr,datatype)用于写入数据的命令;_IOWR(type,nr,datatype)用于双向传输。type和number位字段通过参数传入,而size位字段通过对datatype参数取sizeof获得。,2-1 字符设备驱动程序基本结构,Ioctl函数模板int xxx_ioctl(struct inode*inode,struct f ile*filp,unsigned int cmd,unsigned long arg).switch(cmd)case XXX_CMD1:.break;case XXX_CMD2:.break;default:/*不能支持的命令*/return-ENOTTY;return 0;,阶段总结,本节介绍了字符设备驱动结构,2-2 添加驱动程序到内核,配置内核编译内核添加驱动程序到内核中,2-2 添加驱动程序到内核,配置内核配置命令包括:make config make menuconfig make xconfig make gconfig 可通过“上”、“下”、“左”、“右”键移动菜单,选择某项按“Y”,取消选择按“N”,如果选择某项编译为模块按“M”,进入子菜单按“Enter”,返回上一级菜单按“Esc”使用make config、make menuconfig等命令后,会生成一个.config配置文件(是隐身文件,通过ls a才能看到),2-2 添加驱动程序到内核,编译内核可用如下命令编译内核:make ARC=arm CROSS_COMPILE=arm-linux-zImage源代码根目录的Makefile中将ARCH和CROSS_COMPILE直接指定为arm和arm-linux-,如:,这样就没有必要每次编译的时候都指定体系结构和交叉编译器了,只须使用下面命令就可以了:make zImage,ARCH?=armCROSS_COMPILE?=arm-linux-,2-2 添加驱动程序到内核,添加驱动程序到内核Linux 2.6内核的配置系统由以下3个部分组成。Makefile:分布在Linux内核源代码中的Makefite定义Linux内核的编译规则配置文件(Kconfig):给用户提供配置选择的功能。配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)配置用户界面(提供字符界面和图形界面)。这些配置工具都是使用脚本语言编写的,如Tcl/TK、Perl等。在Linux内核中增加程序需要完成以下3项工作。将编写的源代码复制到Linux内核源代码的相应目录。在目录的Kconfig文件中增加新源代码对应项目的编译配置选项。在目录的Makefile文件中增加对新源代码的编译条目。,2-2 添加驱动程序到内核,实例:在内核源代码drivers目录下为ARM体系结构新增test driver test driver的树形目录:步骤:1、拷贝test到drivers路径下2、为新增目录创建Kconfig和Makefile3、修改新增目录父目录的Kconfig和Makefile,以便新增的Kconfig和Makefile能够被引用4、在arch/arm/Kconfig里增加source“drivers/test/Kconfig”,2-2 添加驱动程序到内核,步骤:1、拷贝test到drivers路径下 cp fr test linux_kernel_path/drivers2、为新增目录创建Kconfig和Makefile,2-2 添加驱动程序到内核,修改新增目录的父目录的Kconfig和Makefile在drivers/Kconig中加入:source drivers/test/Kconfig“在drivers/Makefile中加入:obj-$(CONFIG_TEST)+=test/在arch/arm/Kconfig里加入:source“drivers/test/Kconfig”增加了Kconfig和Makefile文件之后的新的test树型目录如下所示:,阶段总结,配置和编译Linux内核的方法如何将驱动程序加入到内核中-Makefile&Kconfig,2-3 用户空间调用设备驱动程序,创建设备节点$mknod/dev/node_name c major minor示例代码,int main(void)int dev_fd;char read_buf10;dev_fd=open(/dev/node_name,O_RDWR|O_NONBLOCK);if(dev_fd=-1)printf(Cannt open file/dev/node_name n);exit(1);read(dev_fd,read_buf,5);ioctl(dev_fd,XXX_IOCTL_CMD,0);close(dev_fd);return 0;,2-3 用户空间调用设备驱动程序,编写Makefile,KERNELDIR?=/your_kernel_path/includeall:main main:main.carm-linux-gcc-I$(KERNELDIR)-o$clean:rm main,阶段总结,手动创建设备节点方法用户层如何调用驱动程序编写用户程序的Makefile,本章总结,字符设备驱动主要结构和开发方法,如何配置、编译内核,以及如何把驱动程序添加到内核,如何在用户空间调用驱动,字符设备驱动基本结构,字符设备驱动程序,用户空间调用设备驱动程序,添加驱动程序到内核,内核配置和编译方法,添加驱动程序到内核中,主要概念和结构体,实例,字符驱动的主要组成,实验,任务一、蜂鸣器驱动程序编写与测试,

    注意事项

    本文(字符设备驱动程序.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开