Qualcomm一直扮演着芯片制造商的身份,但在全球芯片市场趋于饱和的状态下,车载成了Qualcomm新的目标。为了在车载领域分一杯羹,Qualcomm与松下开发了基于骁龙820新时代的车载信息娱乐系统。
软件方面和google合作开发,此车载系统基于android,google公司为了让系统变得更加安全和稳定,对系统进行了许多深度定制。
小编所在公司有幸参与了骁龙820A开发板的相关开发工作,对其中的vehicle_network_service有些见解,再次分享出来,以供大家参考。
Android make文件分析
Android.mk是Android提供的一种makefile文件,用来指定诸如编译生成so库名、引用的头文件目录、需要编译的.c/.cpp文件和.a静态库文件。
总体来说Android.mk定义了该模块的编译方式。
Android.mk引用的文件包括lib文件,编译所需文件还有头文件,引用的文件如下所示:
这个模块最重要的文件是main_vehiclenetwork.cpp,和相关的共享库和静态库libvehiclenetworkservice。Android.mk编译的目标是可执行文件,也就是说adb shell 之后,直接是命令行./vehicle_network_service的形式运行即可。
主程序分析main_Vehiclenetwork.cpp
程序内容比较简洁,具体的实现在libvehiclenetworkservice中。
main_Vehiclenetwork是该模块的程序入口,里面四个关键函数如上图所示,分别为:
defaultServiceManager(),
instantiate(),
startThreadPool(),
joinThreadPool()。
这是启动一个service的基本流程。其中defaultServiceManager()获取IServiceManager对象,并将VehicleNetworkService实例化,通过startThreadPool()和joinThreadPool()启动线程。
ProcessState类的在frameworks/base/include/binder/ProcessState.h中定义。从它的定义看,IPCThreadState是它的友元类,所以IPCThreadState可以调用它的相关函数。
获取IServiceManager对象defaultServiceManager()
该代码定义在frameworks/native/libs/binder/IServiceManager.cpp中。它是获取IServiceManager对象,该函数的声明在frameworks/native/include/binder/IServiceManager.h中。虽然defaultServiceManager()在IServiceManager.cpp文件中实现,但是它并不是IServiceManager的一个成员方法,而是一个全局方法。 defaultServiceManager()返回的是IServiceManager对象,获取IServiceManager对象之后就可以和ServiceManager进程进行通信。在骁龙820A里面,这个ServiceManager就是VehicleNetworkService。
gDefaultServiceManagerLock是全局互斥锁,gDefaultServiceManager是全局的IServiceManager对象。它们都定义在frameworks/native/libs/binder/Static.cpp中。gDefaultServiceManager是采用单例模式实现的,第一次调用该函数时,会创建gDefaultServiceManager对象。
具体实现代码如下:
其中,gDefaultServiceManagerLock是全局互斥锁,gDefaultServiceManager是全局的IServiceManager对象。
ProcessState::self()->startThreadPool()
该代码定义在frameworks/native/libs/binder/ProcessState.cpp中,它的作用是返回gProcess对象。gProcess也是单例模式对象,它也定义在frameworks/native/libs/binder/Static.cpp中。第一次执行self()时,会新建ProcessState对象。在ProcessState的构造函数中,它会进行一系列的初始化。
ProcessState中startThreadPool()函数调用spawnPooledThread,然后spawnPooledThread调用PoolThread,接着返回一个Thread对象,最后实现Thread里面的run方法。此时骁龙820A车载系统就进入binder消息循环了。
调用spawnPooledThread代码如下:
spawnPooledThread调用PoolThread代码如下:
PoolThread的实现方式
IPCThreadState::self()->joinThreadPool()
startThreadPool中新启动的线程通过joinThreadPool读取binder设备,查看是否有请求。主线程也调用joinThreadPool读取binder设备,查看是否有请求。
总结
车载网络服务main_Vehiclenetwork.cpp的实现比较简单,里面最具车载特色的是instantiate()方法,可以拿surfacefliger举个例子
其中最重要的是SurfaceFliger::instantiate()方法,是不是看起来和我们的车载模块的函数入口差不多。所以想要了解骁龙820A的VehicleNetworkService::instantiate(),就必须深入了解VehicleNetworkService,小编会在以后的文章中和大家一起分析和探讨。
Qualcomm汽车技术讨论组 QQ群号:566131670