具有多个设备属性的Linux驱动程序链接到相同的功能

时间:2014-09-12 09:31:56

标签: c linux linux-kernel linux-device-driver

我正在编写一个具有多个设备属性的简单Linux驱动程序。现在独立于您读取或写入的属性,最后您将在设备的内存中读取或写入某个位置。只有定义精确位置的偏移量才会从一个属性变为另一个属性。使用几行代码可以更容易地解释这一点:

/* General read function evoked by attributes */
static const ssize_t foo_show(struct device *dev,
    struct device_attribute *attr, char *buf)
{
    u32 offset;

    if (attr->attr.name == "control")
        offset = OFFSET_CTRL;
    else if (attr->attr.name == "status")
        offset = OFFSET_STATUS;

    u32 data = ioread32(dev_mem + offset);
    ...
}

...

/* declaring attributes, all linking to the same function */
static DEVICE_ATTR(control, S_IWUGO | S_IRUGO, foo_show, foo_set);
static DEVICE_ATTR(status, S_IRUGO, foo_show, NULL);

现在你可能猜测使用attr->attr.name == foo并不是一个很好的方法,特别是因为我得到了警告"与字符串文字的比较导致了未指明的行为" telling me使用strcmp。您是否知道更好的方法来确定哪个属性负责呼叫?

2 个答案:

答案 0 :(得分:3)

在现有驱动程序中这样做的方法是直接与全局属性进行比较。

static DEVICE_ATTR(control, S_IWUGO | S_IRUGO, foo_show, foo_set);
static DEVICE_ATTR(status, S_IRUGO, foo_show, NULL);

static const ssize_t foo_show(struct device *dev,
    struct device_attribute *attr, char *buf)
{
    u32 offset;

    if (attr == &dev_attr_control)
        offset = OFFSET_CTRL;
    else if (attr == &dev_attr_status)
        offset = OFFSET_STATUS;

答案 1 :(得分:1)

只能根据名称识别属性。由于默认情况下attribute中只有两个字段可用。 http://lxr.free-electrons.com/source/include/linux/sysfs.h#L29

可以使用strcmp()的内核空间实现。所以使用它会有效。 http://lxr.free-electrons.com/source/lib/string.c#L245