鸿蒙进阶——驱动框架UHDF 机制核心源码解读(一)
文章大纲
- 引言
- 一、uhdf 概述
- 二、uhdf 的核心参与角色
- 1、drivers/hdf_core/adapter/uhdf2/manager/device_manager.c
- 1.1、drivers/hdf_core/framework/core/manager/src/devmgr_service.c#DevmgrServiceGetInstance通过objectId获取IDevmgrService实例
- 1.2、drivers/hdf_core/framework/core/shared/src/hdf_object_manager.c#HdfObjectManagerGetObject——>HdfObjectManagerGetCreators
- 2、drivers/hdf_core/adapter/uhdf2/host/devhost.c、driver_loader_full.c和device_info.hcs
- 三、hdf_device_manager的启动
- 1、DevmgrServiceGetInstance()
- 2、IDevmgrService#StartService(instance)——>drivers/hdf_core/framework/core/manager/src/devmgr_service.c#DevmgrServiceStartService
- 2.1、DevSvcManagerStartService()
- 2.2、DevmgrServiceStartDeviceHosts
引言
前面两篇文章从理论的角度简单介绍了下HDF驱动框架的基本理论知识和原理,接下来就从源码角度介绍下UHDF核心工作流程。
一、uhdf 概述
区别于传统的硬件驱动khdf,OpenHarmony还设计了一层uhdf,本质上就是一个应用进程,主要是面向用户层提供与驱动的交互接口层。与khdf一样每一个uhdf 都需要注册到device_info.hcs文件内,当然了uhdf 正常工作时是离不开khdf的。
二、uhdf 的核心参与角色
NNRT HOST 的启动也是由uhdf 驱动的,以下是uhdf工作流程
1、drivers/hdf_core/adapter/uhdf2/manager/device_manager.c
device_manager.c承担着所有硬件外设的管理角色,所有设备的host_service服务都由它统一管理,再由devhost.c创建对应的xxx_host_service需要主动注册到device_manager中,当需要使用时直接通过device_manager获取并使用。
int main()
{HDF_LOGI("start hdf device manager");int status = HDF_FAILURE;struct IDevmgrService* instance = DevmgrServiceGetInstance();if (instance->StartService != NULL) {status = instance->StartService(instance);}(void)DevMgrUeventReceiveStart();DevMgrRegisterDumpFunc();if (status == HDF_SUCCESS) {struct DevmgrServiceFull *fullService = (struct DevmgrServiceFull *)instance;struct HdfMessageLooper *looper = &fullService->looper;if ((looper != NULL) && (looper->Start != NULL)) {looper->Start(looper);}}HDF_LOGE("starting device manager service failed, status is %{public}d", status);return status;
}
1.1、drivers/hdf_core/framework/core/manager/src/devmgr_service.c#DevmgrServiceGetInstance通过objectId获取IDevmgrService实例
struct IDevmgrService *DevmgrServiceGetInstance(void)
{static struct IDevmgrService *instance = NULL;if (instance == NULL) {instance = (struct IDevmgrService *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVMGR_SERVICE);}return instance;
}
1.2、drivers/hdf_core/framework/core/shared/src/hdf_object_manager.c#HdfObjectManagerGetObject——>HdfObjectManagerGetCreators
不同的Service 有各自对应的HdfObjectManagerGetCreators 实现。
2、drivers/hdf_core/adapter/uhdf2/host/devhost.c、driver_loader_full.c和device_info.hcs
.hcs是开发者注册hdf驱动列表的配置文件,再编译后会结合SeLinux 策略重新编译整理成.hcg文件,同时devhost.c 成为一个可执行文件,当需要拉起对应的uhdf _host_service时被执行,所以有可能被执行多次,而需要注意的是dev_host相当于是只是一个空壳,还需要driver_loader_full.c 来把真正这个uhdf 驱动的真正的业务逻辑对应的so 加载进来,才能成为一个真正的uhdf 设备驱动并且将其句柄缓存至系统的设备驱动列表中。以nnrt_host为例,当我们把nnrt_host 的uhdf驱动的信息添加到.hcs驱动列表文件后,当系统遍历时就会去执行devhost.c的main函数解析.hcg的信息,创建对应的nnrt_host的实例句柄并且加载其相应的so,再把符号连接到对应的位置,拉起对应的进程。
NNRT HOST 启动三部曲
三、hdf_device_manager的启动
系统启动过程中首先是由脚本触发device_manager#main函数执行
int main()
{HDF_LOGI("start hdf device manager");int status = HDF_FAILURE;struct IDevmgrService* instance = DevmgrServiceGetInstance();...if (instance->StartService != NULL) {status = instance->StartService(instance);}(void)DevMgrUeventReceiveStart();DevMgrRegisterDumpFunc();if (status == HDF_SUCCESS) {struct DevmgrServiceFull *fullService = (struct DevmgrServiceFull *)instance;struct HdfMessageLooper *looper = &fullService->looper;if ((looper != NULL) && (looper->Start != NULL)) {looper->Start(looper);}}...return status;
}
1、DevmgrServiceGetInstance()
通过传入HDF_OBJECT_ID_DEVMGR_SERVICE作为objectId 获取IDevmgrService 的指针。
drivers/hdf_core/framework/core/manager/src/devmgr_service.c
struct IDevmgrService *DevmgrServiceGetInstance(void)
{static struct IDevmgrService *instance = NULL;if (instance == NULL) {instance = (struct IDevmgrService *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVMGR_SERVICE);}return instance;
}
然后drivers/hdf_core/framework/core/shared/src/hdf_object_manager.c#HdfObjectManagerGetObject 里触发Create函数指针
struct HdfObject *HdfObjectManagerGetObject(int objectId)
{struct HdfObject *object = NULL;const struct HdfObjectCreator *targetCreator = HdfObjectManagerGetCreators(objectId);if ((targetCreator != NULL) && (targetCreator->Create != NULL)) {// 触发函数指针Create 执行object = targetCreator->Create();if (object != NULL) {object->objectId = objectId;}}return object;
}
在drivers/hdf_core/framework/core/common/src/devlite_object_config.c里定义了一个常量结构体,可以根据objectId拿到对应的成员变量并执行其Create指针指向的函数
const struct HdfObjectCreator *HdfObjectManagerGetCreators(int objectId)
{int numConfigs = sizeof(g_liteObjectCreators) / sizeof(g_liteObjectCreators[0]);if ((objectId >= 0) && (objectId < numConfigs)) {return &g_liteObjectCreators[objectId];}return NULL;
}static const struct HdfObjectCreator g_liteObjectCreators[] = {[HDF_OBJECT_ID_DEVMGR_SERVICE] ={.Create = DevmgrServiceCreate,.Release = DevmgrServiceRelease,},[HDF_OBJECT_ID_DEVSVC_MANAGER] ={.Create = DevSvcManagerExtCreate,.Release = DevSvcManagerExtRelease,},[HDF_OBJECT_ID_DEVHOST_SERVICE] ={.Create = DevHostServiceCreate,.Release = DevHostServiceRelease,},[HDF_OBJECT_ID_DRIVER_INSTALLER] ={.Create = DriverInstallerCreate,.Release = NULL,},[HDF_OBJECT_ID_DRIVER_LOADER] ={.Create = HdfDriverLoaderCreate,.Release = NULL,},[HDF_OBJECT_ID_DEVICE] ={.Create = HdfDeviceCreate,.Release = HdfDeviceRelease,},[HDF_OBJECT_ID_DEVICE_TOKEN] ={.Create = HdfDeviceTokenCreate,.Release = HdfDeviceTokenRelease,},[HDF_OBJECT_ID_DEVICE_SERVICE] ={.Create = DeviceNodeExtCreate,.Release = DeviceNodeExtRelease,}
};
触发函数指针Create 即执行DevmgrServiceCreate 给IDevmgrService结构体指针函数赋值后再返回。
bool DevmgrServiceConstruct(struct DevmgrService *inst)
{struct IDevmgrService *devMgrSvcIf = NULL;...devMgrSvcIf = (struct IDevmgrService *)inst;if (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;DListHeadInit(&inst->hosts);return true;} else {return false;}
}
2、IDevmgrService#StartService(instance)——>drivers/hdf_core/framework/core/manager/src/devmgr_service.c#DevmgrServiceStartService
int DevmgrServiceStartService(struct IDevmgrService *inst)
{int ret;struct DevmgrService *dmService = (struct DevmgrService *)inst;...ret = DevSvcManagerStartService();HDF_LOGI("start svcmgr result %{public}d", ret);return DevmgrServiceStartDeviceHosts(dmService);
}
2.1、DevSvcManagerStartService()
DevSvcManagerGetInstance——>HdfObjectManagerGetObject——>HdfObjectManagerGetCreators——>根据objectId去HdfObjectCreator数组中去获取对应的指针,并触发Create函数指针
drivers/hdf_core/framework/core/manager/src/devmgr_service.c
int DevSvcManagerStartService(void)
{int ret;struct IDevSvcManager *svcmgr = DevSvcManagerGetInstance();if (svcmgr->StartService == NULL) {return HDF_SUCCESS;}//触发DevSvcManagerStubStartret = svcmgr->StartService(svcmgr);if (ret != HDF_SUCCESS) {HDF_LOGE("failed to start service manager");}return ret;
}
和上面类似先是执行Create 函数指针即DevSvcManagerStubCreate,并给StartService函数指针赋值
struct HdfObject *DevSvcManagerStubCreate(void)
{static struct DevSvcManagerStub *instance;instance = OsalMemCalloc(sizeof(struct DevSvcManagerStub));if (!DevSvcManagerStubConstruct(instance)) {OsalMemFree(instance);instance = NULL;}return (struct HdfObject *)instance;
}
static bool DevSvcManagerStubConstruct(struct DevSvcManagerStub *inst)
{...//给IDevSvcManager 的函数指针赋值if (!DevSvcManagerConstruct(&inst->super)) {HDF_LOGE("failed to construct device service manager");return false;}inst->super.super.StartService = DevSvcManagerStubStart;OsalMutexInit(&inst->devSvcStubMutex);HdfSListInit(&inst->devObjHolderList);return true;
}执行了上面后IDevSvcManager的函数指针StartService被赋值为DevSvcManagerStubStart并随即执行,用于注册到HDF和IPC相关的。
●HdfRemoteDispatcher 的Dispatch 函数指针被赋值为DevSvcManagerStubDispatch
●给DevSvcManagerStub的remote 对象赋值为远端代理对象以及监听远端代理对象死亡时间
●执行注册
drivers/hdf_core/adapter/uhdf2/manager/src/devsvc_manager_stub.c
int DevSvcManagerStubStart(struct IDevSvcManager *svcmgr)
{struct DevSvcManagerStub *inst = (struct DevSvcManagerStub *)svcmgr;...ServStatListenerHolderinit();...//后面IPC时会用到static struct HdfRemoteDispatcher dispatcher = {.Dispatch = DevSvcManagerStubDispatch};inst->remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher);if (inst->remote == NULL) {HDF_LOGE("failed to obtain device service manager remote service");return HDF_ERR_MALLOC_FAIL;}if (!HdfRemoteServiceSetInterfaceDesc(inst->remote, "HDI.IServiceManager.V1_0")) {HDF_LOGE("%{public}s: failed to init interface desc", __func__);HdfRemoteServiceRecycle(inst->remote);return HDF_ERR_INVALID_OBJECT;}inst->recipient.OnRemoteDied = DevSvcManagerOnServiceDied;//注册并发布int ret = HdfRemoteServiceRegister(DEVICE_SERVICE_MANAGER_SA_ID, inst->remote);if (ret != 0) {HDF_LOGE("failed to publish device service manager, %{public}d", ret);HdfRemoteServiceRecycle(inst->remote);inst->remote = NULL;} else {HDF_LOGI("publish device service manager success");inst->started = true;}return ret;
}
执行注册
drivers/hdf_core/adapter/uhdf2/ipc/src/hdf_remote_service.c
int HdfRemoteServiceRegister(int32_t serviceId, struct HdfRemoteService *service)
{return HdfRemoteAdapterAddSa(serviceId, service);
}int HdfRemoteAdapterAddSa(int32_t saId, struct HdfRemoteService *service)
{...auto saManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();const int32_t waitTimes = 50;const int32_t sleepInterval = 20000;int32_t timeout = waitTimes;while (saManager == nullptr && (timeout > 0)) {HDF_LOGI("waiting for samgr...");usleep(sleepInterval);saManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();timeout--;}struct HdfRemoteServiceHolder *holder = reinterpret_cast<struct HdfRemoteServiceHolder *>(service);int ret = saManager->AddSystemAbility(saId, holder->remote_);(void)OHOS::IPCSkeleton::GetInstance().SetMaxWorkThreadNum(g_remoteThreadMax++);HDF_LOGI("add sa %{public}d, ret = %{public}s", saId, (ret == 0) ? "succ" : "fail");...return HDF_SUCCESS;
}
原来注册、发布的对象都是SA,接下来就是SA相关的管理逻辑了。
2.2、DevmgrServiceStartDeviceHosts
static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
{int ret;struct HdfSList hostList;struct HdfSListIterator it;struct HdfHostInfo *hostAttr = NULL;HdfSListInit(&hostList);if (!HdfAttributeManagerGetHostList(&hostList)) {HDF_LOGW("%s: host list is null", __func__);return HDF_SUCCESS;}HdfSListIteratorInit(&it, &hostList);while (HdfSListIteratorHasNext(&it)) {hostAttr = (struct HdfHostInfo *)HdfSListIteratorNext(&it);ret = DevmgrServiceStartDeviceHost(inst, hostAttr);if (ret != HDF_SUCCESS) {HDF_LOGW("%{public}s failed to start device host, host id is %{public}u, host name is '%{public}s'",__func__, hostAttr->hostId, hostAttr->hostName);}}HdfSListFlush(&hostList, HdfHostInfoDelete);return HDF_SUCCESS;
}
然后DevmgrServiceStartHostProcess 里通过IDriverInstaller 启动StartDeviceHost,即执行DriverInstallerFullStartDeviceHost
static int DevmgrServiceStartHostProcess(struct DevHostServiceClnt *hostClnt, bool sync, bool dynamic)
{HDF_LOGE("NNRT#DevmgrServiceStartHostProcess ");int waitCount = WAIT_HOST_SLEEP_CNT;struct IDriverInstaller *installer = DriverInstallerGetInstance();if (installer == NULL || installer->StartDeviceHost == NULL) {HDF_LOGE("invalid installer");return HDF_FAILURE;}hostClnt->hostPid = installer->StartDeviceHost(hostClnt->hostId, hostClnt->hostName, dynamic);if (hostClnt->hostPid == HDF_FAILURE) {HDF_LOGW("failed to start device host(%{public}s, %{public}u)", hostClnt->hostName, hostClnt->hostId);return HDF_FAILURE;}hostClnt->stopFlag = false;if (!sync) {return HDF_SUCCESS;}while (hostClnt->hostService == NULL && waitCount > 0) {OsalMSleep(WAIT_HOST_SLEEP_TIME);waitCount--;}if (waitCount <= 0) {HDF_LOGE("wait host(%{public}s, %{public}d) attach timeout", hostClnt->hostName, hostClnt->hostId);hostClnt->hostPid = -1;return HDF_ERR_TIMEOUT;}return HDF_SUCCESS;
}
然后installer->StartDeviceHost
int DriverInstallerFullStartDeviceHost(uint32_t devHostId, const char* devHostName, bool dynamic)
{if (dynamic) {int ret = ServiceControlWithExtra(devHostName, START, NULL, 0);HDF_LOGD("%{public}s %{public}s %{public}d %{public}d", __func__, devHostName, devHostId, ret);}return HDF_SUCCESS;
}
在base/startup/init/interfaces/innerkits/service_control/service_control.c#ServiceControlWithExtra里真正开始启动进程
int ServiceControlWithExtra(const char *serviceName, int action, const char *extArgv[], int extArgc)
{BEGET_ERROR_CHECK(serviceName != NULL, return -1, "Service name is null.");int ret = 0;switch (action) {case START:ret = StartProcess(serviceName, extArgv, extArgc);break;case STOP:ret = StopProcess(serviceName);break;case RESTART:ret = RestartProcess(serviceName, extArgv, extArgc);break;default:BEGET_LOGE("Set service %s action %d error", serviceName, action);ret = -1;break;}return ret;
}
未完待续…