在一个驱动程序模块中处理多个 i2c_clients(使用 sysfs)
Handling multiple i2c_clients in one driver module (with sysfs)
我想为 tmp102 温度传感器创建内核驱动程序。
在一个项目中,我只有 1 个传感器,而在另一个项目中,我有 2 个传感器。我希望我的内核模块能够支持 N 个传感器,而不是固定数量。我在管理超过 1 个结构 i2c_client 并为每个结构创建 sysfs 条目时遇到问题。我是这样做的:
在 probe()
函数中,我为我提供 I2C_BOARD_INFO()
的每个设备得到 struct i2c_client*
。
然后我 kobject_create_and_add("tmp102", kernel_kobj)
获取 sysfs.
中模块的主目录
对于我正在创建的每个设备 sysfs_create_group()
,它获取指向静态创建的属性的指针。这些属性将 (*show)()
和 (*store)()
指针设置为静态函数,例如
static ssize_t tmp102_sysfs_thigh_get_one(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
在这个函数中我想通过I2C读取。问题是......我不知道如何获取设备的 struct i2c_client *
应该以某种方式 linked 到这个 sysfs 条目,以及I2C地址在那里!
我应该如何正确地 "link" i2c_client 与 sysfs 条目,以便我可以在函数中获取 I2C 地址?
理想情况下,我希望只有一组函数(每个属性一个)。 sysfs 树应该是这样的:
/sysfs/kernel/tmp102
|
|-> <hex i2c address, e.g. /48>
| |
| |-> temperature
|
|
|-> /49
|
|-> temperature
我希望两个 'temperature' 属性使用相同的函数,它能够确定它应该写入的 I2C 地址。
或者我的架构完全错误?如果是这样,对于需要处理多个 i2c_client
的驱动程序来说应该是什么样子?
编辑:
我决定使用 struct device_attribute
而不是常规的 attribute
。据我了解,使用常规属性时,获取struct device
指针并不容易,struct i2c_client
也是如此。他们不容易 "linked" 和来自 /sys/kernel
的 kobject
s,我需要在这个项目中拥有我的属性。 device_attribute
s 可以在 /sys/devices
中找到 - 我使用了 sysfs_create_group
并且 link 使用 device_attribute
组编辑了我设备的 kobject
。我使用了 sysfs_create_link
,并且 link 使用 /sys/kernel/tmp102
编辑了我设备的 kobject
。这样我就可以为每个设备创建一个文件夹 (link),它指向 /sys/devices
中的原始属性文件夹。
首先,您应该知道已经有一个具有 sysfs 接口的 tmp102 内核驱动程序。看看 drivers/hwmon/tmp102.c.
现在,对于您的问题,您有一个 struct kobject
传递给您的 sysfs 回调。您可以调用 kobj_to_dev()
来获取指向设备的指针。然后,例如,您可以使用 dev_get_drvdata()
获取指向您自己的私有结构的指针,该结构将包含指向 i2c 客户端的指针。不要忘记先在您的探测器中使用 dev_set_drvdata()
进行设置。
您可以在 drivers/rtc/rtc-ds1343.c 中找到示例,但它使用的是 spi_driver。
我想为 tmp102 温度传感器创建内核驱动程序。 在一个项目中,我只有 1 个传感器,而在另一个项目中,我有 2 个传感器。我希望我的内核模块能够支持 N 个传感器,而不是固定数量。我在管理超过 1 个结构 i2c_client 并为每个结构创建 sysfs 条目时遇到问题。我是这样做的:
在
probe()
函数中,我为我提供I2C_BOARD_INFO()
的每个设备得到struct i2c_client*
。然后我
kobject_create_and_add("tmp102", kernel_kobj)
获取 sysfs. 中模块的主目录
对于我正在创建的每个设备
sysfs_create_group()
,它获取指向静态创建的属性的指针。这些属性将(*show)()
和(*store)()
指针设置为静态函数,例如static ssize_t tmp102_sysfs_thigh_get_one(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
在这个函数中我想通过I2C读取。问题是......我不知道如何获取设备的 struct i2c_client *
应该以某种方式 linked 到这个 sysfs 条目,以及I2C地址在那里!
我应该如何正确地 "link" i2c_client 与 sysfs 条目,以便我可以在函数中获取 I2C 地址?
理想情况下,我希望只有一组函数(每个属性一个)。 sysfs 树应该是这样的:
/sysfs/kernel/tmp102
|
|-> <hex i2c address, e.g. /48>
| |
| |-> temperature
|
|
|-> /49
|
|-> temperature
我希望两个 'temperature' 属性使用相同的函数,它能够确定它应该写入的 I2C 地址。
或者我的架构完全错误?如果是这样,对于需要处理多个 i2c_client
的驱动程序来说应该是什么样子?
编辑:
我决定使用 struct device_attribute
而不是常规的 attribute
。据我了解,使用常规属性时,获取struct device
指针并不容易,struct i2c_client
也是如此。他们不容易 "linked" 和来自 /sys/kernel
的 kobject
s,我需要在这个项目中拥有我的属性。 device_attribute
s 可以在 /sys/devices
中找到 - 我使用了 sysfs_create_group
并且 link 使用 device_attribute
组编辑了我设备的 kobject
。我使用了 sysfs_create_link
,并且 link 使用 /sys/kernel/tmp102
编辑了我设备的 kobject
。这样我就可以为每个设备创建一个文件夹 (link),它指向 /sys/devices
中的原始属性文件夹。
首先,您应该知道已经有一个具有 sysfs 接口的 tmp102 内核驱动程序。看看 drivers/hwmon/tmp102.c.
现在,对于您的问题,您有一个 struct kobject
传递给您的 sysfs 回调。您可以调用 kobj_to_dev()
来获取指向设备的指针。然后,例如,您可以使用 dev_get_drvdata()
获取指向您自己的私有结构的指针,该结构将包含指向 i2c 客户端的指针。不要忘记先在您的探测器中使用 dev_set_drvdata()
进行设置。
您可以在 drivers/rtc/rtc-ds1343.c 中找到示例,但它使用的是 spi_driver。