Bootstrap

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

概述

相机驱动框架模型(后面文章中称为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拿到了

[HDF_OBJECT_ID_DEVMGR_SERVICE] = {.Create = DevmgrServiceStubCreate},

看下DevmgrServiceStubCreate函数

【drivers\adapter\uhdf2\manager\src\devmgrservicestub.c】

struct HdfObject *DevmgrServiceStubCreate(void)
{
    static struct DevmgrServiceStub *instance = NULL;
		...
        DevmgrServiceStubConstruct(instance);
		...
    }
    return (struct HdfObject *)instance;
}

static void DevmgrServiceStubConstruct(struct DevmgrServiceStub *inst)
{
    struct IDevmgrService *pvtbl = (struct IDevmgrService *)inst;

    DevmgrServiceFullConstruct(&inst->super);
    pvtbl->StartService = DevmgrServiceStubStartService;
    inst->remote = NULL;
    OsalMutexInit(&inst->devmgrStubMutx);
}

void DevmgrServiceFullConstruct(struct DevmgrServiceFull *inst)
{
    static struct IHdfMessageHandler handler = {
        .Dispatch = DevmgrServiceFullDispatchMessage
    };
    if (inst != NULL) {
        HdfMessageLooperConstruct(&inst->looper);
        DevmgrServiceConstruct(&inst->super);
        HdfMessageTaskConstruct(&inst->task, &inst->looper, &handler);
    }
}

bool DevmgrServiceConstruct(struct DevmgrService *inst)
{
    struct IDevmgrService *devMgrSvcIf = NULL;

        devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice;
        devMgrSvcIf->DetachDevice = DevmgrServiceDetachDevice;
        devMgrSvcIf->LoadDevice = DevmgrServiceLoadDevice;
        devMgrSvcIf->UnloadDevice = DevmgrServiceUnloadDevice;
        devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;
        devMgrSvcIf->StartService = DevmgrServiceStartService;
        devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange;
        devMgrSvcIf->ListAllDevice = DevmgrServiceListAllDevice;
}

【drivers\adapter\uhdf2\manager\src\devmgrservicefull.c】

注意这里的消息分发函数,比较重要	
void DevmgrServiceFullConstruct(struct DevmgrServiceFull *inst)
{
    static struct IHdfMessageHandler handler = {
        .Dispatch = DevmgrServiceFullDispatchMessage
    };
    if (inst != NULL) {
        HdfMessageLooperConstruct(&inst->looper);
        DevmgrServiceConstruct(&inst->super);
        HdfMessageTaskConstruct(&inst->task, &inst->looper, &handler);
    }
}  

在这里创建好了dev mgr service。

2.3 完成DevMgrSvcIf和camerahostService的绑定

因此我们回到上面的调用devMgrSvcIf->AttachDeviceHost(devMgrSvcIf, hostId, hostService);即调用函数DevmgrServiceAttachDeviceHost

【drivers\framework\core\manager\src\devmgr_service.c】

static int DevmgrServiceAttachDeviceHost(
struct IDevmgrService *inst, uint16_t hostId, struct IDevHostService *hostService)
{
	//通过DevmgrServiceFindDeviceHost去找hostid=8的,其实就是找cameraservice
    struct DevHostServiceClnt *hostClnt = DevmgrServiceFindDeviceHost(inst, hostId);
    if (hostClnt == NULL) {
        HDF_LOGE("failed to attach device host, hostClnt is null");
        return HDF_FAILURE;
    }
    if (hostService == NULL) {
        HDF_LOGE("failed to attach device host, hostService is null");
        return HDF_FAILURE;
    }

    hostClnt->hostService = hostService;
    return DevHostServiceClntInstallDriver(hostClnt);
}

然后通过DevHostServiceClntInstallDriver函数安装驱动

【drivers\framework\core\manager\src\devhostserviceclnt.c】

