Linux的总线设备驱动模型
裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同;
而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的总线设备驱动模型的更多相关文章
- Linux中总线设备驱动模型及平台设备驱动实例
本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...
- Linux I2C总线设备驱动模型分析(ov7740)
1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...
- Linux学习 : 总线-设备-驱动模型
platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...
- usb驱动开发4之总线设备驱动模型
在上文说usb_init函数,却给我们留下了很多岔路口.这次就来好好聊聊关于总线设备驱动模型.这节只讲理论,不讲其中的函数方法,关于函数方法使用参考其他资料. 总线.设备.驱动对应内核结构体分别为bu ...
- 总线设备驱动模型---platform篇
总线设备驱动模型----驱动篇 http://blog.chinaunix.net/uid-27664726-id-3334923.html http://blog.chinaunix.net/uid ...
- 芯灵思SinlinxA33开发板 Linux平台总线设备驱动
1.什么是platform(平台)总线? 相对于USB.PCI.I2C.SPI等物理总线来说,platform总线是一种虚拟.抽象出来的总线,实际中并不存在这样的总线. 那为什么需要platform总 ...
- Linux总线设备驱动模型
1. Linux2.6内核引入总线.设备.驱动模型来描述各种总线(PCI.USB.I2C.SPI)与外围设备及其驱动之间的关系. 2. 在Linux内核中,总线用bus_type结构来描述,定义于文件 ...
- Linux平台总线设备驱动
1. 平台总线(Platform bus)是linux2.6内核加入的一种虚拟总线,其优势在于采用了总线的模型对设备(没有挂到真实总线的设备)与驱动进行了管理,这样提高了程序的可移植性. 2. 平台总 ...
- Linux下 USB设备驱动分析(原创)
之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB ...
随机推荐
- 使用docker部署awx-1.7.1.0(ansible图形化界面)
文章目录 关于环境 下载awx 下载安装所需依赖 安装docker-compose 配置inventory文件 出现的报错 TASK [local_docker : Run migrations in ...
- Python基础—基础数据类型int、bool、str(Day3)
一.int 数字 用于计算,+ - * / % **等 bit_lenth():转化成二进制的最小位数. i=4 print(i.bit_length())执行结果:3 1 0000 0001 2 ...
- 五、MyBatis缓存初体验
缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存, 我们可以避免频繁的与数据库进行交互, 进而提高响应速度. 一级缓存初体验(session,默认打开) 同一查询执行两次以上:selec ...
- JVM学习——学习方法论&学习大纲
2020年02月06日22:25:51 完成了Springboot系列的学习和Kafka的学习,接下来进入JVM的学习阶段 深入理解JVM 学习方法论 如何去学习一门课程--方法论 多讨论,从别人身上 ...
- 图解AI数学基础 | 概率与统计
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/83 本文地址:http://www.showmeai.tech/article-det ...
- 防世界之Web_ics-06
题目: 进入实验环境,发现其他页面啥都没有,题目描述说报表中心数据被删,打开报表中心看看 进入数据中发现url上有?id=1的字样就要注意,敏感起来.id是数值,可以尝试爆破一下. 打开burpsui ...
- python基础之数值类型与序列类型
Hello大家好,我是python学习者小杨同学,已经学习python有一段时间,今天将之前学习过的内容整理一番,在这与大家分享与交流,现在开始我们的python基础知识之旅吧. 数值类型与序列类型 ...
- GAN实战笔记——第五章训练与普遍挑战:为成功而GAN
训练与普遍挑战:为成功而GAN 一.评估 回顾一下第1章中伪造达・芬奇画作的类比.假设一个伪造者(生成器)正在试图模仿达・芬奇,想使这幅伪造的画被展览接收.伪造者要与艺术评论家(判别器)竞争,后者试图 ...
- Win10搭建web服务实现文件共享
配置Internet Information Services服务,实现文件共享. 1.打开控制面板,启用IIS服务. 启用IIS服务,系统会自动搜索并安装IIS服务. 2.管理web服务 此时在浏览 ...
- Hook(钩子技术)基本知识讲解,原理
一.什么是HOOK(钩子) API Windows消息传递机制,当在应用程序进行相关操作,例如点击鼠标.按下键盘,操作窗口等,操作系统能够感知这一事件,接着把此消息放到系统消息队列,然后到应用程序的 ...