Linux设备驱动程序课件(-62张).ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《Linux设备驱动程序课件(-62张).ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 设备 驱动程序 课件 62
- 资源描述:
-
1、Linux设备驱动设备驱动广州嵌入式软件公共技术支持中心2007年07月设备驱动概述设备驱动概述l操作系统是通过各种驱动程序来驾驭硬件设备,它为操作系统是通过各种驱动程序来驾驭硬件设备,它为用户屏蔽了各种各样的设备用户屏蔽了各种各样的设备,硬件设备的抽象。硬件设备的抽象。l设备驱动程序设备驱动程序:处理和管理硬件控制器的软件。处理和管理硬件控制器的软件。l设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动概述设备驱动概述l设备由两部分组成,一个是被称为控制器的电器部分,设备由两部分组成,一个是被称为控制器的电器部分,另一个是机械部分。另一个
2、是机械部分。l一组寄存器组被赋予到各个控制器。一组寄存器组被赋予到各个控制器。I/O端口包含端口包含4组寄组寄存器,即状态寄存器,控制寄存器,数据输入寄存器,存器,即状态寄存器,控制寄存器,数据输入寄存器,数据输出寄存器。数据输出寄存器。状态寄存器拥有可以被状态寄存器拥有可以被CPU读取的读取的(状态状态)位,用来位,用来 指示当前命令是否执行完毕,或者字节是否可以被指示当前命令是否执行完毕,或者字节是否可以被读出或写入,以及任何错误提示。读出或写入,以及任何错误提示。控制寄存器则用于启动一条命令(指令)或者改变控制寄存器则用于启动一条命令(指令)或者改变设备的设备的(工作工作)模式。模式。数
3、据输入寄存器用于获取输入的数据。数据输入寄存器用于获取输入的数据。数据输出寄存器则向数据输出寄存器则向CPU发送结果。发送结果。l处理器和设备之间的基本界面是控制和状态寄存器。处理器和设备之间的基本界面是控制和状态寄存器。设备驱动概述设备驱动概述l寄存器拥有在寄存器拥有在I/O空间明确定义的地址范围。空间明确定义的地址范围。l通常这些地址在启动时被分配。通常这些地址在启动时被分配。如果设备是静态加载的如果设备是静态加载的,各个设备的地址范围可能被预各个设备的地址范围可能被预分配。这意味内核包含了已存在设备的驱动分配。这意味内核包含了已存在设备的驱动 程序。通程序。通过运行过运行“cat/pro
4、c/ioports”命令检查其所使用的地命令检查其所使用的地址范围。第一列输出显示了端口的范围而第二列则是址范围。第一列输出显示了端口的范围而第二列则是拥用这些端口的设备。拥用这些端口的设备。设备驱动概述设备驱动概述l设备驱动的概念是非常抽象的并且处于一台计算设备驱动的概念是非常抽象的并且处于一台计算上所运行软件的最低层。上所运行软件的最低层。l由于直接到设备的硬件特性的限由于直接到设备的硬件特性的限 制。每个设备驱制。每个设备驱动都只管理一种单一类型的设备。动都只管理一种单一类型的设备。l如果一个应用如果一个应用 程序向设备提出(操作)要求。内程序向设备提出(操作)要求。内核会联系到对应的设
5、备驱动,设备驱动接着向特核会联系到对应的设备驱动,设备驱动接着向特定的设备发出命令。定的设备发出命令。l设备驱设备驱 动是一个函数集合:包含了许多调用入口,动是一个函数集合:包含了许多调用入口,类似于类似于open,close,read,write,ioctl,llseek 等。等。设备驱动概述设备驱动概述lLinuxLinux操作系统把设备操作系统把设备纳入文件系统的范畴纳入文件系统的范畴来管理。来管理。l文件操作是对设备操作的组织和抽象。设备操作则是文件操作是对设备操作的组织和抽象。设备操作则是对文件操作的最终实现。对文件操作的最终实现。l每个设备都对应一个文件名每个设备都对应一个文件名,
6、在内核中也就对应一个,在内核中也就对应一个索引节点。索引节点。l对文件操作的系统调用大都适用于设备文件。对文件操作的系统调用大都适用于设备文件。l从应用程序的角度看,设备文件逻辑上的空间是一个从应用程序的角度看,设备文件逻辑上的空间是一个线性空间(起始地址为线性空间(起始地址为0 0,每读取一个字节加,每读取一个字节加1 1)。从)。从这个逻辑空间到具体设备物理空间(如磁盘的磁道、这个逻辑空间到具体设备物理空间(如磁盘的磁道、扇区)的映射则是由内核提供,并被划分为扇区)的映射则是由内核提供,并被划分为文件操作文件操作和和设备驱动设备驱动两个层次。两个层次。设备驱动概述设备驱动概述lLinuxL
7、inux将设备分成两大类。将设备分成两大类。一类像键盘那样以字符(字节)为单位,逐个字符一类像键盘那样以字符(字节)为单位,逐个字符进行输入输出的设备,称为进行输入输出的设备,称为字符设备字符设备。一类是像磁盘那样以块或扇区为单位,成块进行输一类是像磁盘那样以块或扇区为单位,成块进行输入输出的设备,称为入输出的设备,称为块设备块设备。文件系统通常都建立在块设备上。文件系统通常都建立在块设备上。设备驱动概述设备驱动概述l文件操作和设备驱动是对一个具体的设备操作的不同层文件操作和设备驱动是对一个具体的设备操作的不同层次。从这种观点出发,从概念上可以把一个系统划分为次。从这种观点出发,从概念上可以把
8、一个系统划分为应用、文件系统和设备驱动三个层次。应用、文件系统和设备驱动三个层次。将请求加入请求队列 请求提交操作readsys_readfile-f_op-readdo_generic_file_read用户空间函数内核系统调用文件系统读操作通用文件系统读操作readsys_readfile-f_op-readdo_generic_file_read用户空间函数内核系统调用文件系统读操作submit_bhsubmit_bhadd_requstadd_requst设备驱动概述设备驱动概述设备驱动概述设备驱动概述l要使一项设备可以被应用程序访问,首先要在系统中要使一项设备可以被应用程序访问,首先
9、要在系统中建立一个代表此设备的设备文件,这是通过系统调用建立一个代表此设备的设备文件,这是通过系统调用mknode()mknode()实现的。此外,更重要的是在设备驱动层要实现的。此外,更重要的是在设备驱动层要有这种设备的驱动程序。有这种设备的驱动程序。设备驱动概述设备驱动概述l设备文件:设备文件:任何设备都被当作路径任何设备都被当作路径/dev 的设备文件处理,并通的设备文件处理,并通过这些设备文件提供访问硬件的方法。过这些设备文件提供访问硬件的方法。每个设备文件除了设备名外,还有类型、主设备号、每个设备文件除了设备名外,还有类型、主设备号、次设备号这三个属性。次设备号这三个属性。设备文件是
10、通过设备文件是通过mknodmknod系统调用创建的。其原型为:系统调用创建的。其原型为:mknod(const char mknod(const char*filename,int mode,dev_t filename,int mode,dev_t dev)dev)mknod/dev/led0 c 253 0 mknod/dev/led0 c 253 0 设备驱动概述设备驱动概述l主设备号和次设备号:主设备号和次设备号:主设备号标识设备对应的驱动程序。一般主设备号标识设备对应的驱动程序。一般“一个主一个主设备号对应一个驱动程序设备号对应一个驱动程序”次设备号用于确定设备文件所指的设备。次设
11、备号用于确定设备文件所指的设备。可通过可通过ls l“设备文件名设备文件名”命令查看设备的主次设命令查看设备的主次设备号,以及设备的类型。备号,以及设备的类型。设备驱动概述设备驱动概述l主设备号和次设备号的内部表达:主设备号和次设备号的内部表达:Dev_t类型用于保存设备号,称为设备编号。类型用于保存设备号,称为设备编号。/linux/types.h文件中定义。文件中定义。目前设备编号目前设备编号dev_t是一个是一个32位的整数,其中位的整数,其中12位位表示主设备号,表示主设备号,20位表示次设备号。位表示次设备号。通过设备编号获取主次设备号:通过设备编号获取主次设备号:MAJOR(dev
12、_t dev);MINOR(dev_t dev);通过主次设备号合成设备编号:通过主次设备号合成设备编号:MKDEV(int major,int minor);Dev_t格式以后可能会发生变化,但只要使用这些格式以后可能会发生变化,但只要使用这些宏,就可保证设备驱动程序的正确性。宏,就可保证设备驱动程序的正确性。一些重要的数据结构一些重要的数据结构l大部分驱动程序涉及三个重要的内核数据结构:大部分驱动程序涉及三个重要的内核数据结构:文件操作文件操作file_operations结构体结构体文件对象文件对象file结构体结构体索引节点索引节点inode结构体结构体一些重要的数据结构一些重要的数据
13、结构l文件操作结构体文件操作结构体file_operations结构体结构体file_operations在头文件在头文件 linux/fs.h中定义,中定义,用来存储驱动内核模块提供的用来存储驱动内核模块提供的对设备进行各种操作对设备进行各种操作的函数的指针的函数的指针。结构体的每个域都对应着驱动模块用来处理某个被结构体的每个域都对应着驱动模块用来处理某个被请求的事务的函数的地址。请求的事务的函数的地址。struct file_operations struct module*owner;loff_t(*llseek)(struct file*,loff_t,int);ssize_t(*re
14、ad)(struct file*,char _user*,size_t,loff_t*);ssize_t(*write)(struct file*,const char _user*,size_t,loff_t*);。一些重要的数据结构一些重要的数据结构lfile_operations重要的成员重要的成员Struct module*owner,指向拥有该结构体的模,指向拥有该结构体的模块的指针。块的指针。方法方法llseek用来修改文件的当前读写位置,把新位用来修改文件的当前读写位置,把新位置作为返回值返回。置作为返回值返回。方法方法read用来从设备中读取数据。非负返回值表示用来从设备中读取
15、数据。非负返回值表示成功读取的直接数。成功读取的直接数。方法方法write向设备发送数据。向设备发送数据。方法方法ioctl提供一种执行设备特定命令的方法。提供一种执行设备特定命令的方法。一些重要的数据结构一些重要的数据结构lfile_operations重要的成员重要的成员驱动内核模块是不需要实现每个函数的。相对应的驱动内核模块是不需要实现每个函数的。相对应的file_operations的项就为的项就为 NULL。Gcc的语法扩展,使得可以定义该结构体:的语法扩展,使得可以定义该结构体:struct file_operations fops=read:device_read,write:d
16、evice_write,open:device_open,release:device_release;这种语法清晰,没有显示声明的结构体成员都被这种语法清晰,没有显示声明的结构体成员都被gcc初始化为初始化为NULL。一些重要的数据结构一些重要的数据结构lfile_operations重要的成员重要的成员标准标准C的标记化结构体的初始化方法:的标记化结构体的初始化方法:struct file_operations fops=.read=device_read,.write=device_write,.open=device_open,.release=device_release;推荐使用该
17、方法,提高移植性,方法允许对结构体成员进行重推荐使用该方法,提高移植性,方法允许对结构体成员进行重新排列。新排列。没有显示声明的结构体成员同样都被没有显示声明的结构体成员同样都被gcc初始化为初始化为NULL。指向结构体指向结构体file_operations的指针通常命名为的指针通常命名为fops。一些重要的数据结构一些重要的数据结构l文件对象文件对象file结构体结构体文件对象文件对象file代表着一个打开的文件代表着一个打开的文件。进程通过文进程通过文件描述符件描述符fdfd与已打开文件的与已打开文件的filefile结构相联系。进程结构相联系。进程通过它对文件的线性逻辑空间进行操作。例
18、如:通过它对文件的线性逻辑空间进行操作。例如:file-f_op-read();file-f_op-read();Struct file Struct file 在在中定义。中定义。指向结构体指向结构体struct file的指针通常命名为的指针通常命名为filp,或者,或者file。建议使用文件指针。建议使用文件指针filp。一些重要的数据结构一些重要的数据结构l文件对象文件对象file结构体的成员结构体的成员Struct file_operations*f_op;与文件相关的操作结构体指针。与文件相关的操作与文件相关的操作结构体指针。与文件相关的操作是在打开文件的时候确定下来的,也就是确定
19、该指是在打开文件的时候确定下来的,也就是确定该指针的值。可在需要的时候,改变指针所指向的文件针的值。可在需要的时候,改变指针所指向的文件操作结构体。用操作结构体。用C语言实现面向对象编程的方法重语言实现面向对象编程的方法重载。载。其他成员可先忽略,后面具体实例分析。因为设备其他成员可先忽略,后面具体实例分析。因为设备驱动模块并不自己直接填充结构体驱动模块并不自己直接填充结构体 file,只是使用,只是使用file中的数据。中的数据。一些重要的数据结构一些重要的数据结构l索引节点索引节点inode结构结构文件打开,在内存建立副本后,由文件打开,在内存建立副本后,由唯一的索引节点唯一的索引节点in
20、ode描述。描述。与与file结构不同。结构不同。file结构是进程使用的结构,进程每打开一个文结构是进程使用的结构,进程每打开一个文件,就建立一个件,就建立一个file结构。不同的进程打开同一结构。不同的进程打开同一个文件,建立不同的个文件,建立不同的file结构。结构。Inode结构是内核使用的结构,文件在内存建立结构是内核使用的结构,文件在内存建立副本,就建立一个副本,就建立一个inode结构来描述。结构来描述。一个文件一个文件在内存里面只有一个在内存里面只有一个inode结构对应。结构对应。一些重要的数据结构一些重要的数据结构l索引节点索引节点inode结构结构Inode结构包含大量描
21、述文件信息的成员变量。结构包含大量描述文件信息的成员变量。但是对于描述设备文件的但是对于描述设备文件的inode,跟设备驱动有关,跟设备驱动有关的成员只有两个。的成员只有两个。Dev_t i_rdev;包含真正的设备编号。包含真正的设备编号。Struct cdev*i_cdev;指向指向cdev结构体的指针。结构体的指针。cdev是表示字符设备的内核数据结构。是表示字符设备的内核数据结构。从从inode中获得主设备号和次设备号的宏:中获得主设备号和次设备号的宏:Unsigned int iminor(struct inode*inode);Unsigned int imajor(struct
22、inode*inode);驱动程序中的内存分配驱动程序中的内存分配l在在Linux内核模式下,不能使用用户态的内核模式下,不能使用用户态的malloc()和和free()函数申请和释放内存。函数申请和释放内存。l内核编程最常用的内存申请和释放函数为内核编程最常用的内存申请和释放函数为kmalloc()和和kfree(),其原型为:,其原型为:include/linux/kernel.hvoid void*kmalloc(unsigned int len,int priority);kmalloc(unsigned int len,int priority);void kfree(void vo
23、id kfree(void*_ptr);_ptr);priority参数参数:通常设置为通常设置为GFP_KERNEL,可能会引起睡眠,可能会引起睡眠.如果在中断服务程序里申请内存则要用如果在中断服务程序里申请内存则要用GFP_ATOMIC参数,参数,在中断中是不允许睡眠的。在中断中是不允许睡眠的。初始化和卸载函数初始化和卸载函数l驱动程序是内核的一部分,因此我们需要给其添驱动程序是内核的一部分,因此我们需要给其添加模块初始化函数,该函数用来完成对所控设备加模块初始化函数,该函数用来完成对所控设备的初始化工作,并调用的初始化工作,并调用register_chrdev()函数函数注册字符设备注册
24、字符设备.int register_chrdev(unsigned int major,const char*name,struct file_operations*fops);major 是给定的主设备号。为0代表什么?name 是驱动的名字(将出现在/proc/devices),fops 是设备驱动的file_operations 结构。register_chrdev 将给设备分配 0-255 的次设备号,并且为每一个建立一个缺省的 cdev 结构。l与模块初始化函数对应的就是模块卸载函数,需与模块初始化函数对应的就是模块卸载函数,需要调用要调用register_chrdev()的的反函数
25、反函数设备操作函数集的定义设备操作函数集的定义lfile_operations结构体,驱动程序只是利用其中结构体,驱动程序只是利用其中的一部分。的一部分。l对于字符设备来说,要提供的主要入口有:对于字符设备来说,要提供的主要入口有:open()、release()、read()、write()、ioctl()等。等。设备操作函数集的定义设备操作函数集的定义lopen()函数函数对设备特殊文件进行对设备特殊文件进行open()系统调用时,将调用驱动系统调用时,将调用驱动程序的程序的open()函数:函数:int(int(*open)(struct inode open)(struct inode
展开阅读全文