驱动进化之路:设备树的引入及简明教程

设备树的基本概念和产生背景

问题1:
以LED为例,当要更换LED所用的GPIO引脚时,需要修改驱动程序源码,重新编译驱动,重新加载驱动。
问题2:
由于芯片种类繁多,里面包含了各种各样的芯片所有包含了许多用不着的C代码。
根据上面两个问题:引入设备树
设备树只是用来给内核里的驱动程序,指定硬件的信息。比如 LED 驱动,在
内核的驱动程序里去操作寄存器,但是操作哪一个引脚?这由设备树指定。

设备树的语法


我们需要编写设备树文件(dts: device tree source),它需要编译为
dtb(device tree blob)文件,内核使用的是 dtb 文件。

内核对设备树的处理过程


1.dts在PC机上被编译为dtb文件
2.u-boot把dtb文件传给内核
3.内核解析dtb文件,把每个节点都转化为device_node结构体
4.对于某些device_node结构体,会被转换为platform_device
dtb中的每一个节点都被转换为device_node结构体

根节点被保存在全局变量of_root中,从of_root开始可以访问到任意节点

哪些设备树节点会被转换为platform_device

1.根节点下含有 compatile 属性的子节点
2.含有特定 compatile 属性的节点的子节点
如果一个节点的 compatile 属性,它的值是这 4 者之一:“simplebus”,“simple-mfd”,“isa”,“arm,amba-bus”, 那 么 它 的 子结点 ( 需 含
compatile 属性)也可以转换为 platform_device。
3.总线 I2C、SPI 节点下的子节点:不转换为 platform_device
某个总线下到子节点,应该交给对应的总线驱动程序来处理, 它们不应该被转换为 platform_device。

⚫/mytest 会被转换为 platform_device, 因为它兼容"simple-bus";
它的子节点/mytest/mytest@0 也会被转换为 platform_device
⚫ /i2c 节点一般表示 i2c 控制器, 它会被转换为 platform_device, 在内核
中有对应的 platform_driver;
⚫ /i2c/at24c02 节点不会被转换为 platform_device, 它被如何处理完全由
父节点的 platform_driver 决定, 一般是被创建为一个 i2c_client。
⚫ 类似的也有/spi 节点, 它一般也是用来表示 SPI 控制器, 它会被转换为
platform_device, 在内核中有对应的 platform_driver;
⚫ /spi/flash@0 节点不会被转换为 platform_device, 它被如何处理完全由
父节点的 platform_driver 决定, 一般是被创建为一个 spi_device。

怎么转换为 platform_device

内核处理设备树的函数调用过程,这里不去分析;我们只需要得到如下结论:
◼ platform_device 中含有 resource 数组, 它来自 device_node 的
reg, interrupts 属性;
◼ platform_device.dev.of_node 指向 device_node, 可以通过它获
得其他属性

platform_device 如何与 platform_driver 配对

从设备树转换得来的 platform_device 会被注册进内核里,以后当我们每
注册一个 platform_driver 时,它们就会两两确定能否配对,如果能配对成功
就调用 platform_driver 的 probe 函数。

1.最先比较:是否强制选择某个driver

platform_device.driver_override 和 platform_driver.driver.name
可以设置 platform_device 的 driver_override,强制选择某个 platform_driver

2.然后比较:设备树信息

platform_device.dev.of_node 和 platform_driver.driver.of_match_table。
由设备树节点转换得来的 platform_device 中,含有一个结构体:of_node
结构如下:

如果一个 platform_driver 支 持 设 备 树 , 它 的
platform_driver.driver.of_match_table 是一个数组,类型如下

首先,如果 of_match_table 中含有 compatible 值,就跟 dev 的 compatile
属性比较,若一致则成功,否则返回失败;
其次,如果 of_match_table 中含有 type 值,就跟 dev 的 device_type 属性
比较,若一致则成功,否则返回失败;
最后,如果 of_match_table 中含有 name 值,就跟 dev 的 name 属性比
较,若一致则成功,否则返回失败。
而设备树中建议不再使用 devcie_type 和 name 属性,所以基本上只使用设
备节点的 compatible 属性来寻找匹配的 platform_driver。

接下来比较platform_device_id

比较 platform_device. name 和 platform_driver.id_table[i].name,
id_table 中可能有多项。
platform_driver.id_table 是“platform_device_id”指针,表示该 drv
支持若干个 device,它里面列出了各个 device 的{.name, .driver_data},
其中的“name”表示该 drv 支持的设备的名字,driver_data 是些提供给该
device 的私有数据。

最后比较

platform_device.name 和 platform_driver.driver.name
platform_driver.id_table 可能为空,
这 时 可 以 根 据 platform_driver.driver.name 来 寻 找 同 名 的
platform_device。

