当前位置: 首页 > news >正文

复盘|嵌入式Linux驱动开发之I2C子系统

之前看了一位大佬使用费曼学习法复盘了自己对各驱动子系统的理解,这里我也尝试一下,使用文字来进行一下复盘!

I2C子系统各层关系
  • 应用程序向下使用I2C 设备驱动层创建的设备节点进行读、写等操作访问硬件

  • 设备驱动层本身包含控制I2C外设的驱动程序和设备节点。它向上为应用程序创建设备节点,向下调用I2C核心层提供的API与I2C外设通信。

  • I2C核心层向上为设备驱动层提供API接口;向下调用I2C 适配器驱动层提供的接口。

  • I2C 适配器驱动层本身包含I2C 控制器的驱动程序。它向上向I2C核心层注册i2c_adapter并提供I2C传输接口(i2c_algorithm);向下直接操作I2C控制器硬件,实现I2C时序。

  • 硬件层中的I2C控制器需要I2C适配器驱动层驱动它工作。硬件层中的I2C外设通过SDA和SCL与处理器的I2C控制器连接

在这里插入图片描述

从左到右、从适配器驱动到设备驱动、从 Platform 总线到 I2C 总线的接力如何进行?
  • I2C控制器放在platform总线上,adapter放在i2c_bus总线上

在这里插入图片描述

适配器驱动和设备驱动两条线不能分开看!!!

这是一个连续的过程:平台总线 的探测流程触发了 I2C 总线 的探测流程。

阶段一:Platform 总线 —— “适配器驱动” 的加载

这个阶段的目标是让 I2C 控制器(适配器) 本身开始工作。

控制器本身是挂载在 platform_bus_type(平台总线)上的一个设备。

  1. 起点 (DTS -> platform_device)
    • 内核启动,调用 of_platform_populate 来扫描设备树根节点 (/)。
    • 然后,调用 of_platform_bus_create遍历根节点 / 下的所有直接子节点
    • of_platform_bus_create -> of_platform_device_create_pdata
    • 这会调用of_device_alloc分配一个 platform_device 结构体(我们称之为 pdev),并从设备树节点中读取信息(如 “compatible” = “fsl,imx6ul-i2c”)。
    • 关键一步:pdev->dev.bus = &platform_bus_type;声明它属于platform_bus_type平台总线
  2. 注册与探测 (platform_device -> platform_driver)
    • 调用 of_device_add(pdev) -> device_add(pdev) 将这个 platform_device 注册到内核。
    • device_add 内部调用 bus_add_devicepdev 添加到 platform_bus_type 的设备列表(bus->p->klist_devices)中。
    • 触发探测device_add 最后调用 bus_probe_device(pdev)
    • 内核开始为这个 pdev 寻找驱动:device_attach -> bus_for_each_drv(遍历 platform_bus_type 上的所有驱动)。
    • driver_match_device 被调用,用于比较 pdevi2c_imx_driver
  3. 匹配与执行 (Match!)
    • 匹配成功pdev"compatible" 属性 ("fsl,imx6ul-i2c") 与 i2c_imx_driverof_match_table 匹配成功。
    • 内核调用 driver_probe_device -> really_probe(执行探测)。
    • 阶段一终点i2c_imx_driver->probe 函数被执行,也就是 i2c_imx_probe(pdev) 被调用
阶段二:I2C 总线 —— “设备驱动” 的加载

