换工做在即,也有了可贵的一段空闲时间作下总结。接下来计划分别介绍下Android的Sensor/Touch/Camera/Binder的Software架构,若是还有时间就总结下kernel。设计模式
Sensor属于Android相对简单的一个模块,但麻雀虽小,五脏俱全,以此来做为切入点对理解整个Android系统有很大帮助。必需要说的是,Android系统的总体架构并不适用于全部模块,每一个模块都有各自的特殊性,请不要一开始就把某些介绍看成公式。架构
不少模块均可以称为Sensor,Touch是一种Sensor,Camera也能够理解为一种Sensor。但这里介绍的Sensor架构并不适用于Touch和Camera,所使用的主要包含下面几类Sensor。框架
Categorysocket |
Components函数 |
Motion Sensorsoop |
Accelerameter/ Gravity/ Gyroscope/ Rotation Vector/…优化 |
Environmental Sensorsspa |
ALS/ Pressure/…线程 |
Position Sensors设计 |
Orientation/ Mag/… |
这几类器件有几个类似的特色,产生的数据量少,实时性较强,构造相对简单。
首先从总体上,Sensor的架构能够用下图来解释。
有些分法把SensorService归为Framework的一部分,但这里为了凸显出Service的重要性单独分为一层。
Sensor的总体逻辑很是清晰,一个控制流(蓝色向下箭头),一个数据流(红色向上箭头)。控制主要包括开关Sensor,设置Sensor的采样频率,数据流则是数据从驱动到应用的整个过程。
系统初始化过程当中,SensorService和HAL层(硬件抽象层)会进行初始化操做。SensorService链接着Framework和HAL,它采用动态连接加载HAL层模块(HAL层以so共享文件的形式存在)。
//动态连接的匹配 hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); //Service |
struct sensors_module_t my_hal = { common: { … id: SENSORS_HARDWARE_MODULE_ID, … }, get_sensors_list: …, }; //HAL |
一句话归纳该过程的目的就是,通过动态连接,Service能够调用HAL层的函数,方便将控制传递至HAL层,也能够从HAL获取数据。完成该动做后,Service调用my_hal内的open函数。HAL能够在open动做中完成初始化,如检测系统中存在的Sensor,保存每一个Sensor的信息,维护一个全部的Sensor的列表。
HAL初始化后,Service便可调用get_sensors_list获取系统所支持的全部Sensor。某些物理Sensor组合后,能够虚拟出其余Sensor,Service也会针对虚拟Sensor作处理,这部分暂不介绍。
一句话总结,与HAL创建联系(动态连接),HAL初始化(open),获取Sensor信息(get_sensors_list)。
控制,一是开关,二是频率,Android默认支持四种采样频率。
名称 |
频率 |
SENSOR_DELAY_FASTEST |
器件的最大采样频率 |
SENSOR_DELAY_GAME |
50HZ |
SENSOR_DELAY_UI |
30HZ |
SENSOR_DELAY_NORMAL |
5HZ |
除了这四种频率之外,用户也能够指定一个特定频率。控制的流程以下。
控制从APP注册监听器开始,熟悉面向对象程序设计的童鞋应该能够猜获得这是一个观察者设计模式,实际上也确实如此。注册监听器的直接操做就是enable和setDelay两个操做(unregisterListener则对应disable操做),Service与APP并非执行在同一个进程内的,Framework传递来的控制须要经过进程通讯传递至Service,使用的就是Binder(Binder几乎贯穿了Android系统的各个模块,后面介绍)。Service是惟一的,APP能够有无限个,Service为它们服务。这样设计的缘由显而易见——保证单一控制:硬件是惟一的(好比某一个加速度Sensor),对它的控制也应该是惟一的,不该该由各APP单独控制。好比enable操做,若是已经有APP打开了设备,那么只须要将引用计数增长1便可,并不会真正的触发驱动的操做;disable操做,若是引用计数大于1,说明当前除了该APP,还有其余使用者,那么也不会触发驱动的操做。
Service与HAL层属于同一个进程,Service调用HAL层的函数,HAL找到对应的文件节点,根据不一样的目的写入不一样的值来触发驱动的操做。驱动根据获得的指令,读写设定好的寄存器控制流就获得了最终的落实。
一句话总结,应用开启控制流,层层传递,最终读写寄存器。
五、数据流
数据由硬件产生,最终被应用使用,流程以下图。
驱动负责收集数据(中断或者轮询模式),经过input子系统(也有部分厂商选择使用IIO)上报数据。HAL层使用poll监控input节点,数据到来后poll返回,而后读取数据。Service部分有一个线程,该线程能够理解为一个循环,不断地poll HAL层的数据。收到数据后,Service会作一些处理(好比计算虚拟Sensor的数据),以后则经过socket将数据发送至APP进程。APP收到数据后,遍历当前已经注册的listener,通知它们,观察者模式完成。
与控制流相同,数据流依然是一个Service对应多个APP,Service会将数据发送到多个APP。
说到这里,有个地方能够优化下。目前Service收到数据后,会通知全部的已经注册了listener的APP,这个过程并非没有代价的,除了正常的执行代码外,还涉及了进程通讯。若是给APP添加一个感兴趣的Sensor类型的列表(bitmap也可),只有列表内的Sensor的数据到来才会通知该APP进程,会高效的多。
形象一点讲,整个Sensor的软件架构就像是水泵抽水灌溉。Service扮演电机的角色,它不断的产生抽水的动力,并将水输送至目的地(APP),驱动扮演泵的角色,它负责完成抽水的必要准备并抽水,HAL则很像是链接电机和泵的管道。
driver能够逻辑上分为三部分,以下图。一部分支持它自己的功能,i2c读写,中断或者轮询处理。第二部分为sysfs文件节点,接受HAL层传递下来的操做,经过i2c读写完成任务。第三部分为input子系统(注意,该处为Linux内核的input子系统,并非Android的input系统),负责数据上报。
一句话,driver的任务就是正常工做,完成控制操做,产生数据。
HAL层的做用一是屏蔽硬件差别,二是传递控制和数据。
SensorService自己就是一个线程(Thread为其父类),不出意外它循环地执行threadLoop(Android的机制),该函数一方面负责poll数据,一方面获得数据后处理,发送。
到了Framework,问题就简单了,简单的函数调用(最多涉及到jni)。
本文仅阐释了整个框架,并未罗列出详细的代码,但愿给出一个全局的介绍。
博客得来终觉浅,只因码上才能见真知。如有任何疑问或者但愿下一篇博客的内容介绍哪部分请直接留言或发邮件至邮箱(个人用户名@onesixthree邮箱)。