int DevHostServiceClntInstallDriver(struct DevHostServiceClnt *hostClnt)
{
	...
    HdfSListIteratorInit(&it, &hostClnt->unloadDevInfos);
    while (HdfSListIteratorHasNext(&it)) {
        deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&it);
        if ((deviceInfo == NULL) || (deviceInfo->preload == DEVICE_PRELOAD_DISABLE)) {
            continue;
        }
        /*
         * If quick start feature enable, the device which 'preload' attribute set as
         * DEVICE_PRELOAD_ENABLE_STEP2 will be loaded later
         */
        if (DeviceManagerIsQuickLoad() == DEV_MGR_QUICK_LOAD &&
            deviceInfo->preload == DEVICE_PRELOAD_ENABLE_STEP2) {
            continue;
        }
        ret = devHostSvcIf->AddDevice(devHostSvcIf, deviceInfo);
		...
    return HDF_SUCCESS;
}

接下来通过devHostSvcIf->AddDevice来添加设备了,这里调用的是DevHostServiceFullAddDevice
通过消息,实际调用DevHostServiceAddDevice

【drivers\framework\core\host\src\devhost_service.c】

int DevHostServiceAddDevice(struct IDevHostService *inst, const struct HdfDeviceInfo *deviceInfo)
{
    struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance();

    device = DevHostServiceQueryOrAddDevice(hostService, DEVICEID(deviceInfo->deviceId));

    devNode = device->super.GetDeviceNode(&device->super, deviceInfo->deviceId);

    driver = driverLoader->GetDriver(deviceInfo->moduleName);

    devNode = HdfDeviceNodeNewInstance(deviceInfo, driver);

    devNode->hostService = hostService;
    devNode->device = device;
    devNode->driver = driver;

    ret = device->super.Attach(&device->super, devNode);

    return ret;
}

2.3.1 构建driverloader实例及其接口初始化

获取IDriverLoader实例,做好相关的初始化

【drivers\adapter\uhdf2\host\src\driverloaderfull.c】

struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance();

[HDF_OBJECT_ID_DRIVER_LOADER] =
    {
        .Create = HdfDriverLoaderFullCreate,
        .Release = HdfDriverLoaderFullRelease,
    },

将driverLoader相关接口初始化

【drivers\framework\core\host\src\devhost_service.c】

void HdfDriverLoaderFullConstruct(struct DriverLoaderFull *inst)
{
    struct HdfDriverLoader *pvtbl = (struct HdfDriverLoader *)inst;
    pvtbl->super.GetDriver = HdfDriverLoaderGetDriver;
    pvtbl->super.ReclaimDriver = HdfDriverLoaderFullReclaimDriver;
}

所以driver = driverLoader->GetDriver(deviceInfo->moduleName);实际就是通过.moduleName = “camera_service”,拿到对应的camera host drvier驱动的结构体 dfDriverEntry

【drivers\framework\core\host\src\hdf_device.c】

struct HdfDriverEntry g_cameraHostDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "camera_service",
    .Bind = HdfCameraHostDriverBind,
    .Init = HdfCameraHostDriverInit,
    .Release = HdfCameraHostDriverRelease,
};

2.3.2 构建hdf device实例及其接口初始化

通过DevHostServiceQueryOrAddDevice构建HdfDevice设备,并将其加到DevHost列表中

【drivers\peripheral\camera\interfaces\hdiipc\server\src\camerahost_driver.cpp】

static struct HdfDevice *DevHostServiceQueryOrAddDevice(struct DevHostService *inst, uint16_t deviceId)
{
    struct HdfDevice *device = DevHostServiceFindDevice(inst, deviceId);
    if (device == NULL) {
        device = HdfDeviceNewInstance();
        if (device == NULL) {
            HDF_LOGE("Dev host service failed to create driver instance");
            return NULL;
        }
        device->deviceId = MK_DEVID(inst->hostId, deviceId, 0);
        DListInsertHead(&device->node, &inst->devices);
    }
    return device;
}

如果device为NULL,则创建HdfDevice实例,device = HdfDeviceNewInstance(),并将相关接口初始化

[HDF_OBJECT_ID_DEVICE] =
{
    .Create = HdfDeviceCreate,
    .Release = HdfDeviceRelease,
},

