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
相关产品推荐
相关产品推荐