有些节点不会生成 platform_device,怎么访问它们

内核会把 dtb 文件解析出一系列的 device_node 结构体,我们可以直接访
问这些 device_node。

驱动进化之路:设备树的引入及简明教程相关推荐

  1. 嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程

    文章目录 1.驱动进化之路:设备树的引入及简明教程 1.1 设备树的引入与作用 1.2 设备树的语法 1.2.1 Devicetree格式 1.2.1.1 DTS文件的格式 1.2.1.2 node的 ...

  2. 设备树的引入及简明教程

    文章目录 1 设备树的引入与作用 2 设备树的语法 2.1 设备树语法概览 2.2 Devicetree 格式 2.2.1 DTS 文件的格式 2.2.2 node 的格式 2.2.3 propert ...

  3. 驱动进化之路:总线设备驱动模型

    文章目录 1 驱动编写的3种方法 1.1 传统写法 1.2 总线设备驱动模型 1.3 设备树 2 在 Linux 中实现"分离":Bus/Dev/Drv 模型 2.1 模型 2.2 ...

  4. 驱动开发基础知识——设备树

    BSP开发工程师[原来BSP就是那些被指臃肿的文件啊 BSP的出生 Linux经过不断的发展,原先嵌入式系统的三层结构逐步演化成为一种四层结构. 这个新增加的中间层次位于操作系统和硬件之间,包含了系统 ...

  5. Linux驱动开发中与设备树相关的6种debug方法

    整理出了6种驱动开发时与设备注册.设备树相关的调试方法,彼此间没有优先级之分,每种方法不一定是最优解,但可以作为一种debug查找问题的手段,快速定位问题原因.例如在芯片验证时,不同时钟频率下系统启动 ...

  6. Android 驱动(10)----设备树(二)linux内核顶层am335x-evm.dts

    设备树(二)linux内核顶层am335x-evm.dts 摘自:http://blog.csdn.net/xiaojiezuo123/article/details/49890507 了解基本的dt ...

  7. Android 驱动(9)----设备树(一)linux内核主线了解dts

    设备树(一)linux内核主线了解dts http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tr ...

  8. linux驱动开发学习2 设备树

    设备树 dtb板级信息文件,大势所趋,一定要学  如何确定要编译哪个DTS文件:查看linux下的arch/arm/boot/dts/Makefile  DTS语言有属于自己的语法:以树形来描述设备信 ...

  9. Linux驱动学习记录-6.设备树的LED驱动

    这一章使用第五章的设备树知识来写led驱动 1.修改设备树 在根节点下面添加子节点 alphaled {#address-cells = <1>;#size-cells = <1&g ...

最新文章

  1. [JavaScript] JavaScript 值类型使用:与数组有关的API
  2. 网站集成支付宝的方法和所需资料下载
  3. python刷新网页脚本_python语言如何测试实现页面下拉刷新
  4. 探寻用户自定义定时任务的实践方案
  5. 基于DOM的Web信息提取方法
  6. 根据Request获取客户端IP
  7. 如何遍历某数据库中的每一个表的总记录数
  8. MySQL 8.0窗口函数
  9. 网络中的那些事儿(五)之校园网规划综述
  10. PPT双屏抽奖,大气,能Hold住全场!与其它PPT内容可融为一体,实现无缝切换!
  11. linux下的mysql调优_MySQL调优三步曲(慢查询、explain profile)
  12. 贪心算法适用条件_贪心算法
  13. 何小龙——DRM 驱动程序开发(VKMS)部分代码修正
  14. 2020全国工业互联网安全技术技能大赛Web题WP
  15. 鸿蒙使用体验 2.0,鸿蒙的到来与华为的破局
  16. Oracle数据库服务重启方法
  17. 再谈 iOS App Crash 防护
  18. 单反相机的传奇—佳能单反50年辉煌之路(连载十三)
  19. HDU - 4532 湫秋系列故事――安排座位
  20. vrchat模型保存_轻松简单自己上传VRChat的Avatar

热门文章

  1. 日期计算器,时间差,零食过期判断
  2. win10正确安装PostgreSQL数据库和PostGIS插件
  3. JAVA中的非法输入如何处理,非法的表达式开始解决办法
  4. python - input()用户输入的值不合法则要求重新输入
  5. 销售宝:微信小程序为什么没有火?
  6. 华为怎么连接android studio,华为荣耀5x怎么连接Android studio
  7. acer s7 linux,清新脱俗深入骨髓!宏碁Aspire S7评测
  8. 英灵神殿云服务器配置要求,英灵神殿云服务器MOD安装教程[多图]
  9. linux命令ps详解
  10. Python递归锁说明举例