用户空间与内核空间的接口:sysfs

在调试驱动,或驱动涉及一些参数的输入输出时,难免需要对驱动里的某些变量或内核参数进行读写,或函数调用。此时sysfs接口就很有用了,它可以使得可以在用户空间直接对驱动的这些变量读写或调用驱动的某些函数。sysfs接口与proc文件系统很相似,有人将proc文件系统形容为Windows XP,而将sysfs接口形容为Windows 7。

而在Android系统中,振动器、背光、电源系统等往往使用sysfs接口作为内核空间和用户空间的接口,驱动程序需要提供这些接口内容。

上一个例程:

[cpp]  view plain copy
  1. #include <linux/module.h>  
  2. #include <linux/types.h>  
  3. #include <linux/kobject.h>  
  4. static ssize_t sysfs_read(struct kobject *kobj, struct kobj_attribute *attr, char *buf)  
  5. {  
  6.     return sprintf(buf, "%s\n""sysfs test read,created by vincent");  
  7. }  
  8. static ssize_t sysfs_write(struct kobject *kobj, struct kobj_attribute *attr, const char *buf,ssize_t  count)  
  9. {  
  10.     int i;  
  11.     printk("\nfrom user,length=0x%X,content=%s\n",count,buf);  
  12.     if(count)  
  13.         return count;  
  14.     else  
  15.         return 1 ;  
  16. }  
  17.   
  18. static struct kobj_attribute my_sysfs_read =__ATTR(read, S_IRUGO, sysfs_read, NULL);  
  19. static struct kobj_attribute my_sysfs_write =__ATTR(write, S_IWUGO, NULL,sysfs_write);  
  20.   
  21. static struct attribute *my_sysfs_test[] = {  
  22.     &my_sysfs_read.attr,  
  23.     &my_sysfs_write.attr,  
  24.     NULL,  
  25. };  
  26. static struct attribute_group my_attr_group = {  
  27.     .attrs = my_sysfs_test,  
  28. };  
  29.   
  30. static int sysfs_status = 0 ;  
  31. struct kobject *soc_kobj = NULL;  
  32. int helloworld_init(void)  
  33. {  
  34.     int ret = 0;  
  35.     printk("\nHello Android driver : %s\n",__func__);  
  36.     printk("Compile Driver Via eclipse IDE: %s\n",__func__);  
  37.   
  38.     soc_kobj = kobject_create_and_add("my_sysfs_test", NULL);  
  39.     if (!soc_kobj)  
  40.         goto err_board_obj;  
  41.   
  42.     ret = sysfs_create_group(soc_kobj, &my_attr_group);  
  43.     if (ret)  
  44.         goto err_soc_sysfs_create;  
  45.     sysfs_status = 1;  
  46.     /* init func must contain a return vaule,otherwise meet warning when insmod this module */  
  47.     return 0;  
  48.   
  49.     sysfs_status = 0;  
  50. err_soc_sysfs_create:  
  51.     kobject_put(soc_kobj);  
  52.     sysfs_remove_group(soc_kobj, &my_attr_group);  
  53.     printk("\nsysfs_create_group ERROR : %s\n",__func__);  
  54.     return 0;  
  55. err_board_obj:  
  56.     printk("\nobject_create_and_add ERROR : %s\n",__func__);  
  57.     return 0;  
  58. }  
  59. void helloworld_exit(void)  
  60. {  
  61.     printk("\nExit Android driver : %s\n",__func__);  
  62.     printk("Compile Driver Via eclipse IDE: %s\n",__func__);  
  63.   
  64.     if(sysfs_status == 1)  
  65.     {  
  66.         sysfs_status = 0;  
  67.         kobject_put(soc_kobj);  
  68.         sysfs_remove_group(soc_kobj, &my_attr_group);  
  69.     }  
  70. }  
  71. MODULE_AUTHOR("vincent wu");  
  72. MODULE_LICENSE("Dual BSD/GPL");  
  73. module_init(helloworld_init);  
  74. module_exit(helloworld_exit);  
在定义sysfs接口属性时,各个命名字符要一致,看以下颜色标注:

static struct kobj_attribute my_sysfs_read =__ATTR(read, S_IRUGO, sysfs_read, NULL);

static struct kobj_attribute my_sysfs_write =__ATTR(write, S_IWUGO, NULL,sysfs_write);

static struct attribute *my_sysfs_test[] = {
 &my_sysfs_read.attr,
 &my_sysfs_write.attr,
 NULL,
};

使用:

1.编译,insmod 驱动。

2.cd /sys ,发现多了一个创建的"my_sysfs_test"目录。

3.cd my_sysfs_test,发现多了两个创建的"read","write"目录。

4.cat read ,控制台输出"sysfs test read,created by vincent",这里实际会调用上面的sysfs_read函数。

5.echo hi sysfs > write ,这里实际会调用上面的sysfs_write函数输出。


另外还有其他方法定义sysfs接口,常见到就是以下宏:

#define DEVICE_ATTR(_name, _mode, _show, _store) \

struct device_attributedev_attr_##_name = __ATTR(_name, _mode, _show, _store)

示例:

static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);

注意,在使用以上宏定义一个sysfs接口时,已经由宏定义了接口属性名字的前缀为“dev_attr_",所以在定义属性结构体时,要使用一样的名字字符,如下所示:

static struct attribute *my_sysfs_test[] = {
 &dev_attr_XXX.attr,
 &dev_attr_YYY.attr,
 NULL,
};
”XXX"与“YYY”和“_name"一致。

由此可见,通过上面的方式可以方便定制属性名字,而使用宏DEVICE_ATTR则受约束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值