在上文说usb_init函数,却给我们留下了很多岔路口。这次就来好好聊聊关于总线设备驱动模型。这节只讲理论,不讲其中的函数方法,关于函数方法使用参考其他资料。

总线、设备、驱动对应内核结构体分别为bus_type、device、device_driver。

我们会发现,struct bus_type 结构中有成员struct kset drivers 和struct kset devices,同时struct device结构中有两个成员struct bus_type和structdevice_driver,struct device_driver结构中有两个成员struct bus_type和struct klist。先不说什么是klist、kset,光从成员的名字看,它们就是一个完美的三角关系。

我们可以知道,struct device中的bus表示这个设备连到哪个总线上,driver表示这个设备的驱动是什么,struct device_driver中的bus表示这个驱动属于哪个总线,klist_devices表示这个驱动都支持哪些设备,因为这里device是复数,又是list,因为一个驱动可以支持多个设备,而一个设备只能绑定一个驱动。当然,struct bus_type中的drivers和devices分别表示了这个总线拥有哪些设备和哪些驱动。

我们还需要看看什么是klist、kset。还有上面device和driver结构里出现的kobject结构是什么?实际上,kobject和kset都是linux设备模型中最基本的元素,总线、设备、驱动是西瓜,kobjcet、klist是种瓜的人,没有幕后种瓜人的汗水不会有清爽解渴的西瓜,我们不能光知道西瓜的的甜,还要知道种瓜人的辛苦。kobject和kset存在的意义在于把总线、设备和驱动这样的对象连接到设备模型上。

一般来说应该这么理解,整个linux的设备模型是一个OO的体系结构,总线、设备和驱动都是其中鲜活存在的对象,kobject是它们的基类,所实现的只是一些公共的接口,kset是同种类型kobject对象的集合,也可以说是对象的容器。只是因为C里不可能会有C++里类的class继承、组合等的概念,只有通过kobject嵌入到对象结构里来实现。这样,内核使用kobject将各个对象连接起来组成了一个分层的结构体系,就好像通过马列主义将我们13亿人也连接成了一个分层的社会体系一样。kobject结构里包含了parent成员,指向了另一个kobject结构,也就是这个分层结构的上一层结点。而kset是通过链表来实现的,这样就可以明白,struct bus_type 结构中的成员drivers 和devices表示了一条总线拥有两条链表,一条是设备链表,一条是驱动链表。我们知道了总线对应的数据结构,就可以找到这条总线关联了多少设备,又有哪些驱动来支持这类设备。klist其实它就包含了一个链表和一个自旋锁,我们暂且把它看成链表也无妨。

那么总线、设备和驱动它们只见是如何和谐共处?还是先说说总线中的那两条链表是怎么形成的吧。每次出现一个设备就要向总线汇报,或者说注册,每次出现一个驱动,也要向总线汇报,或者说注册。比如系统初始化的时候,会扫描连接了哪些设备,并为每一个设备建立起一个struct device的变量,每一次有一个驱动程序,就要准备一个struct device_driver结构的变量。把这些变量统统加入相应的链表,device 插入devices 链表,driver插入drivers链表。这样通过总线就能找到每一个设备,每一个驱动。然而,假如计算机里只有设备却没有对应的驱动,那么设备无法工作。反过来,倘若只有驱动却没有设备,驱动也起不了任何作用。在他们遇见彼此之前,双方都如同路埂的野草,一个飘啊飘,一个摇啊摇,谁也不知道未来在哪里,只能在生命的风里飘摇。于是总线上的两张表里就慢慢的就挂上了那许多孤单的灵魂。devices开始多了,drivers开始多了,他们像是两个来自世界,devices们彼此取暖,drivers们一起狂欢,但他们有一点是相同的,都只是在等待属于自己的那个另一半。

现在,总线上的两条链表已经有了,这个三角关系三个边已经有了两个,剩下的那个那?链表里的device和driver又是如何联系那?先有device还是先有driver?在linux2.6内核之后版本中引入了热插拔概念,device可以在计算机启动以后在插入或者拔出计算机了。因此,很难再说是先有device还是先有driver了。device可以在任何时刻出现,而driver 也可以在任何时刻被加载,所以,出现的情况就是,每当一个struct device诞生,它就会去bus的drivers链表中寻找自己的另一半,反之,每当一个一个struct device_driver诞生,它就去bus的devices链表中寻找它的那些设备。如果找到了合适,调用device_bind_driver绑定好。