void HdfDeviceConstruct(struct HdfDevice *device)
{
    device->super.Attach = HdfDeviceAttach;
    device->super.Detach = HdfDeviceDetach;
    device->super.DetachWithDevid = HdfDeviceDetachWithDevid;
    device->super.GetDeviceNode = HdfDeviceGetDeviceNode;

    DListHeadInit(&device->devNodes);
}

回到adddevice中,通过super.GetDeviceNode创建HdfDeviceNode

devNode = device->super.GetDeviceNode(&device->super, deviceInfo->deviceId);

获取HdfDeviceNode实例和构建HdfDeviceNode服务接口
devNode = HdfDeviceNodeNewInstance(deviceInfo, driver);

[HDF_OBJECT_ID_DEVICE_SERVICE] =
    {
        .Create = DeviceServiceStubCreate,
        .Release = DeviceServiceStubRelease,
    }

void DeviceServiceStubConstruct(struct DeviceServiceStub *inst)
{
    HdfDeviceNodeConstruct(&inst->super);
    struct IDeviceNode *serviceIf = (struct IDeviceNode *)inst;
    if (serviceIf != NULL) {
        serviceIf->PublishService = DeviceServiceStubPublishService;
        serviceIf->RemoveService = DeviceServiceStubRemoveService;
    }
}

2.3.3 关联HDF Device和Driver

最后关联driver和device

ret = device->super.Attach(&device->super, devNode);

【drivers\framework\core\host\src\hdf_device.c】

static int HdfDeviceAttach(struct IHdfDevice *devInst, struct HdfDeviceNode *devNode)
{
    int ret;
    struct HdfDevice *device = (struct HdfDevice *)devInst;
    struct IDeviceNode *nodeIf = (struct IDeviceNode *)devNode;
	...
    devNode->token->devid = devNode->devId;
    ret = nodeIf->Launc hNode(devNode);
    if (ret == HDF_SUCCESS) {
        DListInsertTail(&devNode->entry, &device->devNodes);
        UpdateDeivceNodeIdIndex(device, devNode->devId);
    }

    return ret;
}

好了,非常关键的来了,看看下面几个函数

【drivers\framework\core\host\src\hdfdevicenode.c】

int HdfDeviceLaunchNode(struct HdfDeviceNode *devNode)
{
	...
    ret = DeviceDriverBind(devNode);

    ret = driverEntry->Init(&devNode->deviceObject);

    ret = HdfDeviceNodePublishService(devNode);

    ret = DevmgrServiceClntAttachDevice(devNode->token);
	...	
}

到这里我们再看下camera_host_driver,实现HdfDriverEntry

【drivers\peripheral\camera\interfaces\hdiipc\server\src\camerahost_driver.cpp】

struct HdfDriverEntry g_cameraHostDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "camera_service",
    .Bind = HdfCameraHostDriverBind,
    .Init = HdfCameraHostDriverInit,
    .Release = HdfCameraHostDriverRelease,
};

这几个很重要,先看下DeviceDriverBind(devNode)

【drivers\peripheral\camera\interfaces\hdiipc\server\src\camerahost_driver.cpp】

int DeviceDriverBind(struct HdfDeviceNode *devNode)
{

    ret = driverEntry->Bind(&devNode->deviceObject);

    return HDF_SUCCESS;
}

调用驱动的bind函数,即上面的HdfCameraHostDriverBind

【drivers\framework\core\host\src\hdfdevicenode.c】

int HdfCameraHostDriverBind(HdfDeviceObject *deviceObject)
{ 
    if (deviceObject == nullptr) {
        HDF_LOGE("HdfCameraHostDriverBind: HdfDeviceObject is NULL !");
        return HDF_FAILURE;
    }

    HdfCameraService *hdfCameraService =
        reinterpret_cast<HdfCameraService *>(OsalMemAlloc(sizeof(HdfCameraService)));
    if (hdfCameraService == nullptr) {
        HDF_LOGE("HdfCameraHostDriverBind OsalMemAlloc HdfCameraService failed!");
        return HDF_FAILURE;
    }

    hdfCameraService->ioservice.Dispatch = CameraServiceDispatch;
    hdfCameraService->ioservice.Open = nullptr;
    hdfCameraService->ioservice.Release = nullptr;
    hdfCameraService->instance = CameraHostStubInstance();

    deviceObject->service = &hdfCameraService->ioservice;
    return HDF_SUCCESS;
}

