Linux驱动学习 —— 在/sys下面创建目录示例

Posted 摩斯电码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux驱动学习 —— 在/sys下面创建目录示例相关的知识,希望对你有一定的参考价值。

有时我们需要在/sys下面创建一些目录, 下面给出了一个示例。 在加载驱动模块后, 在/sys下面会创建一个名为sysfs_demo的目录,并在其中在创建几个文件和目录。

[[email protected] mnt]# ls -R /sys/sysfs_demo/
/sys/sysfs_demo/:
node_one      node_two      sysfs_demo_2

/sys/sysfs_demo/sysfs_demo_2:
node_four   node_three

这里用到的两个函数分别是: kobject_create_and_add 和 sysfs_create_group。前一个函数用于在/sys下面创建目录, 后一个函数用于创建文件。

示例驱动:

  1 #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
  2 
  3 #include <linux/init.h>
  4 #include <linux/module.h>
  5 #include <linux/kobject.h>
  6 #include <linux/device.h>
  7 
  8 static struct kobject *k_obj = NULL;
  9 static struct kobject *k_obj_2 = NULL;
 10 
 11 static char node_one_buf[20] = {0};
 12 
 13 static ssize_t sysfs_demo_show_node_one(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
 14 {
 15     pr_info("enter, node: %s\n", attr->attr.name);
 16     return sprintf(buf, "%s: %s\n", attr->attr.name, node_one_buf);
 17 }
 18 
 19 static ssize_t sysfs_demo_store_node_one(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
 20 {
 21     pr_info("enter, node: %s\n", attr->attr.name);
 22 
 23     sprintf(node_one_buf, "%s", buf);
 24 
 25     return n;
 26 }
 27 
 28 static struct kobj_attribute node_one_attribute =
 29     __ATTR(node_one, S_IWUSR|S_IRUGO, sysfs_demo_show_node_one, sysfs_demo_store_node_one);
 30 
 31 static ssize_t sysfs_demo_show_node_two(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
 32 {
 33 
 34     return sprintf(buf, "%s\n", attr->attr.name);
 35 }
 36 
 37 static struct kobj_attribute node_two_attribute =
 38     __ATTR(node_two, S_IWUSR|S_IRUGO, sysfs_demo_show_node_two, NULL);
 39 
 40 static struct attribute *sysfs_demo_attributes[] = {
 41     &node_one_attribute.attr,
 42     &node_two_attribute.attr,
 43     NULL
 44 };
 45 
 46 static const struct attribute_group sysfs_demo_attr_group = {
 47     .attrs = sysfs_demo_attributes,
 48 };
 49 
 50 static char node_three_buf[20] = {0};
 51 
 52 static ssize_t sysfs_demo_show_node_three(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
 53 {
 54     pr_info("enter, node: %s\n", attr->attr.name);
 55     return sprintf(buf, "%s: %s\n", attr->attr.name, node_three_buf);
 56 }
 57 
 58 static ssize_t sysfs_demo_store_node_three(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
 59 {
 60     pr_info("enter, node: %s\n", attr->attr.name);
 61 
 62     sprintf(node_three_buf, "%s", buf);
 63 
 64     return n;
 65 }
 66 
 67 static struct kobj_attribute node_three_attribute =
 68     __ATTR(node_three, S_IWUSR|S_IRUGO, sysfs_demo_show_node_three, sysfs_demo_store_node_three);
 69 
 70 static ssize_t sysfs_demo_show_node_four(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
 71 {
 72 
 73     return sprintf(buf, "%s\n", attr->attr.name);
 74 }
 75 
 76 static struct kobj_attribute node_four_attribute =
 77     __ATTR(node_four, S_IWUSR|S_IRUGO, sysfs_demo_show_node_four, NULL);
 78 
 79 static struct attribute *sysfs_demo2_attributes[] = {
 80     &node_three_attribute.attr,
 81     &node_four_attribute.attr,
 82     NULL
 83 };
 84 
 85 static const struct attribute_group sysfs_demo2_attr_group = {
 86     .attrs = sysfs_demo2_attributes,
 87 };
 88 
 89 static int __init sysfs_demo_init(void)
 90 {
 91     if ((k_obj = kobject_create_and_add("sysfs_demo", NULL)) == NULL ) {
 92         pr_err("sysfs_demo sys node create error \n");
 93         goto out;
 94     }
 95 
 96     if(sysfs_create_group(k_obj, &sysfs_demo_attr_group) ) {
 97         pr_err("sysfs_create_group failed\n");
 98         goto out2;
 99     }
100 
101     if ((k_obj_2 = kobject_create_and_add("sysfs_demo_2", k_obj)) == NULL ) {
102         pr_err("hwinfo sys node create error \n");
103         goto out3;
104     }
105 
106     if(sysfs_create_group(k_obj_2, &sysfs_demo2_attr_group) ) {
107         pr_err("sysfs_create_group failed\n");
108         goto out4;
109     }
110 
111     pr_info("enter.\n");
112     return 0;
113 out4:
114     kobject_put(k_obj_2);
115 out3:
116     sysfs_remove_group(k_obj, &sysfs_demo_attr_group);
117 out2:
118     kobject_put(k_obj);
119 out:
120     return -1;
121 }
122 module_init(sysfs_demo_init);
123 
124 static void __exit sysfs_demo_exit(void)
125 {
126     pr_info("enter.\n");
127 
128     if (k_obj) {
129         sysfs_remove_group(k_obj, &sysfs_demo_attr_group);
130         if (k_obj_2) {
131             sysfs_remove_group(k_obj_2, &sysfs_demo2_attr_group);
132             kobject_put(k_obj_2);
133         }
134         kobject_put(k_obj);
135     }
136 
137 }
138 module_exit(sysfs_demo_exit);
139 
140 MODULE_LICENSE("GPL");

 

以上是关于Linux驱动学习 —— 在/sys下面创建目录示例的主要内容,如果未能解决你的问题,请参考以下文章

linux设备驱动(11) dev sys/dev sys/devices的区别

鼠标驱动之-sys节点-input子系统

Linux嵌入式驱动学习之路按键驱动-poll机制

《驱动学习 - 虚拟网卡驱动》

Linux虚拟Pinctrl Demo驱动 -- Debug FS之Pinctrl分析

Linux虚拟Pinctrl Demo驱动 -- Debug FS之Pinctrl分析