usb驱动开发4之总线设备驱动模型的更多相关文章

  1. usb驱动开发5之总线设备与接口

    Linux设备模型中的总线落实在USB子系统里就是usb_bus_type,它在usb_init的函数bus_register(&usb_bus_type)里注册.usb_bus_type定义 ...

  2. (57)Linux驱动开发之三Linux字符设备驱动

    1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是: ...

  3. arm-linux字符设备驱动开发之---简单字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...

  4. Linux设备驱动开发基础--阻塞型设备驱动

    1. 当一个设备无法立刻满足用户的读写请求时(例如调用read时,设备没有数据提供),驱动程序应当(缺省的)阻塞进程,使它进入等待(睡眠)状态,知道请求可以得到满足. 2. Linux内核等待队列:在 ...

  5. linux驱动开发( 五) 字符设备驱动框架的填充file_operations结构体中的操作函数(read write llseek unlocked_ioctl)

    例子就直接使用宋宝华的书上例子. /* * a simple char device driver: globalmem without mutex * * Copyright (C) 2014 Ba ...

  6. 芯灵思SinlinxA33开发板 Linux平台总线设备驱动

    1.什么是platform(平台)总线? 相对于USB.PCI.I2C.SPI等物理总线来说,platform总线是一种虚拟.抽象出来的总线,实际中并不存在这样的总线. 那为什么需要platform总 ...

  7. Linux中总线设备驱动模型及平台设备驱动实例

    本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...

  8. Linux的总线设备驱动模型

    裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同: 而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照"模板"来写,写出来的驱动就比较统一. ...

  9. Linux学习 : 总线-设备-驱动模型

    platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...

随机推荐

  1. 【读书笔记】iOS-NSPredicate

    一,Cocoa提供了一个名为NSPredicate的类,它用于指定过滤器的条件.可以创建NSPredicate对象,通过该对象准确地描述所需的条件,对每个对象通过谓词进行筛选,判断它们是否与条件相匹配 ...

  2. iOS 秒数转换成时间,时,分,秒

    //转换成时分秒 - (NSString *)timeFormatted:(int)totalSeconds{ int seconds = totalSeconds % 60;     int min ...

  3. Java基础--常用正则匹配符号(必背,必须背,死都要背)

    1.字母:匹配单个字母 (1)A:表示匹配字母A: (2)\\:匹配转义字符“\”: (3)\t:匹配转义字符“\t”: (4)\n:匹配转义字符“\n”: 2.一组字符:任意匹配里面的一个单个字符: ...

  4. 转 自定义View之onMeasure()

    可以说重载onMeasure(),onLayout(),onDraw()三个函数构建了自定义View的外观形象.再加上onTouchEvent()等重载视图的行为,可以构建任何我们需要的可感知到的自定 ...

  5. 一步步学敏捷开发:6、Scrum的3种工件

    Scrum的3种工件包括:Product Blacklog.Sprint Backlog.完成标准. 1.产品待办事项列表(Product Backlog) 产品Blacklog是Scrum中的核心工 ...

  6. 数据库update的异常一例

    调查一列bug,偶然发现了update的一个特性:update t set a=a+1 where id=4; 这样一条简单的语句,也会发生让人意外的事情: 如果 a 的初始值为null时,无论你up ...

  7. cocos2d-x之action初试

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...

  8. 虚拟机Linux----Ubuntu1204----退格键方向键无法使用

    修改 /etc/vim/vimrc.tiny,如下: set compatible #修改为 set nocompatible #控制方向键set backspace=2 #控制退格键

  9. 第一次wubi安装Ubuntu的经历及所走的弯路

    #安装目标:利用xp存储剩余空间安装ubuntu, 形成双系统. 整理出待安装的磁盘空间 #需要无损磁盘工具, 用了"傲梅分区助手", 偷懒没有选其他高大上的英文软件. XP下硬盘 ...

  10. tika提取pdf信息异常

    org.apache.tika.sax.WriteOutContentHandler$WriteLimitReachedException: Your document contained more ...