当前位置:操作系统 > 安卓/Android >>

Android模拟器学framework和driver之传感器篇1(linux sensor driver)

对于android模拟器开发环境的搭建这里我就不多说了,网上google下一大堆,还有就是android 模拟器的kernel使用的是goldfish的kernel,可以使用git得到源码,然后就可以编译了,大家还是可以参考罗老师的博客。。。
 
 
 
 
在这里我准备编写一个温度传感器的虚拟driver,之前写过g-sensor和light sensor,所以不想写了,换个新鲜的,其实驱动架构都是一样的,OK 分化不多说,下面就介绍一下这个驱动。
 
 
 
 
在这里,我比较偷懒的使用了linux的一个iio子系统,这是一个不成熟的子系统,所以被放到源码陌路下面的/drvers/staging中,对于这个子系统,我也只是粗略的看过它的驱动模型,好吧^0^,不过个人觉得这个子系统还是蛮简单使用的,而却里面的api不是很多,相信大家随便分析下就能搞懂了。
 
 
 
 
OK,首先是头文件
 
/common/drivers/staging/iio/temperature/android-temperature.h
 
 
[cpp] view plaincopyprint?#include <linux/module.h>  
#include <linux/platform_device.h>  
#include <linux/slab.h>  
#include <linux/input-polldev.h>  
#include "../iio.h"  
 
#define POLL_INTERVAL   2000    //set poll time  
 
struct temperature_drvdata { 
    struct iio_dev *indio_dev; 
    struct input_polled_dev *poll_input; 
    //....reserved  
}; 
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/input-polldev.h>
#include "../iio.h"
 
#define POLL_INTERVAL     2000       //set poll time
 
struct temperature_drvdata {
       struct iio_dev *indio_dev;
       struct input_polled_dev *poll_input;
       //....reserved
};
相信大家看到了这个头文件就差不多知道驱动是怎么写的了吧,我选用的是platform device driver,driver layer向user space传送数据时通过input sybsystem传送的,这也是android sensor驱动比较主流的做法,还有一些做法是直接往自己创建的sysfs中写数据,这也是一中比较简单的做法,事件的触控方式我选用的是poll方式,因为这里我写的驱动是一个虚拟的设备,一般出发方式会选用中断触发,而我这个驱动选择每隔一段时间往user space上报数据,时间间隔就是这里的POLL_INTERVAL这个宏设定的。
 
说了这么多都没有看到驱动的代码真不好意思,下面来分析下驱动的代码。
 
/common/drivers/staging/iio/temperature/android-temperature.c
 
 
首先是init和exit函数:
 
 
<span style="color:#cc33cc;"><strong>static int __init temperature_init(void) 

    printk(KERN_INFO "temperature init...\n"); 
    return platform_driver_register(&temperature_device_driver); 

 
static void __exit temperature_exit(void) 

    platform_driver_unregister(&temperature_device_driver); 

 
module_init(temperature_init); 
module_exit(temperature_exit);</strong></span> 
<span style="color:#cc33cc;"><strong>static int __init temperature_init(void)
{
       printk(KERN_INFO "temperature init...\n");
       return platform_driver_register(&temperature_device_driver);
}
 
static void __exit temperature_exit(void)
{
       platform_driver_unregister(&temperature_device_driver);
}
 
module_init(temperature_init);
module_exit(temperature_exit);</strong></span>这也没啥好说的,大家愿意的话可以再后面在添上这个driver module的作者和出处,传扬千里,哈哈,我就不了,本人比较谦虚。 
这也没啥好说的,大家愿意的话可以再后面在添上这个driver module的作者和出处,传扬千里,哈哈,我就不了,本人比较谦虚。这边最主要的应该就是temperature_device_driver这个变量这是一个platform_driver结构体,在驱动注册的时候必须把这个结构体传进去,我们的platform设备模型就是通过这个结构体找到相应的device,然后把driver和device绑定在一起,这边涉及到linux 设备驱动模型,这边我也不做详细的分析了,想要了解的话可以自己学习,个人觉得如果是做linux驱动的话了解linux 设备驱动模型是很重要的,这可以让我们站在一个比较高的层次上去写代码。
 
OK,不扯了看下这个结构体:
 
 
[cpp] view plaincopyprint?<span style="background-color: rgb(255, 255, 255);"><span style="color:#cc33cc;">static struct platform_driver temperature_device_driver = { 
    .probe      =   temperature_probe, 
//  .remove     =   __devexit_p(temperature_remove),  
    .driver     = { 
        .name = "android-temperature", 
        .owner= THIS_MODULE, 
    }, 
};</span></span> 
<span style="background-color: rgb(255, 255, 255);"><span style="color:#cc33cc;">static struct platform_driver temperature_device_driver = {
       .probe            =     temperature_probe,
//     .remove          =     __devexit_p(temperature_remove),
       .driver            = {
              .name = "android-temperature",
              .owner= THIS_MODULE,
       },
};</span></span>
这边就是定义了probe和remove,真实的设备的话还有会suspend,resume,early_suspend,late_resume等回调函数,在适当的时间会回调到这些函数(犀利的读者可能看到了这边remove我没有去实现,哈哈,我比较懒,不过大家要有一个良好的习惯,不要学我)。但是在这边注册了platform的驱动,是去找哪的platform设备呢?当然是我们自己要去实现啦,通常device端我们都会在板级的文件中去定义,我们这里是:
 
/common/arch/arm/mach-goldfish/board-goldfish.c
 
 
[cpp] view plaincopyprint?<strong><span style="color:#cc33cc;">struct platform_device android_temperature_device = { 
    .name="android-temperature", 
    .id=-1, 
}; 
</span></strong> 
static void __init goldfish_init(void) 

    platform_device_register(&goldfish_pdev_bus_device); 
<span style="color:#cc33cc;"><strong>   platform_device_register(&android_temperature_device);</strong></span> 

<strong><span style="color:#cc33cc;">struct platform_device android_temperature_device = {
       .name="android-temperature",
       .id=-1,
};
</span></strong>
static void __init goldfish_init(void)
{
   
补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,