OpenHarmony——相机驱动框架模型 原创 精华

深开鸿
发布于 2022-8-4 11:55
浏览
3收藏

作者:罗健

概述

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

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

Camera Host驱动层架构图如下:
OpenHarmony——相机驱动框架模型-鸿蒙开发者社区

由于相机整个从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】

<font color=“red”>

int status = instance->StartService(instance);

</font>

由上面接口初始化,可以知道实际调用的是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;
}

<font color=“green”>

【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);
    }
}  

</font>

在这里创建好了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,管理相应的设备。
OpenHarmony——相机驱动框架模型-鸿蒙开发者社区

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流转的策略等
OpenHarmony——相机驱动框架模型-鸿蒙开发者社区

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框架

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享OpenHarmony开发技术,欢迎投稿和订阅,让我们一起携手前行共建生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-10-26 17:11:56修改
3
收藏 3
回复
举报
2条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

非常详细的讲解,必须好好收藏学习。

回复
2022-8-4 14:13:13
LoinDIci
LoinDIci

1、这是在v3.1版本上的吧?

2、CMOS sensor、isp驱动这块能出个走mpp框架的解析吗、V4L2在小系统上不大适用的样子?

4、期待大佬再出个继续往下深入的教程

回复
2022-8-16 10:51:04
回复
    相关推荐