LINUX内核 DEVICE_ATTR与cat echo命令 直接读写调用Kernel测试方法

来源:互联网 发布:剑灵捏脸数据下载 编辑:程序博客网 时间:2024/05/16 09:34


sysfs接口函数的建立_DEVICE_ATTR  【转】

出自:http://blog.csdn.net/manshq163com/article/details/7848714

2012-05-09 11:36:46|  分类:linux文件系统 |  标签:device_attr  sysfs接口函数  |字号 订阅

 
 

说道sysfs接口,就不得不提到函数宏 DEVICE_ATTR,原型是

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

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

函数宏DEVICE_ATTR内封装的是__ATTR(_name,_mode,_show,_stroe)方法

_show:表示的是读方法,

_stroe表示的是写方法。

 

当然_ATTR不是独生子女,他还有一系列的姊妹__ATTR_RO宏只有读方法,__ATTR_NULL等等

如对设备的使用        DEVICE_ATTR   

对驱动使用               DRIVER_ATTR

对总线使用               BUS_ATTR 

对类别 (class) 使用  CLASS_ATTR

这四个高级的宏来自于<include/linux/device.h> 

DEVICE_ATTR  宏声明有四个参数,分别是名称、权限位、读函数、写函数。其中读函数和写函数是读写功能函数的函数名。

如果你完成了DEVICE_ATTR函数宏的填充,下面就需要创建接口了

例如:

    static DEVICE_ATTR(polling, S_IRUGO | S_IWUSR, show_polling, set_polling);
    static struct attribute *dev_attrs[] = {
            &dev_attr_polling.attr,
            NULL,
    };

当你想要实现的接口名字是polling的时候,需要实现结构体struct attribute *dev_attrs[]

其中成员变量的名字必须是&dev_attr_polling.attr

然后再封装

    static struct attribute_group dev_attr_grp = {
            .attrs = dev_attrs,
    };

在利用sysfs_create_group(&pdev->dev.kobj, &dev_attr_grp);创建接口

       通过以上简单的三个步骤,就可以在adb shell 终端查看到接口了。当我们将数据 echo 到接口中时,在上层实际上完成了一次 write 操作,对应到 kernel ,调用了驱动中的 “store”。同理,当我们cat 一个 接口时则会调用 “show” 。到这里,只是简单的建立了 android 层到 kernel 的桥梁,真正实现对硬件操作的,还是在 "show" 和 "store" 中完成的。

 

       其实呢?!用个proc文件系统的就知道,这个就和proc中的write和read一样的,以我的理解:proc有点老了,以后肯定会大量使用attribute,proc好比是Windows XP,attribute就像是Windows Seven
 
 
 
 