初始化了分发函数和Camera Host stub实例函数,并将ioserivice交给deviceObject

init部分,camera这边没有做啥事
ret = driverEntry->Init(&devNode->deviceObject);

发布相关的服务ret = HdfDeviceNodePublishService(devNode),

【drivers\adapter\uhdf2\host\src\deviceservicestub.c】

static int HdfDeviceNodePublishService(struct HdfDeviceNode *devNode)
{
	...
    if (devNode->policy == SERVICE_POLICY_PUBLIC || devNode->policy == SERVICE_POLICY_CAPACITY) {
        if (nodeIf->PublishService != NULL) {
			HDF_LOGE("ESLUO PublishService HdfDeviceNode PublishService");
            status = nodeIf->PublishService(devNode);
        }
    }
    if (status == HDF_SUCCESS) {
        status = HdfDeviceNodePublishLocalService(devNode);
    }
    return status;
}

2.4 Camera Host服务发布

当对外发布时,cameraservice会走到nodeIf->PublishService(devNode),由上面的serviceIf->PublishService = DeviceServiceStubPublishService,调到这里,

【drivers\framework\core\host\src\devsvcmanagerclnt.c】

int DeviceServiceStubPublishService(struct HdfDeviceNode *service)
{

    fullService->remote = HdfRemoteServiceObtain((struct HdfObject *)fullService, &g_deviceServiceDispatcher);
    if (fullService->remote == NULL) {
        return HDF_ERR_MALLOC_FAIL;
    }
	...
    do {
        struct DevSvcManagerClnt *serviceManager = DevSvcManagerClntGetInstance();
        if (serviceManager == NULL) {
            HDF_LOGE("device service stub failed to publish, svcmgr clnt invalid");
            status = HDF_DEV_ERR_NO_DEVICE;
            break;
        }

        status = DevSvcManagerClntAddService(service->servName, service->deviceObject.deviceClass,
            &fullService->super.deviceObject, service->servInfo);
    } while (0);
}

在fullService->remote = HdfRemoteServiceObtain((struct HdfObject *)fullService, &g_deviceServiceDispatcher);这里获取camera_host_driver驱动的发布函数

接下来由DevSvcManagerClntAddService函数中调用serviceManager->AddService完成服务的最终发布

int DevSvcManagerClntAddService(const char *svcName, uint16_t devClass,
struct HdfDeviceObject *service, const char *servinfo)
{
    struct DevSvcManagerClnt *devSvcMgrClnt = DevSvcManagerClntGetInstance();
    struct IDevSvcManager *serviceManager = NULL;
    if (devSvcMgrClnt == NULL) {
        HDF_LOGE("failed to add service, client is null");
        return HDF_FAILURE;
    }
    if (devClass >= DEVICE_CLASS_MAX) {
        HDF_LOGE("failed to add service, invalid class");
        return HDF_FAILURE;
    }

    serviceManager = devSvcMgrClnt->devSvcMgrIf;这里获取DevSvcManagerProxy
    if (serviceManager == NULL || serviceManager->AddService == NULL) {
        HDF_LOGE("serviceManager AddService function is null");
        return HDF_FAILURE;
    }
	//DevSvcManagerAddService
    return serviceManager->AddService(serviceManager, svcName, devClass, service, servinfo);
}

让我们再次回到bind函数里面,通过上面我们已经看到已经将cameraservice服务发布,下面我们将通过CameraHostStubInstance()函数,看看具体底下提供了那些服务,是如何实现这些服务的

【drivers\peripheral\camera\interfaces\hdiipc\server\src\camerahost_driver.cpp】

void *CameraHostStubInstance()
{
    OHOS::Camera::RetCode ret = stub->Init();
}

由stub->Init -> CameraHostStub::Init->CameraHost::CreateCameraHost -> cameraHost->Init()调用到

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\v4l2device_manager.cpp】

