欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 驱动开发硬核特训 · Day 6 : 深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比

驱动开发硬核特训 · Day 6 : 深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比

2025/4/16 4:46:14 来源:https://blog.csdn.net/Interview_TC/article/details/147098105  浏览:    关键词:驱动开发硬核特训 · 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

在这里插入图片描述

✅ 匹配流程

  1. 设备树解析阶段,生成 platform_device(如 lcdif3
  2. 驱动注册时,添加到 platform_bus_typedriver_list
  3. 内核自动遍历设备与驱动,调用 bus_type->match()
  4. 匹配成功后:
    • 设置 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.MX8MRaspberry Pi
SoC 架构多个 LCDIF 控制器 + VPUBroadcom BCM283x
DTS 中定义fsl,imx8mp-lcdif1brcm,bcm2835-i2c
驱动模块名imx-lcdifv3i2c-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_*() 等函数在实际项目中的最佳使用方式。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词