1.[Linux Driver Misc]-(DEVICE_ATTR demo与理解)

__ATTR填充结构体:kernel-4.9/include/linux/sysfs.h

#define __ATTR(_name, _mode, _show, _store) {				\
	.attr = {.name = __stringify(_name),				\
		 .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },		\
	.show	= _show,						\
	.store	= _store,						\
}

DEVICE_ATTR定义并初始化结构体:kernel-4.9/include/linux/device.h

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

DEVICE_ATTR定义的结构体:kernel-4.9/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_create_file创建文件节点,最终调用的还是sysfs_create_file(用于创建一个节点):
:drivers/base/core.c

/**
 * device_create_file - create sysfs attribute file for device.
 * @dev: device.
 * @attr: device attribute descriptor.
 */
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;
}
EXPORT_SYMBOL_GPL(device_create_file);

sysfs_create_files第二个参数是一个二维数组,所以可以创建多个节点:
:fs/sysfs/file.c

int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
{
	int err = 0;
	int i;

	for (i = 0; ptr[i] && !err; i++)
		err = sysfs_create_file(kobj, ptr[i]);
	if (err)
		while (--i >= 0)
			sysfs_remove_file(kobj, ptr[i]);
	return err;
}
EXPORT_SYMBOL_GPL(sysfs_create_files);

kernel4.9下面有中文注册的文档

./Documentation/zh_CN/filesystems/sysfs.txt`

一个demo:只用于参考:

//debug part
static ssize_t fs_demo_show(struct device* cd,
                      struct device_attribute *attr, char* buf)
{
        int len = 0;
	len += snprintf(buf+len, PAGE_SIZE-len, "useg: only a attr fs demo show\n");
	return len;
}

static ssize_t fs_demo_store(struct device* cd,
                   struct device_attribute *attr,const char* buf, size_t len)
{
       int databuf[2];
	if(2 == sscanf(buf,"%d %d",&databuf[0], &databuf[1])){

              unsigned char cmd_tmp[2] = {(unsigned char)databuf[0],0};
              ....
	}
	return len;
}
static DEVICE_ATTR(fs_demo, 0664, fs_demo_show,  fs_demo_store);

//dev_attr_#name;

static int fs_demo_probe(struct platform_devvice *dev)
{
        int device_create_file(struct device *device,
                   const struct device_attribute *entry); //在fs_demo前面加上dev_attr_合并成dev_attr_fs_demo
                                                           //&dev_attr_fs_demo就是entry
}

猜你喜欢

转载自blog.csdn.net/qq_16919359/article/details/102524353