CamRetCode CameraHostImpl::Init()
{
    std::shared_ptr<IDeviceManager> deviceManager =
        IDeviceManager::GetInstance();

    ret = deviceManager->Init();
    if (ret == RC_ERROR) {
        return INVALID_ARGUMENT;
    }

    CameraHostConfig *config = CameraHostConfig::GetInstance();

        std::shared_ptr<CameraDevice> cameraDevice =
            CameraDevice::CreateCameraDevice(cameraId);
        if (cameraDevice != nullptr) {
            cameraDeviceMap_.insert(std::make_pair(cameraId, cameraDevice));
        } else {
            CAMERA_LOGW("host implement new device failed [cameraid = %{public}s].", cameraId.c_str());
        }
    }

    return NO_ERROR;
}

2.4.1 deviceManager初始化

在deviceManager->Init()中完成sensor、flash和isp的创建

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\v4l2device_manager.cpp】

RetCode V4L2DeviceManager::Init()
{
RetCode rc = RC_ERROR;

rc = HosV4L2Dev::Init(hardwareName);
if (rc == RC_ERROR) {
    CAMERA_LOGE("%s HosV4L2Dev Init fail", __FUNCTION__);
    return RC_ERROR;
}

for (auto iter = hardware.cbegin(); iter != hardware.cend(); iter++) {
    bool eraseHardwareNameFlage = true;
    for (auto iterName = hardwareName.cbegin(); iterName != hardwareName.cend(); iterName++) {
        if ((*iter).controllerId == DM_C_SENSOR && (*iterName) == (*iter).hardwareName) {
            eraseHardwareNameFlage = false;
        }
    }
    if (eraseHardwareNameFlage == true && (*iter).controllerId == DM_C_SENSOR) {
        hardware.erase(iter);
    }
}
for (auto iter = hardware.cbegin(); iter != hardware.cend(); iter++) {
    hardwareList_.push_back(*iter);
}
rc = CreateManager();
enumeratorManager_ = std::make_shared<EnumeratorManager>();
if (enumeratorManager_ == nullptr) {
    CAMERA_LOGE("%s Create EnumeratorManager fail", __FUNCTION__);
    return RC_ERROR;
}
rc = enumeratorManager_->Init();
if (rc == RC_ERROR) {
    CAMERA_LOGE("%s EnumeratorManager Init fail", __FUNCTION__);
    return rc;
}
return rc;

}

遍历所有的camera硬件设备,并将各个设备加入到我们的v4l2 device manager中,其实就是我们看到的/dev/videox

std::vector<HardwareConfiguration> hardware = {
	{CAMERA_FIRST, DM_M_SENSOR, DM_C_SENSOR, (std::string) "bm2835 mmal"},
	{CAMERA_FIRST, DM_M_ISP, DM_C_ISP, (std::string) "isp"},
	{CAMERA_FIRST, DM_M_FLASH, DM_C_FLASH, (std::string) "flash"},
}

rc = HosV4L2Dev::Init(hardwareName);

创建devicemanager:

rc = CreateManager();

2.4.1 devicemanager框架介绍

创建SensorManager、FlashManager、ISPManager,管理相应的设备。
image.png

2.4.2 devicemanager接口介绍
2.4.2.1 SensorManager接口介绍

sensor Manager结构如下

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\include\sensormanager.h】

class SensorManager : public IManager {
public:
    SensorManager();
    explicit SensorManager(ManagerId managerId);
    virtual ~SensorManager();
    RetCode CreateController(ControllerId controllerId, std::string hardwareName);
    RetCode DestroyController(ControllerId controllerId, std::string hardwareName);
    std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);

    void Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode Start(std::string hardwareName, int buffCont, DeviceFormat& format);
    RetCode Stop(std::string hardwareName);
    RetCode PowerUp(std::string hardwareName);
    RetCode PowerDown(std::string hardwareName);
    std::shared_ptr<ISensor> GetSensor(std::string sensorName);

    RetCode SendFrameBuffer(std::shared_ptr<FrameSpec> buffer, std::string hardwareName);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName);
    void SetNodeCallBack(const NodeBufferCb cb, std::string hardwareName);
    void SetMetaDataCallBack(const MetaDataCb cb, std::string hardwareName);

