Android世界:孤独的开始

来源:互联网 发布:java架构师证书 编辑:程序博客网 时间:2024/06/11 07:36

    最近的一幕幕闹剧,让我开始对周围的世界失望了。

    每个人对事情都有自己的看法,但当他们把所有的看法都集中到一个人身上时,你就会发现,你自己的力量是多么的薄弱:不能阻挡,不能改变,又不想顺从。在这个多维的宇宙里,似乎没有什么东西是按照一个人的意愿来形成的,包括构成一个人的每一个原子,脑子里形成的每一个想法,就算我想写的这篇文章,也是一开始就注定它是要存在的。

    这世界唯一能依靠的,只有自己的双手,想办法让自己过的好一点...

    6月过了一半了,回头看看这半年的工作,大概只有十天是对项目里的兄弟做了有意义的帮助,其它只是在学习,不过还好,浪费的时间也曲指可数,大致集中在PMP,UML,流媒体协议与实现方面,但能发挥创造性的地方不多,只是按部就班的实现就可以了。对Android的研究是最近才开始的,一个很不错的开始:没人关注,没有目的,没有支持,只有一块机顶盒板子,一个无名的触摸屏,一份平台的SDK和一个对Android一点都不了解的程序员。

    本着没有困难,创造困难也要上的原则,我给这款“产品”做了如下的定义:支持触摸屏的机顶盒。是的,就这么简单,安卓的程序员看了会笑。人家的平台这些都是现成的,最不济,还可以在模拟器上跑,你这是个啥米东西?是的,这个东西就是个垃圾,我要做的,就是看看这个垃圾里有没有值得学习的东西。

    介绍一个我的环境:板子是一个卡拉OK的产品,有HDMI输出、VGA输出,一个以太网口,俩路USB,俩路UART串口;触摸屏是VGA输入,触摸数据通过串口回传;Linux是2.6.37,Android是4.0.1;开发环境是Ubuntu 10.04 64位。其实平台的SDK已经提供了所有的移植,只是不支持VGA输出和我这个不知名的触摸屏的驱动。

    好了,开始吧:

    1、编译

    上来就遇到个最痛苦的事情,这个SDK版本编译的时间太长了:在我这个賽揚双核上,编译一遍要大概半天的时间,驱动部分还好说,C或者C++的代码,似乎还是正常的按Makefile来做,但java部分,不知为什么,每次都要重新打包那些apk,看着那些个慢吞吞的javac,不知所措。被逼无奈,查找了一下我要修改的代码,发现这部分是使用so的方式动态加载,于是通过make -p -n把编译这部分的编译命令抓出来,做成脚本,手动执行,把编译好的so拷贝到根文件系统中,大大提高的我的调试速度。

    2、VGA输出

    平台默认支持3种输出:HDMI、YPbPr(or VGA)、CVBS,VGA的RGB信号与YPbPr共用3路DAC,而且我了解的大多数平台都是复用这3路DAC,因此我要在初始化时告诉平台将色差信号转为RGB输出。通过grep大神的帮助,很快找到了相关的代码,也就是某个so的源文件,通过使用上面的“技巧”,使CPU成功输出RGB信号。但这只是开始,这个平台的VGA行场同步信号是夹在G信号中输出的,对于不支持绿同步的VGA设备,还要将行场同步信号分离出来。我这个板子上已经带了分离同步信号的电路,只是要启用这部分集成电路的功能就可以了,其中涉及到CPU管脚的复用,GPIO的Pull/Push操作,都是平台相关的,使用具体的API即可。

    3、触摸事件

    对于Linux下的用户输入,我只有一点使用uinput的经验:打开kernel的uinput的支持,加载驱动后,在/dev下就会有uinput这个设备,我们按照规则把事件在用户空间注入即可。最初我也是这么设想的,但在Android下,用户程序都是java,似乎要配合jni来操作uinput,而使事件输入在每个程序下都有效,可能得搞个什么后台程序,这大大超出了我预计的工作量,因此经过考虑,决定采用串口中断+linux input系统的方式来注入事件,而且事实证明这才是唯一正确的方式(开始还以为自己是什么天才,后来才发现,input驱动下的串口触摸屏都是这么做的...)。串口中断不用多说,都是平台相关的:注册相应的中断服务,设置波特率、bit位、fifo等,读寄存器手册吧。input系统这块,遇到点问题,使用上的要点如下:1、因为要通过绝对坐标来通知Android触摸事件,在设备初始化时,要使用input_set_abs_params设置x和y的最大值,其实就是屏幕分辨率,否则会引起kernel panic;2、触摸的按下、移动和抬起,只使用BTN_TOUCH就够了,传入1和0即可;3、最可恨的是一个叫idc的东西,这是一个设备配置文件,在Android网站上有介绍,但我一开始不知道,在没有这个文件的时候,我的触摸屏被认为是一个“鼠标”(狗安卓,你见过19寸的大鼠标么?),手指按到屏幕上,就出来一个光圈,左右移动时使用相对坐标,还带鼠标加速、双击等一系列“功能”...。这个文件要手动创建:在根文件系统下的/system/usr/idc下,创建一个your_dev.idc文件,your_dev就是在驱动中创建的dev的name字段,其中只要加上俩行:

    touch.deviceType=touchScreen

    touch.orientationAware=1

即可。对于触摸屏的校准,因为是线性的关系,我使用的式子是:aX1 + c1 = X; bY1 + c2 = Y,随便点几下,用得到的数据求出a、b、c1、c2差不太多就行了,需要注意的是这里最好使用整数计算,我的这个kernel似乎在驱动里不能使用fpu,使用float编译时有错误。

    对于上面做的这些事,最多的还是Linux系统驱动的延续,而并非是Android的根本,想要在Android上做一些事,我还差的太多太多。