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


    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     else
    101     {
    102 #ifdef USE_MOTOR_8997
    103         motor8997_on(0);
    104 #else
    105         VIB_STOP;
    106 #endif
    107     }
    108     return retval;
    109 }
    110 
    111 /*
    112  * sysfs: /sys/devices/platform/s5p-vib
    113  * usage: echo ms > /sys/devices/platform/s5p-vib/vib
    114  */
    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_TEST
    130 #ifdef USE_MOTOR_8997
    131     motor8997_on(1);
    132 #else
    133     VIB_START;
    134 #endif
    135     schedule_delayed_work(&vib_delayed_work, msecs_to_jiffies(1000));
    136 #endif
    137     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_PM
    152 static int s3c_vib_suspend(struct platform_device *pdev, pm_message_t state)
    153 {
    154 #ifdef USE_MOTOR_8997
    155     motor8997_on(0);
    156 #else
    157     VIB_STOP;
    158 #endif
    159     return 0;
    160 }
    161 
    162 static int s3c_vib_resume(struct platform_device *pdev)
    163 {
    164     return 0;
    165 }
    166 #else
    167 #define s3c_vib_suspend NULL
    168 #define s3c_vib_resume  NULL
    169 #endif
    170 
    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);

    按照这个接口 我们可以操作寄存器,可以调试流驱动

  • 相关阅读:
    HDU3068 最长回文
    本周最后一天——4.18
    一周又结束了——4.14
    一本通1591:数字计数
    一本通1589:不要 62
    一本通1588:数字游戏
    洛谷P2657 [SCOI2009] windy 数
    一本通1587: 【例 3】Windy 数
    一本通1586:【 例 2】数字游戏
    安卓自动化测试(一)
  • 原文地址:https://www.cnblogs.com/heimi/p/2994127.html
Copyright © 2020-2023  润新知