Lazy loaded image
🥳嵌入式Linux开发
IIC 驱动专题02 - I2C总线驱动匹配机制分析
Words 2603Read Time 7 min
2025-4-16
2025-4-16
type
date
slug
category
icon
password
参考资料
  • Linux内核文档:
    • Documentation\i2c\instantiating-devices.rst
    • Documentation\i2c\writing-clients.rst
  • Linux内核驱动程序示例:
    • drivers\i2c\i2c-core.c

I2C总线驱动匹配机制分析

I2C总线是Linux设备模型中的一种总线类型,它通过总线匹配机制将I2C设备(client)与相应的驱动(driver)绑定在一起。下面我将结合源码分析I2C总线的匹配机制,特别是i2c_device_match函数的实现。

I2C总线匹配流程图

I2C总线结构定义

i2c-core.c中,I2C总线类型定义如下:
其中.match字段指向i2c_device_match函数,这是I2C总线匹配机制的核心。

i2c_device_match函数分析

i2c_device_match函数实现了I2C设备与驱动的匹配逻辑:
这个函数按照以下顺序尝试匹配:
  1. 设备树匹配:通过of_driver_match_device函数检查设备树中的compatible属性是否与驱动的of_match_table匹配
  1. ACPI匹配:通过acpi_driver_match_device函数检查ACPI设备ID是否与驱动的acpi_match_table匹配
  1. ID表匹配:通过i2c_match_id函数检查设备名称是否与驱动的id_table匹配
只要其中一种匹配成功,函数就返回1,表示匹配成功。

各种匹配方式详解

1. 设备树匹配

设备树匹配通过比较设备节点的compatible属性与驱动的of_match_table来实现。例如:
设备树节点:
驱动中的匹配表:

2. ACPI匹配

ACPI匹配通过比较ACPI设备ID与驱动的acpi_match_table来实现。例如:

3. ID表匹配

ID表匹配是最传统的匹配方式,通过比较设备名称与驱动的id_table来实现:
i2c_match_id函数实现如下:
它通过字符串比较来匹配设备名称与驱动支持的设备ID列表。
 

匹配时机和调用流程

i2c_device_match 函数在以下几种情况下会被调用:
  1. 设备注册时 :当一个I2C设备通过 i2c_new_device 、 i2c_new_dummy 等函数注册到系统时,总线会尝试为其匹配驱动。
  1. 驱动注册时 :当一个I2C驱动通过 i2c_register_driver 注册到系统时,总线会尝试为其匹配已存在的设备。
  1. 总线扫描时 :当系统执行I2C总线扫描时,发现新设备后会尝试匹配驱动。

设备和驱动匹配与绑定机制

drivers\base\dd.c 文件负责处理设备与驱动之间的绑定和解绑关系。其功能主要是
  1. 设备-驱动匹配 :通过总线的match函数(如i2c_device_match)判断设备和驱动是否匹配
  1. 驱动探测 :调用驱动的probe函数初始化设备
  1. 驱动解绑 :处理设备与驱动的分离
  1. 延迟探测 :处理依赖关系导致的探测延迟
设备-驱动匹配流程如下:
  • driver_register 函数定义内核\drivers\base\driver.c文件中,负责将驱动添加到全局驱动列表中,并尝试将驱动与已存在但尚未绑定的设备进行匹配。当I2C驱动通过 i2c_register_driver 注册时,最终会调用到这个函数,从而将I2C驱动纳入Linux设备模型的管理范围内。
    • 这个调用栈展示了从I2C驱动注册到最终与设备匹配的完整过程:
      1. 首先通过i2c_register_driver注册I2C驱动
      1. 然后通过设备模型的核心函数注册到系统
      1. 添加到对应的总线
      1. 遍历总线上的设备进行匹配
      1. 最终调用总线特定的匹配函数判断驱动和设备是否匹配
       
  • device_register 函数定义在Linux内核drivers\base\core.c文件中,用于向系统注册设备,将设备添加到总线上并尝试与驱动匹配。当I2C设备通过 i2c_new_device创建时,最终会调用到这个函数。
    • 这个调用栈展示了从创建I2C设备到最终与驱动匹配的完整过程:
      1. 首先通过i2c_new_device创建I2C设备
      1. 调用device_register将设备注册到设备模型
      1. 通过device_add将设备添加到系统
      1. 触发驱动探测流程
      1. 遍历总线上的驱动进行匹配
      1. 如果找到匹配的驱动则进行探测
      整个过程体现了Linux设备模型的核心工作机制:设备注册时自动寻找匹配的驱动,实现设备和驱动的动态绑定。

匹配成功后的处理

当匹配成功后,总线会调用驱动i2c_device_probe函数来初始化设备:

总结

I2C总线的匹配机制遵循Linux设备模型的通用模式,但增加了对I2C特有的匹配方式支持:
  1. 首先尝试设备树匹配(适用于嵌入式系统)
  1. 然后尝试ACPI匹配(适用于x86平台)
  1. 最后尝试传统的ID表匹配
这种多层次的匹配机制使得I2C驱动能够在不同的平台上灵活工作,同时保持了良好的兼容性。i2c_device_match函数作为匹配的核心,实现了这一机制的关键逻辑。
 
上一篇
模板设计模式:让你的代码结构更清晰
下一篇
Guide to Linux System

Comments
Loading...