驱动开发硬核特训 · Day 6 : 深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比
🔍
B站相应的视屏教程:
📌 内核:博文+视频 - 从静态绑定驱动模型到现代设备模型
主题:深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比
在上一节中,我们从驱动框架的历史演进出发,分析了早期的静态绑定驱动模型及其局限性,并逐步过渡到现代 Linux 设备模型架构。本节将聚焦于设备模型运行时的数据结构与匹配流程,结合实际平台(NXP i.MX8M 与 Raspberry Pi),从设备树的编写、设备注册、驱动匹配、probe 调用等多个角度展开,理论与实战融合讲解设备模型的本质运作方式。
📘 第一部分:设备模型的本质问题 —— 驱动如何找到设备?
在设备模型中,驱动程序不再"直接控制硬件",而是等待系统提供设备信息,再由总线驱动匹配机制完成“驱动与设备的配对”,最终执行 probe()。
因此,理解设备模型的核心本质,就是要搞清楚:
“驱动是怎么和设备匹配的?设备又是怎么被注册到系统中的?”
我们将通过 i.MX8M 和 Raspberry Pi 两个平台,来回答这个问题。
📘 第二部分:设备节点的来源 —— 设备树(Device Tree)
✅ 什么是设备树?
设备树(DTS)是一种用于描述硬件信息的数据结构,编译为 DTB 后在内核启动初期被解析,生成内核中的 struct device_node 树形结构。内核随后根据设备树中的节点内容,注册相应的 platform_device。
📎 i.MX8M 示例(LCDIF3 控制器)
lcdif3: lcd-controller@32fc6000 {compatible = "fsl,imx8mp-lcdif1";reg = <0x32fc6000 0x10000>;interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clk IMX8MP_CLK_MEDIA_APB_ROOT>, ...;status = "okay";
};
📌 内核会根据 compatible 字符串创建一个 platform_device,名字类似 lcdif3.32fc6000。
📎 Raspberry Pi 示例(I2C 控制器)
i2c1: i2c@7e804000 {compatible = "brcm,bcm2835-i2c";reg = <0x7e804000 0x1000>;interrupts = <2 21>;clock-frequency = <100000>;status = "okay";
};
设备树被内核解析后,注册为 platform_device,后续等待匹配合适的驱动。
📘 第三部分:驱动如何声明匹配信息?
驱动需要提供一个 of_match_table,用于告诉设备模型:“我支持哪些设备”。
static const struct of_device_id lcdifv3_dt_ids[] = {{ .compatible = "fsl,imx8mp-lcdif1" },{ }
};
MODULE_DEVICE_TABLE(of, lcdifv3_dt_ids);static struct platform_driver lcdifv3_driver = {.probe = lcdifv3_probe,.remove = lcdifv3_remove,.driver = {.name = "imx-lcdifv3",.of_match_table = lcdifv3_dt_ids,},
};
🔍 注意:只有匹配成功,probe 才会被调用。
📘 第四部分:匹配过程是如何完成的?
✅ 匹配的参与者:
| 组件 | 数据结构 |
|---|---|
| 设备 | struct platform_device |
| 驱动 | struct platform_driver |
| 匹配规则 | struct of_device_id[] |
| 总线中转调度器 | struct bus_type |