/****************************************下面是内核驱动例子  这样就比较清晰了****************/
复制代码
  1 #include <linux/io.h>  2 #include <linux/gpio.h>  3 #include <plat/gpio-cfg.h>  4 #include <mach/regs-gpio.h>  5 #include <linux/module.h>  6 #include <linux/delay.h>  7 #include <linux/platform_device.h>  8 #include <linux/workqueue.h>  9  10 //#include <mach/gpio-v8.h> 11  12 /* Variables */ 13 static struct delayed_work vib_delayed_work; 14  15 /* Definitions */ 16 #define VIB_TEST    0 17  18 #define GPIO_VIBCTL        EXYNOS4_GPD0(0) 19  20 #define CFG_VIB_CTRL    do {\ 21     gpio_request(GPIO_VIBCTL, "MOTOR_PWM");\ 22     s3c_gpio_cfgpin(GPIO_VIBCTL,S3C_GPIO_OUTPUT);\ 23     s3c_gpio_setpull(GPIO_VIBCTL,S3C_GPIO_PULL_NONE);\ 24 } while(0) 25  26 #define VIB_START do {\ 27     gpio_set_value(GPIO_VIBCTL, 1);\ 28 } while(0) 29  30 #define VIB_STOP do {\ 31     gpio_set_value(GPIO_VIBCTL, 0);\ 32 } while(0) 33  34 #define RELEASE_VIB do {\ 35     gpio_free(GPIO_VIBCTL);\ 36 } while(0) 37  38 #ifndef CONFIG_TC4_DVT 39  #define USE_MOTOR_8997 40 #else 41  #undef USE_MOTOR_8997 42 #endif 43  44 #ifdef USE_MOTOR_8997 45 extern void motor8997_on(int on); 46 #endif 47  48 /* Functions */ 49 static void vib_delayed_work_func(struct work_struct *work) 50 { 51 #ifdef USE_MOTOR_8997 52     motor8997_on(0); 53 #else 54     VIB_STOP; 55 #endif 56 } 57  58 int strtoint(const char *str,int len) 59 { 60     int result = 0; 61     int i = 0; 62     char c; 63     while(i <= len-1) 64     {    65         c = str[i++]; 66         if(c<'0' || c>'9') 67             break; 68         result = 10*result + c - '0'; 69     } 70     return result; 71 } 72  73 static ssize_t vib_show(struct device *dev, 74         struct device_attribute *attr, char *buf) 75 { 76     return printk("write a number in to vibrate\n"); 77 } 78  79 static ssize_t vib_store(struct device *dev, 80         struct device_attribute *attr, 81         const char *buf, size_t count) 82 { 83     int retval; 84     int value; 85     value = strtoint(buf,count); 86 #if VIB_TEST 87     printk("count:%d, buf:%s",count,buf); 88     printk("inv:%d ms\n",value); 89 #endif 90     retval = count; 91     if(value) 92     { 93 #ifdef USE_MOTOR_8997 94         motor8997_on(1); 95 #else 96         VIB_START; 97 #endif 98         schedule_delayed_work(&vib_delayed_work, msecs_to_jiffies(value)); 99     }100     else101     {102 #ifdef USE_MOTOR_8997103         motor8997_on(0);104 #else105         VIB_STOP;106 #endif107     }108     return retval;109 }110 111 /*112  * sysfs: /sys/devices/platform/s5p-vib113  * usage: echo ms > /sys/devices/platform/s5p-vib/vib114  */115 static DEVICE_ATTR(vib, S_IRUGO | S_IWUSR, vib_show, vib_store);116 117 static int __devinit s3c_vib_probe(struct platform_device *pdev)118 {119     int err;120     err = device_create_file(&pdev->dev, &dev_attr_vib);121     if (err)122         goto error1;123 124     /* delayed work */125     INIT_DELAYED_WORK(&vib_delayed_work, vib_delayed_work_func);126 127     CFG_VIB_CTRL;128 129 #if VIB_TEST130 #ifdef USE_MOTOR_8997131     motor8997_on(1);132 #else133     VIB_START;134 #endif135     schedule_delayed_work(&vib_delayed_work, msecs_to_jiffies(1000));136 #endif137     printk("vibrator probe success\n");138 139     return 0;140 141 error1:142     return err;143 }144 145 static int __devexit s3c_vib_remove(struct platform_device *dev)146 {147     RELEASE_VIB;148     return 0;149 }150 151 #ifdef CONFIG_PM152 static int s3c_vib_suspend(struct platform_device *pdev, pm_message_t state)153 {154 #ifdef USE_MOTOR_8997155     motor8997_on(0);156 #else157     VIB_STOP;158 #endif159     return 0;160 }161 162 static int s3c_vib_resume(struct platform_device *pdev)163 {164     return 0;165 }166 #else167 #define s3c_vib_suspend NULL168 #define s3c_vib_resume  NULL169 #endif170 171 static struct platform_driver s5p_vib_driver = {172     .probe        = s3c_vib_probe,173     .remove        = __devexit_p(s3c_vib_remove),174     .suspend    = s3c_vib_suspend,175     .resume        = s3c_vib_resume,176     .driver        = {177         .name    = "s5p-vib",178         .owner    = THIS_MODULE,179     },180 };181 182 static char __initdata banner[] = "S5P VIBRATOR\n";183 184 static int __init s3c_vib_init(void)185 {186     printk(banner);187     return platform_driver_register(&s5p_vib_driver);188 }189 190 static void __exit s3c_vib_exit(void)191 {192     printk("%s()\n",__FUNCTION__);193     platform_driver_unregister(&s5p_vib_driver);194 }195 196 module_init(s3c_vib_init);197 module_exit(s3c_vib_exit);
0 0