裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同;

而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照“模板”来写,写出来的驱动就比较统一。

一、 Linux采用总线设备驱动模型。主要包含总线、设备、驱动三个部分。

总线:最先注册,有几个重要的回调函数,例如match函数用于匹配device和driver。

设备:设备的物理信息,例如设备名、物理地址、中断号等;

驱动:设备的驱动程序和设备名等信息,例如初始化函数、波特率设置函数、启动停止函数、中断函数等。

现实中,很多设备都是接在总线上的,例如SPI Flash接在SPI总线上,EEPROM接在I2C总线上。

但也有很多芯片内部设备没有挂在总线上,例如UART、SPI控制器。为了统一使用Linux总线设备驱动模型,内核中定义了一个虚拟总线 platform_bus_type,将这些设备(叫做平台设备)注册到该虚拟总线上统一管理。

二、Linux驱动注册顺序(总线、设备、驱动三者关系)

1、注册总线 xxx_bus_type:

在系统初始化阶段,会首先向内核注册各种常用的总线类型,比如pci, usb, spi, i2c, platform等等。

有两个重要的链表挂在bus上,一个是设备device链表,一个是驱动driver链表。

它包含的最关键的函数:match()用于匹配device和driver。

//例子:
static int __init spi_init(void)
{
int status; printk("@@ spi_init :spi_bus_type\n");
buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);
if (!buf) {
status = -ENOMEM;
goto err0;
} status = bus_register(&spi_bus_type);
if (status < 0)
goto err1; status = class_register(&spi_master_class);
if (status < 0)
goto err2;
return 0; err2:
bus_unregister(&spi_bus_type);
err1:
kfree(buf);
buf = NULL;
err0:
return status;
}

2、注册设备:将系统设备注册进内核的对应总线上,大多是调用xxx_device_regisger注册。

(xxx_device_regisger:将自己加到xxx总线的device链表,然后使用总线bus匹配对应的driver )

3、注册驱动:将系统设备的driver注册进内核的对应总线上:大多是调用xxx_drvier_register()注册。

(xxx_drvier_register:将自己加到xxx总线的driver链表,然后使用总线bus匹配对应的device )

2和3很多是在同一个函数中注册的,所以一起举例:

例子1:
platform_driver_register(&uart_driver); //将uart的driver注册到platform_bus上;
platform_device_register(&uart_device); //将uart的device注册到platform_bus上; 例子2:
SPI Master控制器:drivers/spi/my_spi_master.c
platform_device_register(&dw_spi0_device); //注册device
platform_driver_probe(&dw_spi0_driver, dw_spi0_probe); //1、注册driver
//2、spi_new_device子函数会注册SPI Flash的device到spi总线上;
//3、这里实现Master和Flash的绑定,即flash要使用哪个控制器控制; 例子3:
SPI Flash:drivers/mtd/gd25q_spi.c
spi_register_driver(&spi_flash_drv); //注册SPI Flash的driver到spi总线 上面几个例子的device和driver都成功注册后,对应总线的match回调函数会成功匹配driver和device,
并调用driver的probe函数完成设备初始化。 可以看到,不同设备的device和driver注册位置可能不同、注册顺序可能不同、注册函数名可能不同!!

4、设备和驱动的匹配:

老版内核的匹配大部分是看device和driver的name属性是否相同;新版使用设备树的内核中,是根据程序中driver的compatible 与设备树节点的compatible 是否相同来匹配!

match的工作是由总线(bus)来完成。

在xxx_device_register()或xxx_drvier_register(),即设备或驱动注册的时候,都会引发总线调用自己的match函数来寻找是否挂载有与该设备(或驱动)名字匹配的驱动(或设备);

如果只注册了设备或者只注册了驱动,总线会判定匹配失败,则暂时不会调用driver中的probe函数进行初始化等操作; 要等到设备、驱动都注册成功并匹配绑定后才会调用。

