CHRE架构浅谈
CHRE(Context Hub Runtime Environment)是基于事件驱动的系统,因此CHRE围绕事件循环构建,该循环执行nanoapp代码以及CHRE系统回调。根据CHRE API,nanoapp一次不能在一个以上的线程中执行,因此,尽管系统中可能存在其他支持CHRE的线程,但CHRE围绕执行事件循环的单个线程构建。EventLoopManager是拥有CHRE框架主要状态的Singleton对象,包括CHRE支持的各个子系统的EventLoop和Manager类。
一、 SensorHub与CHRE架构总框图
图片摘自《谷歌开发文档》
Sensor Hub:SensorHub上直接运行算法和sensor驱动程序,驱动与算法之前耦合度较高,遵循sensor hal api接口规范。
CHRE:用于运行Nanoapp的平台,每一个算法或者sensor器件驱动,都是以Nanoapp的形式实现,之前通过发送消息的方式通信,遵循Context Hub HAL API (AP端)和CHRE API (hub端)接口规范。
二、 CHRE代码目录结构
1、 chre_api:提供nanoapps的稳定的API。
2、Core:所有平台上的通用代码,最重要的是事件管理。
3、Pal:实现者必须提供的抽象层来访问设备特定的功能(如GPS和Sensor)。 PAL是一种C API,允许使用供应商提供的库实现。
4、Platform:包含所有平台必须实现的接口,以及个别平台的实现,这个也包含CHRE API接口的实现。
5、Apps:提供小些应用程序例子,这些旨在指导新应用程序的开发人员,并帮助实现者快速测试基本功能,这是参考代码,不是CHRE必需的功能。
6、Util:包含CHRE和通用实用程序代码中使用的数据结构。
三、 CHRE上Nanoapp介绍
Nanoapp主要由如下几个部分组成,并以sensor模块为例介绍,源码路径如下:https://android.googlesource.com/platform/system/chre/+/refs/heads/master/apps/sensor_world/sensor_world.cc
1、Nanoapp入口申明,主要是完成nanoapp系统相关的初始化,如:appID号,app版本号。
2、NanoappStart():Nanoapp的启动,需要sensor模块的初始化和平台资源初始化。
3、NanoappEnd():Nanoapp的停止部分。
4、NanoappHandleEvent:NanoAPP事件处理函数,主要用来处理sensor打开、关闭、设置sensor采样率、和数据上报等事件。
四、 CHRE的初始化流程
以CHRE在SLPI上为例,CHRE Host通过fastRPC调用chre_slpi_start_thread函数,主要做两方面的工作,chre:init()初始化,与创建chreThreadEntry线程。
platform/system/chre/+/refs/heads/master/platform/slpi/init.cc
chre:init()初始化,主要包含系统时间初始化和事件循环管理对象初始化。
源码路径如下:platform/system/chre/+/refs/heads/master/core/init.cc
chreThreadEntry线程:主要是装载静态的Nanoapps,然后调用消息循环的run,等待接受系统事件。源码路径如下:
platform/system/chre/+/refs/heads/master/platform/slpi/init.cc
五、 CHRE的事件处理流程
事件管理源码如下:
Event.cc和Event.h:定义CHRE上系统事件,和CHRE发送事件到Host端接口。
Event_loop.cc和Event_loop.h:事件循环实现,从事件队列中获取消息,并派发到相应的handle,进行事件处理。
Event_loop_manager.cc和Event_loop_manager.h:事件循环的管理,包含wifi、sensor、内存、hostcommand、Gnss等事件循环管理。
Event_ref_queue.cc和Event_ref_queue.h:事件队列实现。
1、Event_ref_queue.cc和Event_ref_queue.h 事件队列的实现,push入队和Pop出队。
2、Event_loop_manager.cc和Event_loop_manager.h源码分析如下:
事件循环管理成员变量最核心的是mEventLoop。
事件循环管理接口,最核心的函数是deferCallback(),将事件队列中的事件,发送到对应的nanoapp中进行处理。
3、Event_loop.cc和Event_loop.h源码分析
Event_loop最核心是run()函数、stop()函数和postEvent()函数。
Run()源码分析如下,主要完成从Queue中取事件,并派发到相应的handle中去。
distributeEvent()函数,通过事件id,找出相应的app,并向指定的app派发事件。
参考文献:
[1] https://android.googlesource.com/platform/system/chre/+/HEAD/doc/framework_overview.md