【鸿蒙南向开发】OpenHarmony——相机驱动框架模型

概述

相机驱动框架模型(后面文章中称为camera host)对上实现HDI接口和CameraService进行交互,对下实现Pipeline模型、DeviceManager设备管理窗口以及 Platform Adapter。

  • HDI接口:实现和CameraService交互的接口
  • Pipeline模型:实现数据流通路的搭建及stream流转的策略等
  • DeviceManager设备管理:管理相机各个硬件设备(比如sensor、isp、flash等)
  • Platform Adapter适配层:屏蔽底层芯片和OS(Operation System)差异,支持多平台适配

Camera Host驱动层架构图如下:
image.png

由于相机整个从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拿到了</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值