create_sys

linux设备驱动注册sys文件访问

device_create_file 在当前设备的sys目录下创建一个属性对应的文件。

设备属性文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);
};

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

定义一个device_attribute类型的变量,##代表将两边的名字拼接起来,因此,我们得到的变量名称是含有dev_attr的,该宏定义需要 传入四个参数,name,mode,show,store分别代表文件名,文件权限,show回调函数(cat 节点),store回调函数(echo 节 点),参数mode,可以用宏(S_IRUSR、S_IWUSR、S_IXUSR等等)来定义,表示读写权限。

extern int device_create_file(struct device *device,
const struct device_attribute *entry);
extern void device_remove_file(struct device *dev,
const struct device_attribute *attr);

device表示设备,其成员中有个bus_type变量,用于指定设备挂载在某个总线上,并且会在总线的devices目录下创建一个属于该设备的目录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#用于在sys文件系统中创建一个设备属性

#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>

static ssize_t my_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) {
return sprintf(buf, "Hello, world!\n");
}

static ssize_t my_sysfs_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) {
// 处理写入的数据
return count;
}

static DEVICE_ATTR(my_sysfs_file, 0664, my_sysfs_show, my_sysfs_store);

static int __init my_driver_init(void) {
struct device *dev = /* 获取设备指针 */;
int retval;

retval = device_create_file(dev, &dev_attr_my_sysfs_file);
if (retval) {
printk(KERN_ERR "Failed to create sysfs file\n");
return retval;
}

printk(KERN_INFO "Sysfs file created\n");
return 0;

}

static void __exit my_driver_exit(void) {
struct device *dev = /* 获取设备指针 */;
device_remove_file(dev, &dev_attr_my_sysfs_file);
printk(KERN_INFO "Sysfs file removed\n");
}

module_init(my_driver_init);
module_exit(my_driver_exit);

MODULE_LICENSE("GPL");