驱动学习之字符设备驱动的原理

简介:

1:嵌入式系统的整体工作原理

  应用层->API->设备驱动->硬件

  比如,在应用层,现在使用read函数去读取一个设备文件,这个read函数是属于应用层的,它不能直接读取设备文件,而是通过内核层的函数(其实就是和file_operations结构体中read这个函数指针相绑定的函数,这个函数才是真正操作硬件的函数)来实现读取文件,


2:file_operations结构体

(1)这个结构体里面存放的是一个驱动里面操作文件的各种函数指针,比如,现有一个驱动,它可以打开一个文件,那么这个驱动对应的fire_operation结构体里面的open函数指针就和这个驱动的打开文件的操作函数相绑定,当调用这个驱动去打开文件时,就会到这个驱动的fire_operation结构体中去找到open函数指针,进而找到驱动代码中对应的打开文件的函数。

(2)每个驱动都有一个fire_operations结构体,用来管理这个驱动的操作函数。

(3)设备驱动相内核注册时提供该结构体类型的变量。

2:注册字符驱动设备

(1):为什么要注册:因为注册后内核才能找到这个驱动

(2):谁去负责注册:驱动自己去注册

(3)向谁注册:向内核注册

(4)注册函数从哪来:注册函数是register_chrdev,有内核提供

(5)注册后的结果:注册后内核就能记录这个驱动的file_operations,将来要用到这个驱动的时候就可以通过这个驱动的file_operation来找到相应的驱动。

3:register_chrdev(驱动注册函数)

1
2
3
4
static  inline  int  register_chrdev(unsigned  int  major, const  char  *name, const  struct  file_operations *fops)
{
return  __register_chrdev(major, 0, 256 , name, fops);
}


(1)路径为/include/linux/fs.h,所以以后使用的时候需要添加#include<linux/fd.h>

(2)作用:驱动向内核注册自己的file_operations

(3)返回值:注册成功返回0,注册失败返回一个负整数

(4)参数

  unsigned int major:主设备号,主设备号是内核或者自己给设备(硬件)定义的编号,将来要操作这个硬件的时候只要去调用这个编号(范围是0-255)就行。这设备号可以有内核自动分配,也可以由程序员自己指定,假如自己指定的编号比如是38已经被占用了,那么file_operations就会返回一个负整数,注册失败。

  const char *name:当前设备驱动的名字,便于程序员查看这个驱动的具体作用。

  const struct file_operations *fops:把这个驱动的file_operations结构体变量传给内核,用于注册这个驱动。

(5)static:为了防止和其他文件的函数重名

(6)inline:这个函数是定义在头文件中的,在预处理的时候头文件内容是在.c文件中原地展开的,所以当有多个.c文件调用这个头文件中时就会提示重复定义的错误。另一个原因是,这个函数的内容很短,使用inline就可以减少函数调用的开销,提高函数调用的速度


4:内核如何管理字符设备驱动

(1)内核张有一个数组用来存储注册的字符设备驱动

(2)register_chrdev内部将我们要注册的驱动信息(主要是)存储在书中中相应的位置中

(3)使用cat /proc/devices去查看当前系统中已经注册的设备

5:proc文件系统

(1)/proc 文件系统是一种内核和内核模块用来向进程(process) 发送信息的机制(所以叫做/proc)。这个伪文件系统让你可以和内核内部数据结构进行交互,获取 有关进程的有用信息,在运行中(on the fly) 改变设置(通过改变内核参数)。 与其他文件系统不同,/proc 存在于内存之中而不是硬盘上。如果你察看文件/proc/mounts (和mount 命令一样列出所有已经加载的文件系统),你会看到其中 一行是这样的:

grep proc /proc/mounts

/proc /proc proc rw 0 0

/proc 由内核控制,没有承载/proc 的设备。因为/proc 主要存放由内核控制的状态信息,所以大部分这些信息的逻辑位置位于内核控制的内存。对/proc 进行一次'ls -l' 可以看到大部分文件都是0 字节大的;不过察看这些文件的时候,确实可以看到一些信息。这怎么可能?这是因为/proc 文件系统和其他常规的文件系统一样把自己注册到虚拟文件系统层(VFS) 了。然而,直到当VFS 调用它,请求文件、目录的 i-node 的时候,/proc 文件系统才根据内核中的信息建立相应的文件和目录。

(2)加载proc 文件系统

如果系统中还没有加载proc 文件系统,可以通过如下命令加载proc 文件系统:

mount -t proc proc /proc

上述命令将成功加载你的proc 文件系统。更多细节请阅读mount 命令的man page。

(3)察看/proc 的文件

/proc 的文件可以用于访问有关内核的状态、计算机的属性、正在运行的进程的状态等信息。大部分/proc 中的文件和目录提供系统物理环境最新的信息。尽管/proc 中的文件是虚拟的,但它们仍可以使用任何文件编辑器或像'more', 'less'或'cat'这样的程序来查看。当编辑程序试图打开一个虚拟文件时,这个文件就通过内核中的信息被凭空地(on the fly) 创建了。这是一些我从我的系统中得到的一些有趣结果

参考

http://www.2cto.com/os/201202/119552.html



本文转自 菜鸟养成记 51CTO博客,原文链接:http://blog.51cto.com/11674570/1872407
相关文章
|
Linux
Linux驱动开发(使用I2C总线设备驱动模型编写AT24C02驱动程序)
Linux驱动开发(使用I2C总线设备驱动模型编写AT24C02驱动程序)
155 0
|
4月前
|
Linux
内核实验(五):传统简单字符设备驱动
本文通过一个简单的字符设备驱动程序实验,演示了如何在Linux内核中编写、编译和测试驱动代码,并使用Qemu虚拟机和NFS环境进行部署和验证,同时检验了NFS环境对于提高开发效率的作用。
48 0
内核实验(五):传统简单字符设备驱动
|
7月前
|
Ubuntu 网络协议 Linux
【操作系统】探究驱动奥秘:驱动程序设计的解密与实战
【操作系统】探究驱动奥秘:驱动程序设计的解密与实战
73 0
|
7月前
|
Unix Linux 编译器
Linux驱动设计(一):驱动是什么?
Linux驱动设计(一):驱动是什么?
57 0
|
7月前
|
Linux API
Linux驱动的软件架构(三):主机驱动与外设驱动分离的设计思想
Linux驱动的软件架构(三):主机驱动与外设驱动分离的设计思想
109 0
|
Linux
Linux驱动入门(5)LED驱动---驱动分层和分离,平台总线模型
Linux驱动入门(5)LED驱动---驱动分层和分离,平台总线模型
128 0
|
缓存 Linux API
Linux驱动分析之Uart驱动架构
UART设备驱动可以使用tty驱动的框架来实现,但是因为串口之间有共性,所以Linux在tty接口上封装了一层(serial core)。后面我们再拿一篇文章来解释tty驱动,tty其实就是各种终端设备,串口其实也是终端设备。
Linux驱动分析之Uart驱动架构
|
Linux
一文搞懂 USB 设备端驱动框架
hello 大家好,今天带领大家学习一下USB 设备端驱动 内核版本:4.4.94
1179 0
|
Linux API
Linux驱动分析之SPI驱动架构
Linux驱动分析之SPI驱动架构
【驱动详解】如何理解驱动程序
【驱动详解】如何理解驱动程序
360 0
【驱动详解】如何理解驱动程序