compatible 属性 引用举例

以下是设备树(Device Tree)中 compatible 属性的具体引用举例,涵盖不同硬件场景和驱动匹配逻辑:


1. 基础示例:PWM 控制器

设备树节点(.dts 文件)

pwm@020c0000 {
    compatible = "fsl,imx6q-pwm", "brcm,bcm2835-pwm";
    reg = <0x020c0000 0x4000>;
    #pwm-cells = <2>;
};

驱动代码匹配逻辑

// drivers/pwm/pwm-imx.c
static const struct of_device_id pwm_of_match[] = {
    { .compatible = "fsl,imx6q-pwm" }, // 优先匹配此驱动
    { .compatible = "brcm,bcm2835-pwm" }, // 备选兼容驱动
    { /* sentinel */ }
};


// 若设备树中 compatible 顺序为 "brcm,bcm2835-pwm", "fsl,imx6q-pwm"
// 则内核会优先尝试加载 bcm2835-pwm 驱动

2. 多兼容字符串:I2C 设备

设备树节点

i2c@7e204000 {
    compatible = "brcm,bcm2835-i2c", "simple-bus";
    reg = <0x7e204000 0x1000>;
    #address-cells = <1>;
    #size-cells = <0>;
};

驱动匹配逻辑

  • 内核优先尝试 brcm,bcm2835-i2c 驱动(如 Raspberry Pi 的 I2C 控制器)。
  • 若未找到专用驱动,则回退到通用 simple-bus 驱动(用于总线设备枚举)。

3. SoC 级别兼容性

设备树根节点

/ {
    compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
    model = "Raspberry Pi 3 Model B Rev 1.2";
    // ...
};

作用

  • raspberrypi,3-model-b:特定开发板的兼容标识,用于加载板级驱动(如 GPIO 引脚复用)。
  • brcm,bcm2837:SoC 级别标识,用于加载芯片通用驱动(如时钟、中断控制器)。

4. 驱动代码中的匹配表