Linux的总线设备驱动模型的更多相关文章

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

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

  2. Linux I2C总线设备驱动模型分析(ov7740)

    1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...

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

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

  4. usb驱动开发4之总线设备驱动模型

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

  5. 总线设备驱动模型---platform篇

    总线设备驱动模型----驱动篇 http://blog.chinaunix.net/uid-27664726-id-3334923.html http://blog.chinaunix.net/uid ...

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

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

  7. Linux总线设备驱动模型

    1. Linux2.6内核引入总线.设备.驱动模型来描述各种总线(PCI.USB.I2C.SPI)与外围设备及其驱动之间的关系. 2. 在Linux内核中,总线用bus_type结构来描述,定义于文件 ...

  8. Linux平台总线设备驱动

    1. 平台总线(Platform bus)是linux2.6内核加入的一种虚拟总线,其优势在于采用了总线的模型对设备(没有挂到真实总线的设备)与驱动进行了管理,这样提高了程序的可移植性. 2. 平台总 ...

  9. Linux下 USB设备驱动分析(原创)

    之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB ...

随机推荐

  1. 5个不常提及的HTML技巧

    2021年你需要知道的HTML标签和属性 Web开发人员都在广泛的使用HTML.无论你使用什么框架或者选择哪个后端语言,框架在变,但是HTML始终如一.尽管被广泛使用,但还是有一些标签或者属性是大部分 ...

  2. 暑假撸系统6- Thymeleaf ajax交互!

    本来用Thymeleaf也没想着深度使用ajax,就是用也是非常传统的ajax方式提交然后js控制修改下变量.闲来无事的时候看Thymeleaf的教程发现一哥们的实现方式,以及实现思路,堪称惊奇,先说 ...

  3. pytest(12)-Allure常用特性allure.attach、allure.step、fixture、environment、categories

    上一篇文章pytest Allure生成测试报告我们学习了Allure中的一些特性,接下来继续学习其他常用的特性. allure.attach allure.attach用于在测试报告中添加附件,补充 ...

  4. 面渣逆袭:二十二图、八千字、二十问,彻底搞定MyBatis!

    大家好,我是老三,面渣逆袭系列继续,这节我们的主角是MyBatis,作为当前国内最流行的ORM框架,是我们这些crud选手最趁手的工具,赶紧来看看面试都会问哪些问题吧. 基础 1.说说什么是MyBat ...

  5. [LeetCode]1342. 将数字变成 0 的操作次数

    给你一个非负整数 num ,请你返回将它变成 0 所需要的步数. 如果当前数字是偶数,你需要把它除以 2 :否则,减去 1 . 示例 1: 输入:num = 14 输出:6 解释: 步骤 1) 14 ...

  6. vue3-hash-calendar,一款基于vue3.x开发的移动端日期时间选择组件

    在大家的催更下,鸽了一天又一天,vue3-hash-calendar 终于在今天诞生了. 按照惯例,先上效果图 Demo 扫描上方二维码或者请用浏览器的手机模式查看:https://www.hxkj. ...

  7. 大数据BI系统挖掘企业业务上的价值

    ​相信关注过我们的肯定知道BI是什么,但是老话常谈以防新朋友不知道BI的含义,BI(Business Intelligence)即商务智能,它是一套完整的解决方案,用来将企业中现有的数据进行有效的整合 ...

  8. 苹果如何控制android手机,安卓手机怎么控制苹果?

    小编经常通过手机远程控制别人手机,帮助他人解决一些电脑问题,另外还经常需要通过远程电脑控制服务器,管理脚本之家的服务器等等,可能这些对大家都没有什么诱惑,今天笔者为大家带来一个非常有趣的手机控制电脑的 ...

  9. MyBatis核心对象

    MyBatis 有三个基本要素: 核心接口和类 MyBatis核心配置文件(mybatis-config.xml) SQL映射文件(mapper.xml) 下面首先介绍 MyBatis 的核心接口和类 ...

  10. shell脚本加密方式

    --作者:飞翔的小胖猪 --创建时间:2021年5月17日 --修改时间:2021年5月17日 说明 shell作为Linux操作系统中原生的语言环境,由于其简单.便捷.可以移植等特性常被运维人员作为 ...