You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核I2C驱动如何向用户空间提供芯片唯一ID?

向用户空间暴露I2C芯片UID的规范做法

在Linux内核中,向用户空间暴露硬件信息的标准方式是利用sysfs框架,但不建议自行创建顶层/sys/mydriver目录,而是遵循内核设备模型的层级结构来实现,具体如下:

1. 规范的实现路径

I2C设备的sysfs节点默认挂载在/sys/bus/i2c/devices/<i2c设备地址>/路径下,你应该在这个设备专属的目录下添加uid属性,而非自建顶层目录。这种方式符合内核设备模型的设计逻辑,也方便用户空间工具(如udev)识别和管理硬件信息。

2. 具体代码实现

通过device_create_file()配合device_attribute来实现只读的uid属性:

#include <linux/device.h>
#include <linux/i2c.h>

// 定义驱动私有数据结构
struct my_i2c_dev {
    struct i2c_client *client;
    u64 uid; // 存储芯片UID
};

// 读取UID的show函数
static ssize_t uid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
    struct my_i2c_dev *i2c_dev = dev_get_drvdata(dev);
    // 这里替换为实际读取芯片UID的I2C操作逻辑
    // 示例:假设已从芯片读取到uid并存入i2c_dev->uid
    return scnprintf(buf, PAGE_SIZE, "%016llx\n", i2c_dev->uid);
}

// 定义只读属性
static DEVICE_ATTR_RO(uid);

// 在probe函数中注册属性
static int my_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    struct my_i2c_dev *i2c_dev;
    int ret;

    i2c_dev = devm_kzalloc(&client->dev, sizeof(*i2c_dev), GFP_KERNEL);
    if (!i2c_dev)
        return -ENOMEM;

    i2c_dev->client = client;
    dev_set_drvdata(&client->dev, i2c_dev);

    // 读取芯片UID的逻辑(示例)
    // ret = read_chip_uid(client, &i2c_dev->uid);
    // if (ret)
    //     return ret;

    // 创建uid属性文件
    ret = device_create_file(&client->dev, &dev_attr_uid);
    if (ret) {
        dev_err(&client->dev, "Failed to create uid attribute\n");
        return ret;
    }

    return 0;
}

// 在remove函数中清理属性
static void my_i2c_remove(struct i2c_client *client)
{
    device_remove_file(&client->dev, &dev_attr_uid);
}

static const struct i2c_device_id my_i2c_id[] = {
    {"my_chip", 0},
    {}
};
MODULE_DEVICE_TABLE(i2c, my_i2c_id);

static struct i2c_driver my_i2c_driver = {
    .driver = {
        .name = "my_i2c_driver",
        .owner = THIS_MODULE,
    },
    .probe = my_i2c_probe,
    .remove = my_i2c_remove,
    .id_table = my_i2c_id,
};
module_i2c_driver(my_i2c_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("I2C driver for chip with UID");

3. 为什么不建议自建顶层sysfs目录

内核明确不推荐在/sys根目录下创建自定义顶层目录,原因包括:

  • 破坏设备模型的层级结构,导致用户空间难以关联硬件设备与其属性;
  • 容易与其他驱动或内核子系统的sysfs节点命名冲突;
  • 不符合Linux内核的编码规范,可能在后续内核版本中无法兼容。

总结

直接向用户空间暴露UID是合理需求,但必须遵循内核sysfs框架的规范,将属性添加到对应I2C设备的sysfs目录下,而非自行创建顶层目录。上述实现方式是Linux驱动开发中的通用做法。

内容的提问来源于stack exchange,提问作者fadedbee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:45:36