天天看點

OpenHarmony——相機驅動架構模型

作者:羅健

概述

相機驅動架構模型(後面文章中稱為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】

<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,管理相應的裝置。

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流轉的政策等

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開發技術,歡迎投稿和訂閱,讓我們一起攜手前行共建鴻蒙生态。

繼續閱讀