• DEVICE_ATTR设置设备属性


    DEVICE_ATTR设置设备属性

    为了在sysfs下生成可控节点,方便上层调用。

    sysfs是一个基于RAM的文件系统,它和Kobject一起,可以将Kernel的数据结构导出到用户空间,以文件目录结构的形式,提供对这些数据结构(以及数据结构的属性)的访问支持。Linux设备模型(4)_sysfs

    原型:

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

    类似的还有DRIVER_ATTRBUS_ATTRCLASS_ATTR区别就是,DEVICE_ATTR对应的文件在/sys/devices/目录中对应的device下面。而其他几个分别在driverbusclass中对应的目录下。(待确认)

    我实际测试,用DEVICE_ATTR增加的I2C设备,节点是在/sys/bus/i2c/devices/0-0060/fm1288/下的。按照上面的说法,应该fm1288节点应该是在/sys/device

    用法:

    static ssize_t fm1288_store(struct device *dev,
                      struct device_attribute *attr,
                      const char *buf, size_t count)
    {
      struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
      unsigned int reg = 0, write = 0;
        __u16 val = 0;
        int ret;
    ​
        sscanf(buf,"%x %x %x", &write, &reg, (unsigned int *)&val);//用sscanf读取sysfs写入的值 echo "1 2 3" > fm1288_mode
        fm2018_write(i2c, reg, val);
        fm2018_read(i2c, reg, &val);
    }
    ​
    fm1288_showstatic ssize_t fm1288_show(struct device *dev,
                      struct device_attribute *attr,
                      const char *buf, size_t count)
    {
        //read mode 
        ssprintf("%d", mode);
    }
    ​
    static DEVICE_ATTR(fm1288, S_IWUSR,//模式可以只读0444,只写0222,或者读写都行0666
                fm1288_show, //NULL,不需要该函数可以写NULL
                fm1288_store);
    //注意_show和_store的命名一般习惯都是来自name+ _show / _store
    static int fm2018_i2c_probe(struct i2c_client *i2c,
                                const struct i2c_device_id *id)
    {
        struct device *dev = &i2c->dev;
        ret = device_create_file(&i2c->dev, &dev_attr_register);
        if (ret) {
            dev_err(&i2c->dev, "failed to create sysfs files
    ");
            return ret;
        }
    }
    ​

    也可以写多个属性,这时,使用sysfs_create_group注册就很方便,代替device_create_file

    static DEVICE_ATTR(xtilt,
               S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt);
    static DEVICE_ATTR(ytilt,
               S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt);
    ​
    static struct attribute *aiptek_attributes[] = {
        &dev_attr_xtilt.attr,//名字 dev_attr_name.attr
        &dev_attr_ytilt.attr,
        NULL
    };
    ​
    static struct attribute_group aiptek_attribute_group = {
        .attrs  = aiptek_attributes,
    };
    ​
    aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
    {
        int err = -ENOMEM;
        err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
        if (err) {
            dev_warn(&intf->dev, "cannot create sysfs group err: %d
    ",
                 err);
            goto fail3;
            }
     fail3: return -1;
    }
  • 相关阅读:
    发布国内首个无服务器容器服务,运维效率从未如此高效
    阿里云异构计算团队亮相英伟达2018 GTC大会
    阿里如何将“高峰前扩容、高峰后缩容”的梦想照进现实?
    迁移到 GRUB 2
    (11计科1班-孙鹏启)SHELL脚本—期末成绩统计
    硬盘分区的c盘在外圈还是内圈
    Linux内核设计的艺术(第2版)
    卸载,弹出,安全移除驱动器 的区别
    (11级计科2班-张文旭)关于LINUX连接网络问题
    安装Zend Guard Loader
  • 原文地址:https://www.cnblogs.com/feixiao5566/p/11061939.html
Copyright © 2020-2023  润新知