驱动示例(of_match_table

// drivers/leds/leds-gpio.c
static const struct of_device_id gpio_leds_of_match[] = {
    { .compatible = "gpio-leds" }, // 通用 GPIO LED 驱动
    { .compatible = "raspberrypi,gpio-leds" }, // 树莓派定制驱动
    { /* sentinel */ }
};


// 若设备树中 compatible 为 "raspberrypi,gpio-leds",则加载定制驱动
// 否则回退到通用 "gpio-leds" 驱动

5. 兼容性扩展:屏幕控制器

设备树节点

lcdc@021c0000 {
    compatible = "fsl,imx6q-lcdif", "simple-panel";
    reg = <0x021c0000 0x4000>;
    // ...
};

驱动逻辑

  • 优先尝试 fsl,imx6q-lcdif(NXP i.MX6Q 的 LCD 控制器驱动)。
  • 若未找到,则尝试 simple-panel(通用面板驱动,仅支持基础功能)。

6. 验证兼容性匹配

步骤 1:编译设备树

dtc -I dts -O dtb -o myboard.dtb myboard.dts

步骤 2:查看内核解析结果

cat /proc/device-tree/pwm@020c0000/compatible
# 输出应为:fsl,imx6q-pwm\0brcm,bcm2835-pwm\0

步骤 3:检查驱动加载日志

[ 1.234567] pwm-imx: probe of pwm@020c0000 failed with error -22
# 错误示例:若驱动未匹配,检查 compatible 字符串是否与驱动中的 of_match_table 一致

关键规则总结

  1. 优先级顺序:设备树中的 compatible 字符串按从左到右顺序匹配,驱动代码中的 of_match_table 同理。
  2. 唯一性:厂商缩写(如 fslbrcm)需唯一,设备型号需明确(如 imx6q-pwm)。
  3. 回退机制:通过追加通用字符串(如 simple-bus)实现驱动兼容性降级。

通过合理设计 compatible 属性,可确保硬件与驱动的精准匹配,同时提高代码复用性。

1.内核在匹配驱动和设备的过程中,compatible 属性发生的作用举例,最好有具体的代码 

在 Linux 内核中,compatible 属性是驱动与设备匹配的核心纽带。以下通过具体代码示例内核源码分析,完整展示其作用机制:


1. 设备树节点定义(.dts 文件)

// arch/arm/boot/dts/imx6q-sabresd.dts
pwm@020c0000 {
    compatible = "fsl,imx6q-pwm"; // 唯一匹配标识
    reg = <0x020c0000 0x4000>;
    #pwm-cells = <2>; // 定义 PWM 通道参数格式
};

2. 驱动代码中的 of_device_id 匹配表

// drivers/pwm/pwm-imx.c
#include <linux/of.h>


static const struct of_device_id pwm_of_match[] = {
    { .compatible = "fsl,imx6q-pwm" }, // 精确匹配此字符串
    { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pwm_of_match);


// PWM 驱动结构体
static struct platform_driver imx_pwm_driver = {
    .driver = {
        .name = "imx-pwm",
        .of_match_table = pwm_of_match, // 绑定匹配表
    },
    .probe = imx_pwm_probe,
    .remove = imx_pwm_remove,
};

3. 内核匹配流程详解

步骤 1:设备树解析
  • 内核启动时,dtc 编译器将 .dts 转换为二进制设备树(.dtb)。
  • 解析到 pwm@020c0000 节点时,提取 compatible = "fsl,imx6q-pwm"
步骤 2:驱动注册
  • 驱动通过 platform_driver_register(&imx_pwm_driver) 注册自身。
  • 内核将驱动的 of_match_table 存入全局链表。
步骤 3:设备-驱动匹配
  • 内核遍历所有注册的驱动,调用 of_match_device() 函数:
    // lib/of_platform.c
    const struct of_device_id *of_match_device(const struct of_device_id *matches,
    const struct device *dev)
    {
        // 从设备树节点获取 compatible 字符串
        const char *compat = of_get_property(dev->of_node, "compatible", NULL);
        if (!compat)
            return NULL;
    
    
        // 遍历驱动的 of_match_table
        while (matches->compatible[0]) {
            if (of_device_is_compatible(dev->of_node, matches->compatible))
            return matches;
            matches++;
        }
        return NULL;
    }
    • of_device_is_compatible() 会逐字符比较设备树的 compatible 字符串与驱动匹配表中的条目。
    • 若完全匹配(如 fsl,imx6q-pwm),则返回对应的 of_device_id 条目。
步骤 4:驱动绑定
  • 匹配成功后,内核调用驱动的 probe 函数(如 imx_pwm_probe),完成硬件初始化。

4. 关键代码路径追踪

  1. 设备树解析
    • dtb 加载:arch/arm/kernel/devtree.c::unflatten_device_tree()
    • 提取 compatiblelib/of.c::of_get_property()
  2. 驱动匹配
    • 入口函数:drivers/base/platform.c::platform_match()
    • 匹配逻辑:lib/of_platform.c::of_match_device()
  3. 驱动绑定
    • probe 调用:drivers/base/dd.c::driver_probe_device()

5. 调试技巧

  • 查看驱动匹配日志
    [ 1.234567] pwm-imx: probe of pwm@020c0000 failed with error -22
    • -22 表示 EINVAL,通常因 compatible 字符串不匹配或硬件地址错误。
  • 手动验证匹配

    # 查看内核解析后的设备树
    cat /proc/device-tree/pwm@020c0000/compatible
    # 输出应为:fsl,imx6q-pwm
    
    
    # 检查驱动是否注册
    lsmod | grep pwm_imx

6. 扩展场景:多兼容字符串

若设备树节点定义多个 compatible 字符串:

compatible = "fsl,imx6q-pwm", "brcm,bcm2835-pwm";
  • 内核会按顺序尝试匹配驱动中的 of_match_table
  • 若驱动 A 匹配 fsl,imx6q-pwm,驱动 B 匹配 brcm,bcm2835-pwm,则优先加载驱动 A。

通过上述代码和流程分析可见,compatible 属性是驱动与设备通信的“密码”,内核通过严格的字符串匹配确保硬件被正确初始化。理解此机制对嵌入式开发、驱动调试至关重要。

7.关系分析 

2.设备树的 compatible 属性 

在 Linux 设备树(Device Tree)中,compatible 属性是驱动与硬件匹配的核心标识,用于将硬件描述与内核驱动绑定。以下是详细解释:


1. 语法与结构

  • 格式
    compatible = "厂商缩写,设备型号", "通用兼容字符串";
    • 示例:
      compatible = "fsl,imx6q-pwm", "brcm,bcm2835-pwm";
  • 规则
    • 厂商缩写:通常为大写(如 fsl 代表 Freescale/NXP,brcm 代表 Broadcom)。
    • 设备型号:唯一标识硬件(如 imx6q-pwm 表示 i.MX6Q 的 PWM 控制器)。
    • 兼容字符串:可包含多个值,按优先级排序(内核会尝试从左到右匹配驱动)。

2. 核心作用

  • 驱动匹配
    内核通过 compatible 字符串匹配设备树节点与驱动。驱动代码中通过 of_match_table 定义支持的字符串列表:

    static const struct of_device_id pwm_of_match[] = {
        { .compatible = "fsl,imx6q-pwm" },
        { .compatible = "brcm,bcm2835-pwm" },
        { /* sentinel */ }
    };

    兼容性扩展
    如果硬件与现有驱动兼容但型号不同,可通过追加通用字符串(如 "simple-pwm")实现复用。


3. 实际应用场景

  • 新增硬件支持
    当开发新硬件时,需为设备树节点定义唯一的 compatible 字符串,并确保驱动代码中包含该字符串的匹配项。

  • 驱动调试
    若驱动未加载,可通过内核日志(dmesg)检查匹配过程:

    [ 1.234567] pwm-imx: probe of pwm@020c0000 failed with error -22

    此处 -22 表示 EINVAL(无效参数),可能因 compatible 字符串不匹配或硬件地址错误。


4. 最佳实践

  • 唯一性
    避免重复使用其他厂商的 compatible 字符串,防止驱动冲突。

  • 版本控制
    若硬件有修订版本,可在字符串中追加版本号(如 "fsl,imx6q-pwm-v2")。

  • 文档参考
    查阅芯片厂商的文档(如 NXP 的 i.MX 参考手册)获取官方推荐的 compatible 名称。


5. 工具验证

  • 编译检查
    使用设备树编译器(dtc)编译 .dts 文件,检查语法错误:

    dtc -I dts -O dtb -o myboard.dtb myboard.dts
  • 运行时验证
    通过 /proc/device-tree/ 查看内核解析后的设备树:

    cat /proc/device-tree/pwm@020c0000/compatible

    输出应为:

    fsl,imx6q-pwm\0brcm,bcm2835-pwm\0

6. 常见问题

  • 驱动未匹配
    检查 compatible 字符串是否与驱动中的 of_match_table 完全一致(包括大小写)。

  • 字符串顺序
    内核按顺序匹配,优先使用第一个匹配的驱动。若需覆盖默认行为,可调整字符串顺序。


通过合理设计 compatible 属性,可以确保硬件与驱动的精准匹配,是嵌入式系统开发中的关键步骤。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值