1.概要
2.内容
在设备树(Device Tree)中,compatible
属性是驱动与硬件匹配的核心机制,它通过字符串列表描述设备的兼容性,内核根据这些字符串匹配对应的驱动程序。以下是几个典型的应用示例:
1. 简单GPIO设备(如LED)
场景:通过GPIO控制一个LED。
设备树节点:
led {
compatible = "vendor,led"; // 驱动匹配的关键字符串
gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
label = "user-led";
};
驱动代码(Linux内核):
static const struct of_device_id my_led_of_match[] = {
{ .compatible = "vendor,led" }, // 匹配设备树中的compatible属性
{ }
};
static struct platform_driver my_led_driver = {
.driver = {
.name = "my-led",
.of_match_table = my_led_of_match,
},
.probe = my_led_probe,
// ...
};
2. I2C设备(如温度传感器)
场景:通过I2C总线连接的温度传感器(如TMP102)。
设备树节点:
i2c@40000000 {
compatible = "allwinner,sun4i-i2c";
reg = <0x40000000 0x1000>;
// ...
temp_sensor@48 {
compatible = "ti,tmp102"; // 匹配TI官方驱动
reg = <0x48>;
};
};
驱动代码:
static const struct of_device_id tmp102_of_match[] = {
{ .compatible = "ti,tmp102" },
{ }
};
static struct i2c_driver tmp102_driver = {
.driver = {
.name = "tmp102",
.of_match_table = tmp102_of_match,
},
// ...
};
3. SPI设备(如LCD显示屏)
场景:通过SPI接口连接的LCD显示屏。
设备树节点:
spi@10000000 {
compatible = "allwinner,sun4i-spi";
reg = <0x10000000 0x1000>;
// ...
lcd@0 {
compatible = "vendor,lcd-spi"; // 自定义驱动匹配
reg = <0>;
spi-max-frequency = <10000000>;
};
};
驱动代码:
static const struct of_device_id lcd_of_match[] = {
{ .compatible = "vendor,lcd-spi" },
{ }
};
static struct spi_driver lcd_driver = {
.driver = {
.name = "lcd-spi",
.of_match_table = lcd_of_match,
},
// ...
};
4. 多兼容字符串(兼容旧驱动)
场景:设备兼容多个驱动版本(如新驱动兼容旧硬件)。
设备树节点:
ethernet@1c500000 {
compatible = "realtek,rtl8211f", "realtek,rtl8211"; // 优先匹配新驱动
reg = <0x1c500000 0x1000>;
// ...
};
驱动代码:
static const struct of_device_id rtl8211_of_match[] = {
{ .compatible = "realtek,rtl8211f" }, // 优先匹配
{ .compatible = "realtek,rtl8211" },
{ }
};
5. 平台设备(如SoC内置外设)
场景:描述SoC内置的UART控制器。
设备树节点:
uart@01c28000 {
compatible = "fsl,imx6q-uart", "ns16550a"; // 优先匹配IMX6Q的UART驱动
reg = <0x01c28000 0x4000>;
clocks = <&clks 172>;
// ...
};
驱动代码:
static const struct of_device_id imx_uart_of_match[] = {
{ .compatible = "fsl,imx6q-uart" },
{ }
};
static struct platform_driver imx_uart_driver = {
.driver = {
.name = "imx-uart",
.of_match_table = imx_uart_of_match,
},
// ...
};
关键规则:
- 命名规范:
compatible
字符串通常为<厂商>,<设备名>
(如"ti,tmp102"
),避免使用通用名称(如"led"
)。 - 匹配顺序:内核按顺序匹配字符串,第一个匹配项优先。
- 多字符串:支持多个兼容项(如兼容旧设备或通用驱动)。
通过合理设计 compatible
属性,可以实现硬件与驱动的灵活绑定,是设备树的核心机制之一。
3.关联链接
4.关联知识
1.compatible 属性应用举例
以下从不同技术领域为您展示 compatible
属性的典型应用场景及实例:
一、Android 开发:SDK 版本兼容
在 Android 项目的 build.gradle
文件中,通过 compatibleSdkVersion
指定应用兼容的最低 SDK 版本,确保代码在不同设备上稳定运行。
示例代码:
android {
defaultConfig {
compatibleSdkVersion 30 // 兼容 Android 11(API 30)
minSdkVersion 21 // 最低支持 Android 5.0
}
}
代码逻辑适配:
// 根据当前设备版本执行特定逻辑
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// 适配 Android 4.0 的代码(如旧版 API 调用)
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 使用 Android 5.0+ 的新特性(如 Material Design)
}
二、Linux 设备树:硬件驱动绑定
在设备树(DTS)中,compatible
属性用于将硬件设备与内核驱动匹配,格式为 "厂商,型号"
。内核按顺序查找匹配的驱动。
示例 DTS 片段:
sound {
compatible = "fsl,imx6ul-evk-wm8960", "fsl,imx-audio-wm8960";
// 其他硬件配置(如寄存器地址、中断等)
};
驱动匹配逻辑:
- 内核优先查找
fsl,imx6ul-evk-wm8960
对应的驱动。 - 若未找到,则尝试
fsl,imx-audio-wm8960
。 - 驱动代码中通过
DT_DRV_COMPAT
宏定义匹配的字符串:#define DT_DRV_COMPAT fsl_imx_audio_wm8960
三、.NET 跨语言兼容:CLS 规范
在 .NET 中,CLSCompliant
属性确保组件符合公共语言规范(CLS),从而可在所有 .NET 语言(如 C#、VB.NET)中互操作。
示例代码:
[assembly: CLSCompliant(true)] // 标记程序集为 CLS 兼容
public class MathUtils {
// 兼容的方法(参数/返回值符合 CLS 类型)
public int Add(int a, int b) { return a + b; }
// 非兼容方法(需标记为 false)
[CLSCompliant(false)]
public uint AdvancedCalculation() { return 0u; }
}
编译器行为:
- 若代码违反 CLS 规范(如使用
uint
类型),编译器会发出警告。
四、跨平台框架:Flutter 兼容层
Flutter 通过内置兼容层确保同一代码库适配 iOS 和 Android,自动处理平台差异(如导航栏、手势)。
示例代码:
// 统一处理平台特定逻辑
if (Platform.isAndroid) {
// Android 专属配置(如状态栏颜色)
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
} else if (Platform.isIOS) {
// iOS 专属配置(如返回按钮样式)
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
}
五、Windows 系统:注册表兼容性设置
通过修改注册表禁用长路径兼容模式,解决旧程序在 Windows 10/11 上的路径限制。
操作步骤:
- 按
Win + R
打开运行窗口,输入regedit
。 - 导航至路径:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
- 找到
LongPathsEnabled
键值,将其数值改为0
。 - 重启电脑使配置生效。
六、C 语言:数组类型兼容性
C 语言中,数组类型兼容需满足元素类型兼容,且若指定长度,则长度必须一致。
示例代码:
int arr1[5];
int arr2[5]; // 兼容(元素类型相同,长度一致)
int arr3[6]; // 不兼容(长度不同)
// 隐式指针转换(需注意 const 修饰符)
int* p = NULL;
const int* cp = p; // 允许(添加 const 限定符)
// p = cp; // 错误(丢弃 const 限定符)
p = (int*)cp; // 显式转换(需强制类型转换)
总结
compatible
属性通过明确兼容性规则,在 版本适配、硬件驱动、跨语言互操作、平台差异处理 等场景中发挥关键作用。开发者需根据具体技术栈(如 Android、Linux、.NET)选择合适的兼容性策略,确保代码的稳定性和可移植性。