private:
    bool CheckCameraIdList(std::string hardwareName);
    std::vector<std::shared_ptr<SensorController>> sensorList_;
};
} 

PowerUp为上电接口,OpenCamera时调用此接口进行设备上电操作

PowerDown为下电接口,CloseCamera时调用此接口进行设备下电操作

Configures为Metadata下发接口,如需设置metadata参数到硬件设备,可实现此接口进行解析及下发

Start为硬件模块使能接口,pipeline中的各个node进行使能的时候,会去调用,可根据需要定义实现,比如sensor的起流操作就可放在此处进行实现,Stop和Start为相反操作,可实现停流操作

SendFrameBuffer为每一帧buffer下发接口,所有和驱动进行buffer交互的操作,都是通过此接口进行的

SetNodeCallBack为pipeline,通过此接口将buffer回调函数设置到devicemanager

SetMetaDataCallBack为metadata回调接口,通过此接口将从底层获取的metadata数据上报给上层

BufferCallback上传每一帧已填充数据buffer的接口,通过此接口将buffer上报给pipeline

SetAbilityMetaDataTag设置需要从底层获取哪些类型的metadata数据,因为框架支持单独获取某一类型或多类型的硬件设备信息,所以可以通过此接口,获取想要的metadata数据

2.4.2.2 SensorControl接口介绍

Camera Sensor Controller结构如下:

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\include\sensorcontroller.h】

class SensorController : public IController {
public:
    SensorController();
    explicit SensorController(std::string hardwareName);
    virtual ~SensorController();
    RetCode Init();
    RetCode PowerUp();
    RetCode PowerDown();
    RetCode Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode Start(int buffCont, DeviceFormat& format);
    RetCode Stop();
	...
    void SetMetaDataCallBack(MetaDataCb cb) override;
    void BufferCallback(std::shared_ptr<FrameSpec> buffer);

    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag);
    RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta);
    RetCode Flush(int32_t streamId);
	...

};

PowerUp下发命令给v4l2 dev去操作实际设备进行上电操作
PowerDown下发命令给v4l2 dev去操作实际设备进行下电操作
同理其他操作参考SensorManager.

2.4.2.3 FlashManager接口介绍

Flash Manger结构如下:

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\include\flash_manager.h】

class FlashManager : public IManager {
public:
    FlashManager();
    explicit FlashManager(ManagerId managerId);
    virtual ~FlashManager();
    RetCode CreateController(ControllerId controllerId, std::string hardwareName);
    std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);
    RetCode PowerUp(std::string hardwareName);
    RetCode PowerDown(std::string hardwareName);
    void Configure(std::shared_ptr<CameraMetadata> meta);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName)
    {
        (void)abilityMetaDataTag;
        (void)hardwareName;
        return;
    }
    RetCode SetFlashlight(FlashMode flashMode, bool enable, std::string hardwareName);
private:
    bool CheckCameraIdList(std::string hardwareName);
    std::vector<std::shared_ptr<FlashController>> flashList_;
}

2.4.2.4 FlashControl接口介绍

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\include\flashcontroller.h】

class FlashController : public IController {
public:
    FlashController();
    explicit FlashController(std::string hardwareName);
    virtual ~FlashController();
    RetCode Init();
    RetCode PowerUp();
    RetCode PowerDown();
    RetCode Configure(std::shared_ptr<CameraMetadata> meta)
    {
        (void)meta;
        return RC_OK;
    }
    RetCode SetFlashlight(FlashMode flashMode, bool enable);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag);
    RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta);
private:
    std::mutex startVolock_;
    bool startVoState_ = false;
}

2.4.2.5 ISPManager接口介绍

ISP Manager结构如下

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\include\ispmanager.h】

class IspManager : public IManager {
public:
    IspManager();
    explicit IspManager(ManagerId managerId);
    virtual ~IspManager();
    RetCode CreateController(ControllerId controllerId, std::string hardwareName);
    std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);
    void Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode Start(std::string hardwareName);
    RetCode Stop(std::string hardwareName);
    RetCode PowerUp(std::string hardwareName);
    RetCode PowerDown(std::string hardwareName);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName)
    {
        (void)abilityMetaDataTag;
        (void)hardwareName;
        return;
    }