✅ 匹配流程
- 设备树解析阶段,生成
platform_device(如lcdif3) - 驱动注册时,添加到
platform_bus_type的driver_list - 内核自动遍历设备与驱动,调用
bus_type->match() - 匹配成功后:
- 设置
pdev->dev.driver = &driver - 调用
driver->probe(pdev)完成初始化
- 设置
📘 第五部分:数据结构流动分析(从 DTS 到 probe)
📌 流程图:
DTS → of_node (设备树节点)↓
of_platform_populate()↓
platform_device_register()↓
/sys/devices/platform/xxx ←→ /sys/bus/platform/devices/xxx↓
platform_bus_type.match()↓
platform_driver.probe()
📎 代码对应点(以 LCDIF3 为例):
| 关键节点 | 对应代码 |
|---|---|
| compatible = “fsl,imx8mp-lcdif1” | of_device_id 中匹配 |
| reg/clocks 等资源 | of_address_to_resource() 等函数读取 |
| probe 中访问资源 | platform_get_resource() / devm_ioremap_resource() |
📘 第六部分:i.MX8M vs 树莓派平台对比
| 对比维度 | NXP i.MX8M | Raspberry Pi |
|---|---|---|
| SoC 架构 | 多个 LCDIF 控制器 + VPU | Broadcom BCM283x |
| DTS 中定义 | fsl,imx8mp-lcdif1 | brcm,bcm2835-i2c |
| 驱动模块名 | imx-lcdifv3 | i2c-bcm2835 |
| 驱动结构 | 完整 platform_driver + match | 同样采用 of_match_table 匹配 |
| 热插拔支持 | 支持 runtime pm / suspend / resume | 同样支持 PM、sysfs、modprobe 热加载 |
📌 虽然 SoC 不同,但设备模型使用方式完全统一。
📘 第七部分:常见问题与调试技巧
❓ Q1: 为什么 probe 没被调用?
- 没有写
of_match_table compatible写错,无法匹配- 驱动未被编译进内核或未加载
status = "disabled"导致设备未注册
❓ Q2: 如何确认设备已注册?
- 查看
/sys/bus/platform/devices/ - 使用
dmesg检查设备是否出现 - 加
dev_info()等日志确认 probe 是否执行
❓ Q3: 如何查看匹配关系?
modinfo xxx.ko # 查看 compatible alias
ls /sys/bus/platform/drivers/xxx
📘 第八部分:实战建议
- 永远在驱动中写上正确的
of_match_table - 使用
devm_*系列管理资源,避免内存泄漏 - 善用
dev_dbg()、dev_err()等接口打印调试信息 - 多观察
/sys/目录,理解设备与驱动的 sysfs 映射关系 - 多平台共享一个驱动时,合理利用
of_device_id.data携带平台定制参数
✅ 总结与回顾
本篇深入分析了设备模型中从 DTS → 设备注册 → 驱动匹配 → probe 执行的完整过程。通过对比 i.MX8M 与树莓派平台,我们看到了设备模型在不同平台间的通用性与强大抽象能力。
📌 核心关键词:
- 设备树注册 → platform_device 创建
- 驱动注册 → platform_driver with of_match_table
- 内核总线 → bus_type 匹配 → 调用 probe
这正是现代 Linux 驱动开发的标准范式。
下一篇我们将从 资源管理角度(时钟、中断、寄存器、GPIO)展开,讲解 platform_get_resource()、devm_*()、of_property_read_*() 等函数在实际项目中的最佳使用方式。
相关文章:
驱动开发硬核特训 · Day 6 : 深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比
🔍 B站相应的视屏教程: 📌 内核:博文视频 - 从静态绑定驱动模型到现代设备模型 主题:深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比 在上一节中,我们从驱动框架的历史演进出…...
【UE5 C++课程系列笔记】35——HTTP基础——HTTP客户端异步请求API接口并解析响应的JSON
目录 前言 步骤 一、 搭建异步蓝图节点框架 二、异步蓝图节点嵌入到引擎的执行流程 三、获取本地时间并异步返回 四、获取网络时间并异步返回 五、源码 前言 本文以请求网络/本地时间API为例,介绍如何实现HTTP异步请求。 步骤 一、 搭建异步蓝图节点框架 …...
手机静态ip地址怎么获取?方法与解析
而在某些特定情境下,我们可能需要为手机设置一个静态IP地址。本文将详细介绍手机静态IP地址详解及获取方法 一、什么是静态IP地址? 静态IP:由用户手动设置的固定IP地址,不会因网络重启或设备重连而改变。 动态IP:由路…...
个人博客系统后端 - 注册登录功能实现指南
一、功能概述 个人博客系统的注册登录功能包括: 用户注册:新用户可以通过提供用户名、密码、邮箱等信息创建账号用户登录:已注册用户可以通过用户名和密码进行身份验证,获取JWT令牌身份验证:使用JWT令牌访问需要认证…...
Python 基础语法汇总
Python 语法 │ ├── 基本结构 │ ├── 语句(Statements) │ │ ├── 表达式语句(如赋值、算术运算) │ │ ├── 控制流语句(if, for, while) │ │ ├── 定义语句(def…...
Linux上位机开发实践(OpenCV算法硬件加速)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 图像处理里面,opencv基本是一个标准模块。但是由于图像处理的特点,如果所有的算法都是cpu来做的话,效率会很低。…...
Spring Boot MongoDB自定义连接池配置
手打不易,如果转摘,请注明出处! 注明原文:http://zhangxiaofan.blog.csdn.net/article/details/144341407 一、引言 在 Spring Boot 应用中使用 MongoDB 时,合理配置连接池可以显著提升数据库访问的性能和稳定性。默…...
Redis与Mysql双写一致性如何保证?
我们在面试的时候redis与mysql双写一致性是一个常考的问题,今天我们就一起探讨一下吧 所谓的一致性就是数据的一致性,在分布式系统中,可以理解为多个节点中数据的值是一致的。 强一致性: 这种一致性级别是最符合用户直觉的&…...
C#核心学习(十六)面向对象--关联知识点(2)string和Stringbuilder
引言 在C#开发中,字符串处理是日常编码的基础需求。然而string和StringBuilder的选择常常引发困惑——何时该用不可变的string?什么场景下必须选择可变的StringBuilder?本文将深入剖析两者的核心差异,并通过完整API对比给出实用建…...
游戏引擎学习第223天
回顾 今天我们正在进行过场动画序列的制作,因此我想深入探讨这个部分。昨天,我们暂时停止了过场动画的制作,距离最终结局还有一些内容没有完成。今天的目标是继续完成这些内容。 我们已经制作了一个过场动画的系列,并把它们集中…...
趣味编程之go与rust的爱恨情仇
声明:此篇文章利用deepseek生成。 第一章:出身之谜 Go(江湖人称"高小戈")是名门之后——谷歌家的三少爷。生来就带着"简单粗暴"的家族基因,口号是**“少写代码多搬砖,并发处理赛神仙”**。它爹Ro…...
DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_基础功能示例(CalendarView01_01)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_基础功能示例(CalendarView01_01)📚…...
数据结构第五版【李春葆】
数据结构教程上机实验指导第5版(李春葆主编).pdf 数据结构教程(第5版)(李春葆).pdf 数据结构教程(第五版)课后习题参考答案(李春葆).pdf 数据结构教…...
LabVIEW配电器自动测试系统
随着航天技术的迅猛发展,航天器供配电系统的结构越来越复杂,对配电器的功能完整性、稳定性和可靠性提出了更高要求。传统人工测试方式难以满足高效率、高精度、可重复的测试需求。本项目开发了一套基于LabVIEW平台的宇航配电器自动测试系统,融…...
PhotoShop学习09
1.弯曲钢笔工具 PhotoShop提供了弯曲钢笔工具可以直观地创建路径,只需要对分段推拉就能够进行修改。弯曲港币工具位于工具面板中的钢笔工具里,它的快捷键为P。 在使用前,可以把填充和描边选为空颜色,并打开路径选项,勾…...
【C++】哈希unordered_map和set的使用以及哈希表,哈希桶的概念以及底层实现
📚 博主的专栏 🐧 Linux | 🖥️ C | 📊 数据结构 | 💡C 算法 | 🌐 C 语言 本文章完整代码在下篇文章开头给出 上篇文章:map和set使用红黑树封装的底层实现 下篇文章:封装…...
AOSP14 Launcher3——手势上滑关键类AbsSwipeHandler解析
我们来深入分析 quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java 这个非常核心且复杂的类。 1. 核心作用 (Core Role): AbsSwipeUpHandler 是 Quickstep (Launcher3 的手势导航实现) 中处理从屏幕底部上滑手势的核心逻辑抽象基类。它负责管理从手势开始到结束的…...
设计模式——建造者模式(生成器模式)总结
当我们需要创建一个非常复杂的对象时,可以使用建造者模式,分步骤建造一个对象,最后将完整的对象返回给客户端。 比如,我们要生成一个房子对象,建造一个房子,需要打地基、盖围墙、盖地板、安装门、安装窗户…...
Spring Boot(二十一):RedisTemplate的String和Hash类型操作
RedisTemplate和StringRedisTemplate的系列文章详见: Spring Boot(十七):集成和使用Redis Spring Boot(十八):RedisTemplate和StringRedisTemplate Spring Boot(十九)…...
使用Python爬虫的2大原因和6大常用库
爬虫其实就是请求http、解析网页、存储数据的过程,并非高深的技术,但凡是编程语言都能做,连Excel VBA都可以实现爬虫,但Python爬虫的使用频率最高、场景最广。 这可不仅仅是因为Python有众多爬虫和数据处理库,还有一个…...
Java 架构设计:从单体架构到微服务的转型之路
Java 架构设计:从单体架构到微服务的转型之路 在现代软件开发中,架构设计的选择对系统的可扩展性、可维护性和性能有着深远的影响。随着业务需求的日益复杂和用户规模的不断增长,传统的单体架构逐渐暴露出其局限性,而微服务架构作…...
C# 混淆代码工具--ConfuserEx功能与使用指南
目录 1 前言1.1 可能带来的问题 2 ConfuserEx2.1 简介2.2 功能特点2.3 基本使用方法2.4 集成到MSBuild2.5 深入设置2.5.1 保护机制2.5.1.1 ConfuserEx Protection 2.5.2 精细的代码保护主要特性1. decl-type(string)2.full-name(string)3. is-public()4. match(string)5. match…...
使用PyTorch实现目标检测边界框转换与可视化
一、引言 在目标检测任务中,边界框(Bounding Box)的坐标表示与转换是核心基础操作。本文将演示如何: 实现边界框的两种表示形式(角点坐标 vs 中心坐标)之间的转换 使用Matplotlib在图像上可视化边界框 验…...
nlp面试重点
深度学习基本原理:梯度下降公式,将损失函数越来越小,最终预测值和实际值误差比较小。 交叉熵:-p(x)logq(x),p(x)是one-hot形式。如果不使用softmax计算交叉熵,是不行的。损失函数可能会非常大,…...
欢乐力扣:反转链表二
文章目录 1、题目描述2、思路 1、题目描述 反转链表二。 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 2、思路 参考官方题解,基本思路…...
2025最新系统 Git 教程(七)(完结)
第4章 分布式Git 4.1 分布式 Git - 分布式工作流程 你现在拥有了一个远程 Git 版本库,能为所有开发者共享代码提供服务,在一个本地工作流程下,你也已经熟悉了基本 Git 命令。你现在可以学习如何利用 Git 提供的一些分布式工作流程了。 这一…...
14-大模型微调和训练之-Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析(二分类))
1. datasets 库核心方法 1.1. 列出数据集 使用 datasets 库,你可以轻松列出所有 Hugging Face 平台上的数据集: from datasets import list_datasets # 列出所有数据集 all_datasets list_datasets() print(all_datasets)1.2. 加载数据集 你可以通过…...
聊透多线程编程-线程基础-4.C# Thread 子线程执行完成后通知主线程执行特定动作
在多线程编程中,线程之间的同步和通信是一个常见的需求。例如,我们可能需要一个子线程完成某些任务后通知主线程,并由主线程执行特定的动作。本文将基于一个示例程序,详细讲解如何使用 AutoResetEvent 来实现这种场景。 示例代码…...
论文阅读笔记——Reactive Diffusion Policy
RDP 论文 通过 AR 提供实时触觉/力反馈;慢速扩散策略,用于预测低频潜在空间中的高层动作分块;快速非对称分词器实现闭环反馈控制。 ACT、 π 0 \pi_0 π0 采取了动作分块,在动作分块执行期间处于开环状态,无法及时响…...
ISIS协议(动态路由协议)
ISIS基础 基本概念 IS-IS(Intermediate System to Intermediate System,中间系统到中间系统)是ISO (International Organization for Standardization,国际标准化组织)为它的CLNP(ConnectionL…...
