设备树驱动支持的属性

内核源码路径:

Documentation/devicetree/bindings

概念

没有设备树之前。

要想建立一个/dev/xxx文件,用来操作硬件设备需要以下步骤。

  1. 创建xxx_device.c和xxx_device.h来描述设备。比如某个寄存器。
  2. 创建驱动xxx_driver.c和xxx_driver.h操作描述的设备。比如寄存器写入和读取。
  3. 内核编译和引入。(需补充详细过程)

有设备树之后

要想建立一个/dev/xxx文件,用来操作硬件设备需要以下步骤。

  1. 创建设备树,用来描述设备,代替前面的第一步。
  2. 创建驱动xxx_driver.c和xxx_driver.h操作描述的设备。比如寄存器写入和读取。更多时候编译成模块。
  3. 内核编译和引入。(需补充详细过程)

对于自己编写的驱动,设备树要描述这个驱动,设备树和驱动代码必须做关联联动。

而对于常见的驱动,比如iic,spi等。前辈们已经集成在linux内核中,只需要在设备树下描述硬件信息。就能自己识别到这些驱动。设备树最主要的compatible属性如何匹配的,还不是很明白。

如何与内核联动

设备树

hello {
    compatible = "mycompany,hello";
};

驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lingma Assistant");
MODULE_DESCRIPTION("Hello World driver with Device Tree support");

// 匹配成功后调用的 probe 函数
static int hello_probe(struct platform_device *pdev)
{
    printk(KERN_INFO "Hello, World! Device matched: %s\n", pdev->name);
    // 这里可以获取设备树资源,如寄存器、GPIO 等
    return 0;
}

// 设备移除时调用
static int hello_remove(struct platform_device *pdev)
{
    printk(KERN_INFO "Goodbye, World! Device removed.\n");
    return 0;
}

// 定义支持的 compatible 列表
static const struct of_device_id hello_of_match[] = {
    { .compatible = "mycompany,hello" },
    { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, hello_of_match);

// 定义 platform 驱动结构体
static struct platform_driver hello_driver = {
    .probe    = hello_probe,
    .remove   = hello_remove,
    .driver   = {
        .name = "hello",
        .of_match_table = hello_of_match,
    },
};

module_platform_driver(hello_driver);