private:
    bool CheckCameraIdList(std::string hardwareName);
    std::vector<std::shared_ptr<IspController>> ispList_;
};

2.4.2.6 ISPcontroller接口介绍

ISP controller结构如下

【drivers\peripheral\camera\hal\adapter\platform\v4l2\src\devicemanager\include\ispcontroller.h】

class IspController : public IController {
public:
    IspController();
    explicit IspController(std::string hardwareName);
    virtual ~IspController();
    RetCode Init();
    RetCode Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode PowerUp();
    RetCode PowerDown();
    RetCode Stop();
    RetCode Start();
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag)
    {
        (void)abilityMetaDataTag;
        return;
    }
    RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta)
    {
        (void)meta;
        return RC_OK;
    }
private:
    std::mutex startIsplock_;
    bool startIspState_ = false;
}

2.4.3 Pipeline框架说明

Pipeline主要实现数据流通路的搭建及stream流转的策略等
image.png

2.4.3.1 Pipeline初始化

回到CameraHostImpl::Init()中,通过CameraDevice::CreateCameraDevice(cameraId)创建pipelie

std::shared_ptr<CameraDevice> CameraDevice::CreateCameraDevice(const std::string &cameraId)
{
    // create pipelineCore
    std::shared_ptr<IPipelineCore> pipelineCore = IPipelineCore::Create();
    if (pipelineCore == nullptr) {
        CAMERA_LOGW("create pipeline core failed. [cameraId = %{public}s]", cameraId.c_str());
        return nullptr;
    }

    RetCode rc = pipelineCore->Init();
    if (rc != RC_OK) {
        CAMERA_LOGW("pipeline core init failed. [cameraId = %{public}s]", cameraId.c_str());
        return nullptr;
    }
	...

    return device;
}
} 

在pipelineCore->Init中主要完成了streammgr和streampipeline的实例创建和初始化

RetCode PipelineCore::Init()
{
    context_ = std::make_shared<NodeContext>();
    context_->streamMgr_ = HostStreamMgr::Create();
    spc_ = IStreamPipelineCore::Create(context_);
    return RC_OK;
}

后续的stream流的创建和管理较复杂,这部分具体细节后面章节再说,至此开机工程中,camera host服务主要流程就结束了。

3. 总结

本文主要讲述了,系统启动过程中,camera host服务创建和注册流程

1.hdf_devhost读取vendor/etc/init/hdfdevhost.cfg文件start devhostservice.

2.devhostservice服务启动以后,将devmgrservice服务拉起来,对设备和服务进行管理

3.完成DevMgrSvcIf和camerahostService的绑定,并发布camera host服务

4.最后在CameraHostStubInstance函数中,完成了device manager的创建,为后面具体的服务的管理和控制提供方法

5.简单的介绍了Pipeline框架

写在最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。

这份鸿蒙(HarmonyOS NEXT)文档包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习文档能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习文档

鸿蒙(HarmonyOS NEXT)5.0最新学习路线

在这里插入图片描述

有了路线图,怎么能没有学习文档呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习文档

《鸿蒙 (OpenHarmony)开发入门教学视频》

在这里插入图片描述

《鸿蒙生态应用开发V3.0白皮书》

在这里插入图片描述

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

在这里插入图片描述

《鸿蒙开发基础》

●ArkTS语言
●安装DevEco Studio
●运用你的第一个ArkTS应用
●ArkUI声明式UI开发
.……
在这里插入图片描述

《鸿蒙开发进阶》

●Stage模型入门
●网络管理
●数据管理
●电话服务
●分布式应用开发
●通知与窗口管理
●多媒体技术
●安全技能
●任务管理
●WebGL
●国际化开发
●应用测试
●DFX面向未来设计
●鸿蒙系统移植和裁剪定制
……
在这里插入图片描述

《鸿蒙进阶实战》

●ArkTS实践
●UIAbility应用
●网络案例
……
在这里插入图片描述

获取以上完整鸿蒙HarmonyOS学习文档,请点击→纯血版全套鸿蒙HarmonyOS学习文档

;