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\n");
        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\n",
             err);
        goto fail3;
        }
 fail3: return -1;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM