`
ai_longyu
  • 浏览: 479745 次
社区版块
存档分类
最新评论

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

相信大家看到了这个头文件就差不多知道驱动是怎么写的了吧,我选用的是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函数:

这边最主要的应该就是temperature_device_driver这个变量这是一个platform_driver结构体,在驱动注册的时候必须把这个结构体传进去,我们的platform设备模型就是通过这个结构体找到相应的device,然后把driver和device绑定在一起,这边涉及到linux 设备驱动模型,这边我也不做详细的分析了,想要了解的话可以自己学习,个人觉得如果是做linux驱动的话了解linux 设备驱动模型是很重要的,这可以让我们站在一个比较高的层次上去写代码。

OK,不扯了看下这个结构体:

这边就是定义了probe和remove,真实的设备的话还有会suspend,resume,early_suspend,late_resume等回调函数,在适当的时间会回调到这些函数(犀利的读者可能看到了这边remove我没有去实现,哈哈,我比较懒,不过大家要有一个良好的习惯,不要学我)。但是在这边注册了platform的驱动,是去找哪的platform设备呢?当然是我们自己要去实现啦,通常device端我们都会在板级的文件中去定义,我们这里是:

/common/arch/arm/mach-goldfish/board-goldfish.c

大家注意。这边的name和driver中platform_driver中name用该一样,不然他们怎么可以绑定在一起呢,不然他们怎么会找到对方呢,有缘千里来相会嘛,对不?

OK,当我们的driver找到了device的时候会执行probe回调函数,也就是这里的temperature_probe函数,好,我们来看一下这个probe函数:

这边做的都是一些初始化的事情,我们这边首先给我们的机构体分配内存,然后给iio device分配空间,然后注册iio device,然后注册input_polled_device这里可以参考input)poll的源码,主要就是内嵌了一个工作队列来poll数据,这里不多说读者可以自行去分析。

这里最重要的有2点我提一下,首先就是我们poll数据的回调函数被挂在ddata->poll_input->poll=temperature_dev_poll;参考源码这个回调函数是什么时候被执行的呢,其实input_polled_dev还有几个回调函数,其中有一个open和close函数,当user space去open input下面的这个event的时候poll回调函数就会一直执行,时间间隔为我们定义的interval这个参数。还有一点就是iio 设备驱动上面挂的文件系统就是ddata->indio_dev->attrs = &temperature_attr_group;用法很简单吧,这边我只是注册了一个name的文件节点,user space可以去读写这个节点,一般我们写驱动的时候可以用这个文件节点来开关我们的设备。

OK,接下来就是一些事件的处理,看如下代码:


这里我们上报的数据就是这个tempValue,会每隔一段时间自增1,直到100再回到0,。

OK,驱动介绍完,接下来就可以把驱动编译进goldfish里面,然后运行模拟器,使用adb进入:

大家可以看到我这边cat出name就是自己写进去的那个名字,初步测试驱动ok接下来下一篇中给大家介绍下编译生成一个tool来测试驱动功能。








分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics