device_create_file的使用

DEVICE_ATTR是一个宏,其定义在include/linux/device.h:

#define DEVICE_ATTR(_name, _mode, _show, _store) \
    struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

__ATTR宏定义在include/linux/sysfs.h:

#define __ATTR(_name,_mode,_show,_store) { \
    .attr = {.name = __stringify(_name), .mode = _mode },   \
    .show   = _show,                                        \
    .store  = _store,                                       \
}
struct device_attribute结构定义在include/linux/device.h:
/* interface for exporting device attributes */
struct device_attribute {
    struct attribute    attr;
    ssize_t (*show)(struct device *dev, struct device_attribute *attr,
            char *buf);
    ssize_t (*store)(struct device *dev, struct device_attribute *attr,
             const char *buf, size_t count);
};
DEVICE_ATTR宏展开:
#define DEVICE_ATTR(_name, _mode, _show, _store) \
    struct device_attribute dev_attr_##_name = { \
        .attr = {.name = __stringify(_name), .mode = _mode },   \
        .show   = _show,                                        \
        .store  = _store,                                       \
    }
举例说明DEVICE_ATTR使用方法:
static DEVICE_ATTR(msm_gpio, 0664, msmgpio_show, msmgpio_store);

static ssize_t msmgpio_show(struct device *dev,
                   struct device_attribute *attr, char *buf)
{
    int temp[5];
    struct gpio_data *gpio_data_ptr = dev_get_drvdata(dev);

    temp[0] = gpio_get_value(gpio_data_ptr->gpio0);
    temp[1] = gpio_get_value(gpio_data_ptr->gpio2);
    temp[2] = gpio_get_value(gpio_data_ptr->gpio3);
    temp[3] = gpio_get_value(gpio_data_ptr->gpio10);
    temp[4] = gpio_get_value(gpio_data_ptr->gpio11);

    return snprintf(buf, 6, "%d%d%d%d%d", temp[0], temp[1],
                    temp[2], temp[3], temp[4]);
}

static ssize_t msmgpio_store(struct device *dev,
           struct device_attribute *attr, const char *buf, size_t size)
{
    struct gpio_data *gpio_data_ptr = dev_get_drvdata(dev);

    gpio_set_value(gpio_data_ptr->gpio0,  (buf[0] == '1') ? 1 : 0);
    gpio_set_value(gpio_data_ptr->gpio2,  (buf[1] == '1') ? 1 : 0);
    gpio_set_value(gpio_data_ptr->gpio3,  (buf[2] == '1') ? 1 : 0);
    gpio_set_value(gpio_data_ptr->gpio10, (buf[3] == '1') ? 1 : 0);
    gpio_set_value(gpio_data_ptr->gpio11, (buf[4] == '1') ? 1 : 0);

    return size;
}

static DEVICE_ATTR(msm_gpio, 0664, msmgpio_show, msmgpio_store);

之后在驱动的probe函数中即可调用device_create_file:

err = device_create_file(&dev->dev, &dev_attr_msm_gpio);
if (err) {
        dev_err(&dev->dev, "sys file creation failed\n");
        return -ENODEV;
}
device_create_file和device_remove_file定义在drivers/base/core.c中,声明在include/linux/device.h中,device_create_file返回0代表创建成功。

int device_create_file(struct device *dev, const struct device_attribute *attr)
{
    int error = 0;

    if (dev) {
        WARN(((attr->attr.mode & S_IWUGO) && !attr->store),
            "Attribute %s: write permission without 'store'\n",
            attr->attr.name);
        WARN(((attr->attr.mode & S_IRUGO) && !attr->show),
            "Attribute %s: read permission without 'show'\n",
            attr->attr.name);
        error = sysfs_create_file(&dev->kobj, &attr->attr);
    }

    return error;
}

void device_remove_file(struct device *dev,
            const struct device_attribute *attr)
{
    if (dev)
        sysfs_remove_file(&dev->kobj, &attr->attr);
}
在文件系统/sys/devices/soc.0/gpio_ctrl.72下面生成msm_gpio节点,用cat,echo操作硬件:
root@msm8909:/sys/devices/soc.0/gpio_ctrl.72 # ls -l msm_gpio                  
-rw-rw-r-- root     root         4096 1970-01-01 00:02 msm_gpio
root@msm8909:/sys/devices/soc.0/gpio_ctrl.72 # cat msm_gpio
00000
root@msm8909:/sys/devices/soc.0/gpio_ctrl.72 # echo 11111 > msm_gpio

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值