概述
相机驱动框架模型(后面文章中称为camera host)对上实现HDI接口和CameraService进行交互,对下实现Pipeline模型、DeviceManager设备管理窗口以及 Platform Adapter。
- HDI接口:实现和CameraService交互的接口
- Pipeline模型:实现数据流通路的搭建及stream流转的策略等
- DeviceManager设备管理:管理相机各个硬件设备(比如sensor、isp、flash等)
- Platform Adapter适配层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配
Camera Host驱动层架构图如下:
由于相机整个从APP到HDF,然后再到内核驱动部分,这里涉及的东西很多,而Camera Host涉及多个服务间的交互,其中还存在IPC交互,整体看起来还是有点复杂的
因此我打算从两点来讲Camera Host部分
1、第一条线,camera在开机的时候,涉及camera服务的启动,所以我打算跟随设备启动过程中,host端服务的注册过程
2、第二条线,每个客户端在启动的时候,会对device端进行注册,因此这条线是随应用打开相机的方向,看看device是如何被拿到,以及如何操作具体的硬件设备
本文主要是基于第一条线,看看在开机过程中Camera Host服务如何启动和注册。
1. Camera Host 启动入口
camera host 服务由hdf_devhost启动,配置文件存放于vendor/etc/init/hdf_devhost.cfg
{
"name" : "camera_host",
"path" : ["/vendor/bin/hdf_devhost", "8", "camera_host"],
"uid" : "camera_host",
"gid" : ["camera_host"],
"caps" : ["DAC_OVERRIDE", "DAC_READ_SEARCH"],
"secon" : "u:r:camera_host:s0"
}
加载camera_host驱动代码:
【drivers\adapter\uhdf2\host\devhost.c】
//hostId = 8 hostName = camera_host
struct IDevHostService *instance = (hostId, hostName);
if (instance == NULL || instance->StartService == NULL) {
HDF_LOGE("DevHostServiceGetInstance fail");
return HDF_ERR_INVALID_OBJECT;
}
int status = instance->StartService(instance);
if (status != HDF_SUCCESS) {
HDF_LOGE("Devhost StartService fail, return: %{public}d", status);
DevHostServiceFreeInstance(instance);
return status;
}
2. 构造DevHostService实例并完成初始化
2.1 构造DevHostService实例并完成初始化
首先看下camerahost的这个实例是怎么被实例化的,以及camera host是怎么被创建出来
struct IDevHostService *instance = DevHostServiceNewInstance(hostId, hostName);
在DevHostServiceNewInstance函数中,创建DevHostService实例
【drivers\framework\core\host\src\devhost_service.c】
struct IDevHostService *DevHostServiceNewInstance(uint16_t hostId, const char *hostName)
{
struct DevHostService *hostService =
(struct DevHostService *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVHOST_SERVICE);
if (hostService != NULL && hostName != NULL) {
hostService->hostId = hostId;
hostService->hostName = hostName;
}
return (struct IDevHostService *)hostService;
}
struct HdfObject *HdfObjectManagerGetObject(int objectId)
{
struct HdfObject *object = NULL;
const struct HdfObjectCreator *targetCreator = HdfObjectManagerGetCreators(objectId);
if ((targetCreator != NULL) && (targetCreator->Create != NULL)) {
object = targetCreator->Create();
if (object != NULL) {
object->objectId = objectId;
}
}
return object;
}
void HdfObjectManagerFreeObject(struct HdfObject *object)
{
const struct HdfObjectCreator *targetCreator = NULL;
if (object == NULL) {
return;
}
targetCreator = HdfObjectManagerGetCreators(object->objectId);
if ((targetCreator == NULL) || (targetCreator->Release == NULL)) {
return;
}
targetCreator->Release(object);
}
注意这个HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVHOST_SERVICE)调用中的HDF_OBJECT_ID_DEVHOST_SERVICE,通过他我们可以找
到实际的DEVHOST SERVICE Manager,然后调用DevHostServiceStubCreate函数
【drivers\adapter\uhdf2\host\src\devhostobjectconfig.c】
[HDF_OBJECT_ID_DEVHOST_SERVICE] =
{
.Create = DevHostServiceStubCreate,
.Release = DevHostServiceStubRelease,
},
看下DevHostServiceStubCreate函数:
【drivers\adapter\uhdf2\host\src\devhostservicestub.c】
struct HdfObject *DevHostServiceStubCreate(void)
{
static struct DevHostServiceStub *instance = NULL;
if (instance != NULL) {
return (struct HdfObject *)&instance->super;
}
INSTANCE = (STRUCT DEVHOSTSERVICESTUB *)OSALMEMCALLOC(SIZEOF(STRUCT DEVHOSTSERVICESTUB));
if (instance != NULL) {
DevHostServiceStubConstruct(instance);
return (struct HdfObject *)&instance->super;
}
return NULL;
}
在这里为hdf host service初始化了Dispatch分发函以及DevHostServiceFull接口
【drivers\adapter\uhdf2\host\src\devhostservicestub.c】
static void DevHostServiceStubConstruct(struct DevHostServiceStub *inst)
{
static struct HdfRemoteDispatcher dispatcher = {
.Dispatch = DevHostServiceStubDispatch
};
DEVHOSTSERVICEFULLCONSTRUCT(&inst->super);
inst->remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher);
OsalMutexInit(&inst->hostSvcMutex);
}
void DevHostServiceFullConstruct(struct DevHostServiceFull *inst)
{
struct IDevHostService *hostServiceIf = &inst->super.super;
static struct IHdfMessageHandler handler = {
.Dispatch = DevHostServiceFullDispatchMessage
};
DEVHOSTSERVICECONSTRUCT(&inst->super);
hostServiceIf->AddDevice = DevHostServiceFullAddDevice;
hostServiceIf->DelDevice = DevHostServiceFullDelDevice;
hostServiceIf->StartService = DevHostServiceFullStartService;
hostServiceIf->PmNotify = DevHostServiceFullPmNotify;
HdfMessageLooperConstruct(&inst->looper);
HdfMessageTaskConstruct(&inst->task, &inst->looper, &handler);
}
到此通过这个实例我们拿到了host service初始化了Dispatch分发函以及DevHostServiceFull接口
综上我们拿到了dev host service的实例,并完成了部分的初始化
接下来回到StartService
【drivers\framework\core\host\src\devhost_service.c】
int status = instance->StartService(instance);
由上面接口初始化,可以知道实际调用的是DevHostServiceFullStartService,
【drivers\adapter\uhdf2\host\src\devhostservicefull.c】
static int DevHostServiceFullStartService(struct IDevHostService *service)
{
...
int ret = DevmgrServiceClntAttachDeviceHost(hostService->hostId, service);
...
return HDF_SUCCESS;
}
int DevmgrServiceClntAttachDeviceHost(uint16_t hostId, struct IDevHostService *hostService)
{
...
struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
devMgrSvcIf = inst->devMgrSvcIf;
...
return devMgrSvcIf->AttachDeviceHost(devMgrSvcIf, hostId, hostService);
}
2.2 构造DevMgrService实例并完成初始化
注意在这里我们用开始注册另一个实例dev mgr service,
【drivers\framework\core\host\src\devmgrserviceclnt.c】
struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
struct DevmgrServiceClnt *DevmgrServiceClntGetInstance()
{
static struct DevmgrServiceClnt instance = {0};
if (instance.devMgrSvcIf == NULL) {
instance.devMgrSvcIf = (struct IDevmgrService *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVMGR_SERVICE);
}
return &instance;
}
和上面的方法一样,我们通过HDF_OBJECT_ID_DEVMGR_SERVICE拿到了</