转自:http://blog.csdn.net/dreaming_my_dreams/article/details/8272586

应用层和驱动的衔接,一直是一个老大难问题,若弄不清楚,总觉得驱动写起来似是而非的。下面就说说我对他们的理解,还有就是如何实现一个驱动支持多个上设备的问题。

最主要涉及两个机制:inode和file。

在驱动中:

(1)、我们先找到一个设备号devno,可以动态申请,也可以静态设定,假设静态设定为major,minor,通过宏MKDEV(major,minor)来生成devno

(2)、构建对设备的操作函数file_opreation结构体,里面包含了的设备的操作:open、read、write、release、ioctl等

(3)、构建cdev结构体,里面填充两个主要成员dev(设备号)、file_operation(对设备的操作)

(4)、把cdev添加的cdev链表中:cdev_init、cdev_add

应用程序中:

fd=open("/dev/hello",O_RDWR)来打开设备文件,此设备节点对应有一个设备号,这是我们识别驱动和设备的桥梁。

打开 /dev/hello时,根据设备号,在cdev链表中找到cdev这个结构体,cdev里面包含了file_operation结构体,有设备的各种操作,打开时就调用里面的.open 函数。在这里要完成几件事:

(1)inode节点 每一个文件都对应有一个inode节点,inode结构体里.i_fop由cdev的file_operation填充,i_dev由cdev的设备号填充

(2)file结构体中的file_operation也同样由cdev中对应项填充,还有一项fd,对应于打开文件的文件描述符,fd和file一一对应,文件每打开一次,就有一个file结构体。所以file里面的.private就很重要,下面会说到。

还有一个问题,那就是多个相同的设备,会公用同一个驱动,所以要把每一个设备的私有数据封装起来,构成一个私有数据结构体。对设备的每一次读写,都通过操作设备的私有数据结构体中的资源来完成。也就是说,驱动在加载的时候,会申请多个设备私有资源结构体,每个结构体中包含了设备的所有私有资源,虽然公用一个驱动,可是通过设备号找到此设备号对应设备的私有资源,说的有点拗口。这可以通过file结构体的.private来指向。

例如封装私有数据的结构体为:

struct hello_device{

char buf[128]; //设备的私有资源,譬如buf

struct cdev cdev;//设备结构体,里面有devno和file_operation

……

};

前面应经提到inode中的i_cdev会指向cdev结构,所以可以由Container宏来得到hello_device的地址。

所以,在驱动的open函数中有两个参数,inode和file

int open(structc inode *inode,struct file *file){

struct hello_device   *p =container(inode->i_cdev,hello_struct,cdev)

file->private=p;

}

这样file中就包含了设备的私有数据。

驱动read函数中:

ssize_t read(fd,char __user *buf,count)

fd和file一一对应,每打开一次设备,虽然有不同的fd,但他们的file.private是一样的。

前面主要说了一个驱动如何可以支持多个设备的问题,以及应用层和驱动之间的联系。还有一个问题就是,如何处理过个进程访问同一个设备的问题。

最新文章

  1. Nginx反向代理部署指南
  2. C程序范例(2)——学生管理系统”链表“实现
  3. 使用 CSS3 绘制 Hello Kitty
  4. PackageManager使用
  5. Java集合系列:-----------03ArrayList源码分析
  6. 优化特性(Attribute)性能
  7. node crypto md5加密,并解决中文不相同的问题
  8. 【Linux】linux常用基本命令(转)
  9. js中获取样式的俩种方法 style.color和style['color'] 区别
  10. python 文件编码
  11. huffman编码——原理与实现
  12. SQL Profile 总结(一)
  13. java excel导出
  14. Oracle 子程序参数模式,IN,OUT,IN OUT
  15. react中需要用到【深度复制】的问题
  16. pax3 quick start guide
  17. 机器学习入门之使用numpy和matplotlib绘制图形
  18. MongoDB NoSQL 常用指令
  19. ajax返回数据定义为全局变量
  20. 为什么不能使用Executors.newFixedThreadPool和newCachedThreadPool

热门文章

  1. Scala实战高手****第1课:大数据时代的“黄金”语言Scala
  2. 网络采集软件核心技术剖析系列(6)---将任意博主的全部博文下载到SQLite数据库中并通过Webbrower显示(将之前的内容综合到一起)
  3. tengine + lua 实现流量拷贝
  4. fl2440 platform总线led字符设备驱动
  5. 奇怪也哉!做一个WebApp居然遇到了FF浏览器进不去某页的问题。
  6. window onload 与 img onload事件
  7. php开发第一课
  8. Gperftools中tcmalloc的简介和使用(转)
  9. jQuery控制form表单元素聚焦
  10. CentOS最常用命令