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框架
更多原创内容请关注:深开鸿技术团队
入门到精通、技巧到案例,系统化分享OpenHarmony开发技术,欢迎投稿和订阅,让我们一起携手前行共建生态。
非常详细的讲解,必须好好收藏学习。
1、这是在v3.1版本上的吧?
2、CMOS sensor、isp驱动这块能出个走mpp框架的解析吗、V4L2在小系统上不大适用的样子?
4、期待大佬再出个继续往下深入的教程