这个阶段在阶段一的 终点 (i2c_imx_probe 函数) 内部被触发。现在 I2C 控制器驱动已经运行,它的任务是初始化控制器硬件,并**“孵化”** 出挂载在它下面的所有 I2C 设备。

  1. 起点 (i2c_imx_probe 内部)
    • i2c_imx_probe 函数(适配器驱动)正在执行。
    • 它初始化 I2C 硬件。
    • i2c_imx_probe调用 i2c_add_numbered_adapter 来注册 i2c_adapter(代表 I2C 控制器本身)。
    • 关键接力棒i2c_imx_probe调用 of_i2c_register_devices,这个函数会去扫描它在设备树中的 子节点(例如 at24@50)。
  2. 孵化 (DTS 子节点 -> i2c_client)
    • 对于 at24@50 这个子节点,内核调用 of_i2c_register_device
    • 这个函数的核心作用就是**“翻译”**:
      1. 它分配一个临时的 struct i2c_board_info info
      2. 它解析 at24@50 节点,把 “reg” (0x50) 存入 info.addr,把 “compatible” (“atmel,24c16”) 存入 info.type,并把节点指针存入 info.of_node
    • i2c_board_info 结构体就像一个“中转站”,它持有了从设备树解析出来的、创建 i2c_client 所需的所有信息。
    • 调用 i2c_new_device(adap, &info)
  3. 注册与探测 (i2c_client -> i2c_driver)
    • i2c_new_device 分配一个 i2c_client 结构体(我们称之为 client)。
    • 它从 infoadap 中拷贝信息到 client
    • 关键一步:client->dev.bus = &i2c_bus_type;声明它属于 I2C 总线
    • 调用 device_register(&client->dev) -> device_add(&client->dev)
    • 触发探测(第二次):device_add 再次调用 bus_probe_device(client)
    • 内核开始为这个 client 寻找驱动:device_attach -> bus_for_each_drv(这次遍历的是 i2c_bus_type 上的所有驱动)。
    • driver_match_device 被调用,用于比较 clientat24_driver
  4. 匹配与执行 (Match!)
    • 匹配成功client 的 “compatible” 属性(来自 info.of_node)与 at24_driverof_match_table 匹配成功。
    • 内核调用 driver_probe_device -> really_probe
    • 阶段二终点at24_driver->probe 函数被执行,也就是 at24_probe(client) 被调用
总结
  1. Platform 总线 负责匹配 DTS 节点 (i2c@021a0000) 和 适配器驱动 (i2c_imx_driver)。
  2. 匹配成功后,执行 i2c_imx_probe
  3. i2c_imx_probe 作为“接力”的中间人,它通过解析 DTS 子节点 (at24@50) 来创建 i2c_client
  4. i2c_client 被注册到 I2C 总线
  5. I2C 总线 负责匹配 i2c_client (at24@50) 和 设备驱动 (at24_driver)。
  6. 匹配成功后,执行 at24_probe
http://www.dtcms.com/a/532163.html

相关文章:

  • AI Agent常用的RAG有哪些种,分别适用于什么情况
  • 对中兴光猫zteOnu.exe项目的简单分析(提供下载地址)
  • 有没有专门做中考卷子的网站网站建设培训要多久
  • 做网站图片用什么格式最好个人网站备案能做宣传用么
  • JAVA1026 方法;类:抽象类、抽象类继承;接口、接口继承 Linux:Mysql
  • 密码学系列 - 零知识证明(ZKP) - NTT与MSM的总结
  • 《解决界面交互痛点:WaterFlow 瀑布流、双层嵌套滚动、键盘避让与跨 Ability 跳转实践》
  • 网页设计建立站点步骤做网站的广告词
  • Spring Boot3零基础教程,生命周期启动加载机制,笔记64
  • StarGantt在线甘特图最新版本评测
  • 43.渗透-Kali Linux-工具-Ettercap(dns欺骗)
  • 详解C++中的迭代器
  • 区块链论文速读 CCF A--USENIX Security 2025(2)
  • 基于区块链的新能源管理平台的设计与实现(源码+文档)
  • 2025年10月26日 AI大事件
  • 企业建站个人建站源码沧州专业网站建设公司
  • 基于springboot的电影评论网站系统设计与实现
  • 1.2.1.3 大数据方法论与实践指南-一种跨团队业务结算方式探索
  • 西安地产网站建设百度手机管家
  • NoSQL 简介
  • C++ 分治 快速排序优化 三指针快排 力扣 面试题 17.14. 最小K个数 题解 每日一题
  • 网站建设业务员怎么做适合建设网站的国外服务器
  • 【第1章】基于FPGA的图像形态学处理学习教程——目录
  • stm32单片机命名规则,c6t6只有32KB,c8t6有64KB
  • 基于华为设备的 OSPF+MSTP+DHCP+NAT 综合网络架构实现
  • 使用uniapp——实现微信小程序的拖拽排序(vue3+ts)
  • 5.23基于 LabVIEW 的科学计算器设计
  • STM32 异常和中断
  • OWL 简介
  • 元器件网站建设案例网站建设专家联系方式