device_create_file的使用

来源:互联网 发布:数据库大数据区别 编辑:程序博客网 时间:2024/06/05 23:58

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

0 0
原创粉丝点击