OpenHarmony驱动框架HDF中设备管理服务构建过程详解(一)

作者: 侯旗

前言

如下图,开源鸿蒙系统驱动框架HDF在内核中的实现,可以分为向用户层提供设备服务的管理模块(Manager),和实际管理硬件的Host模块。
Manager分为DeviceManageService和 DeviceServiceManage,前者负责提供服务的设备,包括设备驱动匹配、设备驱动装载、设备启动等;后者负责关联设备提供的服务,包括管理Host端提供的设备服务,和接收用户发起的设备服务订阅请求。

图1 开源鸿蒙系统驱动框架软件架构模块图

本文主要关注点在DeviceManageService,叙述其如何启动设备、创建设备服务节点、装载驱动,以及发布服务的过程。

文章内容简介

开源鸿蒙系统驱动框架HDF内核实现部分完全使用C语言实现,也引入了面向对象编程的思想,使用C语言实现了诸如类继承、虚函数、单例类等的概念,使得HDF内核部分包含了大量的对象类型,对象类型又通过的接口形式对外提供服务。

为了向读者展现开源鸿蒙系统驱动框架HDF内核实现蓝图,本文仅仅介绍介绍DevMgr过程中Manager域和Host域内的对象类型与其接口,先奠定读者对HDF内对象类型的基本认识;然后,在下一篇文章中介绍DevMgrService如何启动设备、装载驱动、发布设备服务的整个过程。

本文章节内容如下:

    1. DevMgr域中的对象类型及接口
    1. Host域中的对象类型及接口

1 DevMgr域中的对象类型及接口

1.1 DevmgrService

1.1.1 DevmgrService及接口

DevmgrService是设备管理的总入口,其Hosts域是一个双向链表,hcs设备配置中的所有Host设备被挂载在这个Hosts双向链表上。

DevmgrService内容及其接口定义如下:

struct IDevmgrService {
    struct HdfObject base;
    struct HdfDeviceObject object;
    // 将Host节点链接到DevMgr的hosts列表
    int (*AttachDeviceHost)(struct IDevmgrService *, uint16_t, struct IDevHostService *);
    // 将HDF设备节点以Token的形式连接到host的devices列表
    int (*AttachDevice)(struct IDevmgrService *, const struct HdfDeviceInfo *, struct IHdfDeviceToken *);
    // 启动DevmgrService服务
    int (*StartService)(struct IDevmgrService *);
    int (*PowerStateChange)(struct IDevmgrService *, enum HdfPowerState pEvent);
};

struct DevmgrService {
    struct IDevmgrService super;
    struct DListHead hosts;
    struct OsalMutex devMgrMutex;
};

由DevmgrService结构体的内容可知,DevmgrService只管理者host设备节点。 有下面章节可知,Host节点下的所有设备则由Host自己管理。

1.1.2 DevMgrService构建过程

下面DevMgrService构建过程,HDF内核实现部分中使用static局部变量实现了C++中单例类的概念,将DevMgrService作为一个单例类,所有的对象指向同一个实体。

 DevmgrServiceCreate()
    |  // C++,单例类概念
    |-> static struct DevmgrService devmgrServiceInstance;
    |-> DevmgrServiceConstruct(&devmgrServiceInstance)
        |-> devMgrSvcIf = (struct IDevmgrService *)inst;
        |
        |-> devMgrSvcIf->AttachDevice =  DevmgrServiceAttachDevice;
        |-> devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;
        |-> devMgrSvcIf->StartService =  DevmgrServiceStartService;
        |-> devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange;

1.1.3 IDevmgrService接口介绍
(1)StartService:DevmgrServiceStartService()

DevmgrServiceStartService()主要功能是挂载并启动hcs设备配置中的所有host设备节点DevmgrService的hosts链表;然后,启动host节点,间接地启动Host节点下的所有设备(装载设备驱动、发布设备服务等)。

DevmgrServiceStartService()
|-> DevmgrServiceStartDeviceHosts()
    |-> DriverInstallerGetInstance() //  installer
    | // (1) 为每一个Hcs配置中的Host设备创建一个DevHostClnt
    |-> HdfAttributeManagerGetHostList(&hostList);
    |-> HdfSListIteratorInit(&it, &hostList);
    |-> hostAttr = HdfSListIteratorNext(&it);
    |
    |-> hostClnt = DevHostServiceClntNewInstance(
    |                    hostAttr->hostId,
    |                    hostAttr->hostName);
    | // (2) 添加HostClnt到DevMgr的hosts链表
    |-> DListInsertTail(&hostClnt->node, &inst->hosts);
    |
    | // (3) 启动host设备对应的DevHostClnt。
    |-> hostClnt->hostPid = installer->StartDeviceHost()

(2)AttachDeviceHost:DevmgrServiceAttachDeviceHost()

DevmgrServiceAttachDeviceHost()遍历host节点先的所有设备信息,使用DriverLoader构建设备节点,装载驱动,发布服务,然后将设备链接到Host的devices列表。

DevmgrServiceAttachDeviceHost( struct IDevmgrService *inst, uint16_t hostId,
|                               struct IDevHostService *hostService) 
|
| // DevHostServiceClnt 已经在 StartDeviceHost() 内按照hcs设备配置树中的host节点创建
|-> struct DevHostServiceClnt *hostClnt = DevmgrServiceFindDeviceHost(inst, hostId);
|
|-> hostClnt->hostService = hostService;
|   // 获得Host节点下所有的设备节点配置信息
|-> hostClnt->deviceInfos = HdfAttributeManagerGetDeviceList()
|-> hostClnt->devCount = HdfSListCount(hostClnt->deviceInfos);
|
|-> DevHostServiceClntInstallDriver(hostClnt)
    | // 遍历 Host 节点下的所有设备(设备+驱动),并将它们挂载到host的devices列表
    |-> HdfSListIteratorInit(&it, hostClnt->deviceInfos);
    |-> deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&it);
    |-> devHostSvcIf->AddDevice(devHostSvcIf, deviceInfo);

(3) AttachDevice:DevmgrServiceAttachDevice

被AttachDeviceHost接口实现DevmgrServiceAttachDeviceHost()调用,在完成host下的设备的驱动匹配、装载及设备服务发布后,将HdfDeviceNode以Token的Token 的形式挂接到 DevHostServiceClnt 的 devices 链表。具体过程如下:

DevmgrServiceAttachDevice(struct IDevmgrService *inst, 
|                          const struct HdfDeviceInfo *deviceInfo,
|                          struct IHdfDeviceToken *token)
|
|-> struct DevHostServiceClnt *hostClnt = DevmgrServiceFindDeviceHost(inst, deviceInfo->hostId);
|-> struct DeviceTokenClnt *tokenClnt = 
|                DeviceTokenClntNewInstance(token); // tokenClnt包含指针指向DeviceToken
|                |-> tokenClnt = (struct DeviceTokenClnt *)OsalMemCalloc(sizeof(struct DeviceTokenClnt));
|                |-> DeviceTokenClntConstruct(tokenClnt, tokenIf);
|                    |-> tokenClnt->tokenIf = tokenIf;
|
|-> tokenClnt->deviceInfo = deviceInfo;
|-> DevmgrServiceUpdateStatus(hostClnt, deviceInfo->deviceId, HDF_SERVICE_USABLE);
|-> HdfSListAdd(&hostClnt->devices, &tokenClnt->node);

1.2 DevHostServiceClnt

1.2.1 DevHostServiceClnt对象类型

DevHostServiceClnt为Host域内DevHostService的概念在Manager域的一个表示,hostService成员为IDevHostService的指针,指向被DevHostService包含的IDevHostService对象地址。此处,又借鉴了C++中基类的概念。

struct DevHostServiceClnt {
    struct DListHead node;               // 链表节点,host设备依次对象挂载在DevMgrService的hosts链表上
    struct HdfSList devices;             // 链表,挂载所有host下的所有设备(以token的形式)
    struct HdfSList *deviceInfos;        // 属于Host设备的所有子设备的devInfo信息
    Map *deviceHashMap;
    struct IDevHostService *hostService; // 指向Host域的host设备服务的实现
    uint16_t devCount;                   // 子设备个数
    uint16_t hostId;                     // 系统内Host设备节点标识,按照加载顺序依次+1;
    int hostPid;                         // 父Host设备节点标识
    const char *hostName;                // Host设备名
};

1.2.2 DevHostServiceClnt 构建流程

DevHostServiceClnt的构建过程如下,若该DevHostServiceClnt不存在,则创建一个对象,初始化其hostService和deviceInfos成员,在其下的设备完全启动后,则将该对象链接到DevMgrService的hosts链表。

static int DevmgrServiceAttachDeviceHost(
    struct IDevmgrService *inst, uint16_t hostId, struct IDevHostService *hostService)
{
    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;
    hostClnt->deviceInfos = HdfAttributeManagerGetDeviceList(hostClnt->hostId, hostClnt->hostName);
    if (hostClnt->deviceInfos == NULL) {
        HDF_LOGW("failed to get device list ");
        return HDF_SUCCESS;
    }
    hostClnt->devCount = HdfSListCount(hostClnt->deviceInfos);
    return DevHostServiceClntInstallDriver(hostClnt);
}

2 Host域内对象类型与接口

2.1 DriverInstaller

2.1.1 DriverInstaller 结构体内容描述

DriverInstaller的功能是根据Hcs设备配置文件中的host节点的名称,启动Host节点服务,包括依次创建Host节点下的所有设备、匹配设备驱动、初始化驱动,发布设备服务等。DriverInstaller的内容定义如下:

struct IDriverInstaller {
    struct HdfObject object;
    int (*StartDeviceHost)(uint32_t, const char *);
};

struct DriverInstaller {
    struct IDriverInstaller super;
};

2.1.2 DriverInstaller构建过程

DriverInstaller 也作为单例类,使用同一个局部static变量实现。

DriverInstallerCreate()
|-> static struct DriverInstaller driverInstaller;
|
|-> DriverInstallerConstruct(&driverInstaller);
    |-> driverInstallIf->StartDeviceHost = DriverInstallerStartDeviceHost;

2.1.3 DriverInstaller 接口简介StartDeviceHost : DriverInstallerStartDeviceHost()

DriverInstallerStartDeviceHost()名义上是启动Host节点服务,实则通过DevMgrService在Host域的client(DevmgrServiceClnt)挂载Host节点到DevMgrService的hosts链表,同时还通过DevHostService的AddDevice()接口将host节点其下的所有设备依次匹配驱动、加载驱动、发布设备服务等。

DriverInstallerStartDeviceHost(uint32_t devHostId, const char *devHostName)
| // 创建Host端DevService
|-> struct IDevHostService *hostServiceIf = DevHostServiceNewInstance(devHostId, devHostName);
|
| // hostServiceIf->StartService(hostServiceIf);
|-> DevHostServiceStartService()
    |-> DevmgrServiceClntAttachDeviceHost()
        | // 创建Host端的DevMgr的Client(“代理”,更合适), DevmgrServiceClnt即IDevmgrService
        |-> struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
        |
        | // 将hostService、devInfo和hostClnt关联,并装载匹配的设备驱动
        | // devMgrSvcIf->AttachDeviceHost()
        |-> DevmgrServiceAttachDeviceHost() 
            |-> struct DevHostServiceClnt *hostClnt = DevmgrServiceFindDeviceHost(inst, hostId);
            |-> hostClnt->hostService = hostService;
            |-> hostClnt->deviceInfos = HdfAttributeManagerGetDeviceList()
            |-> DevHostServiceClntInstallDriver(hostClnt)

2.2 DriverLoader

2.2.1 DriverLoader 结构体

DriverLoader主要是完成Host节点下的设备的装载,包括匹配驱动(GetDriverEntry())、初始化驱动、发布设备服务等。

struct IDriverLoader {
    struct HdfObject object;
    struct HdfDriverEntry *(*GetDriverEntry)(const struct HdfDeviceInfo *deviceInfo);
    struct HdfDeviceNode *(*LoadNode)(struct IDriverLoader *, const struct HdfDeviceInfo *deviceInfo);
    void (*UnLoadNode)(struct IDriverLoader *, const struct HdfDeviceInfo *deviceInfo);
};

struct HdfDriverLoader {
    struct IDriverLoader super;
};

2.2.2 DriverLoader 构建

DriverLoader 同样也作为单例类,使用同一个局部static变量实现,比较其不独占任何设备,只是完成设备节点驱动的装载。

HdfDriverLoaderCreate()
|-> static struct HdfDriverLoader driverLoader;
|
|-> HdfDriverLoaderConstruct(&driverLoader);
    |-> struct IDriverLoader *driverLoaderIf = (struct IDriverLoader *)inst;
    |-> driverLoaderIf->LoadNode = HdfDriverLoaderLoadNode;
    |-> driverLoaderIf->UnLoadNode = HdfDriverLoaderUnLoadNode;
    |-> driverLoaderIf->GetDriverEntry = HdfDriverLoaderGetDriverEntry;

2.2.3 DriverLoader 接口简介
(1) GetDriverEntry : HdfDriverLoaderGetDriverEntry()

从DriverEntry列表中获得指定设备的驱动:

HdfDriverLoaderGetDriverEntry()
|-> static struct HdfDriverEntry *driverEntry = NULL;
|-> static int32_t driverCount = 0;
|
|-> strcmp(deviceInfo->moduleName, driverEntry[i].moduleName) == 0
|-> return &driverEntry[i];

(2) LoadNode : HdfDriverLoaderLoadNode()

简介调用自己的接口GetDriverEntry()完成驱动匹配,然后将设备驱动提供的ioService与HdfDeviceNode的IoService绑定。

HdfDriverLoaderLoadNode(struct IDriverLoader *loader,
|                          const struct HdfDeviceInfo *deviceInfo)
|    // 获得对应设备驱动对象
|-> driverEntry = loader->GetDriverEntry(deviceInfo);
|    // 创建设备节点
|-> devNode = HdfDeviceNodeNewInstance();
|    // 绑定驱动与设备节点
|-> devNode->driverEntry = driverEntry;
|-> devNode->deviceInfo = deviceInfo;
|   // 绑定设备服务与IoService
|-> driverEntry->Bind(&devNode->deviceObject)
|
|-> return devNode;

2.3 DevHostService

Sorry,前面引用了那么多Host,一直未明确其概念。 Host在开源鸿蒙系统中可以理解为平台设备子系统,例如display、Input、Network、Sensor、storage等,在这些子系统中又保护了多种接口的实现。以Display子系统为例,可以是SPI接口的设备,也可以是SDIO接口的设备;而具体到SPI设备,有包括了SPI设备1、2、3等。所以才有了“图1.1.1 DevMgr与host及设备关系图”描述的Host与设备之间的关系。

在host域中,使用DevHostService为host设备节点。

2.3.1 DevHostService 结构体

DevHostService作为Host设备在Host域中的表示,管理着其下的所有设备,每一个具体的设备都以HdfDevice的形式挂载到DevHostService的devices链表,不同于DevHostServiceClnt对设备的管理。

struct IDevHostService {
    struct HdfObject object;
	// 添加设备到DevHostService到devices链表
    int (*AddDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo);
    int (*DelDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo);
	// 启动host服务
    int (*StartService)(struct IDevHostService *hostService);
    int (*PmNotify)(struct IDevHostService *service, uint32_t powerState);
};

struct DevHostService {
    struct IDevHostService super;
    uint16_t hostId; 				// host设备在系统中的唯一表示,按照加载顺序,依次+1
    const char *hostName;
    struct DListHead devices;		// 链表,挂载着host下所有设备的
    struct HdfServiceObserver observer;
    struct HdfSysEventNotifyNode sysEventNotifyNode;
}

2.3.2 DevHostService 构建流程

DevHostService对象的构建比较简单,分配内存,然后初始化,因为对应的是一个个的Host节点,所有也没有单例类的感念。

void DevHostServiceConstruct(struct DevHostService *service)
{
    struct IDevHostService *hostServiceIf = &service->super;
    if (hostServiceIf != NULL) {
        hostServiceIf->AddDevice = DevHostServiceAddDevice;
        hostServiceIf->DelDevice = DevHostServiceDelDevice;
        hostServiceIf->StartService = DevHostServiceStartService;
        hostServiceIf->PmNotify = DevHostServicePmNotify;
        DListHeadInit(&service->devices);
        HdfServiceObserverConstruct(&service->observer);
    }
}

2.3.3 IDevHostService 接口简介
(1)StartService : DevHostServiceStartService()

DevHostServiceStartService()启动HostService,间接调用AddDevice接口,依次加载host下的所有子设备。

DevHostServiceStartService(struct IDevHostService *service)
|-> DevmgrServiceClntAttachDeviceHost()
    |  //  通过DevMgr在Host端的Client,调用
    |-> DevmgrServiceAttachDeviceHost()
        | // 将DevService和deviceInfo与DevHostClnt关联。
        |-> hostClnt->hostService = hostService;
        |-> hostClnt->deviceInfos = HdfAttributeManagerGetDeviceList()
        |
        |-> DevHostServiceClntInstallDriver(hostClnt)
            |-> devHostSvcIf = (struct IDevHostService *)hostClnt->hostService;
            |-> HdfSListIteratorInit(&it, hostClnt->deviceInfos);
            |-> deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&it);
            |-> devHostSvcIf->AddDevice(devHostSvcIf, deviceInfo);

(2)AddDevice : DevHostServiceAddDevice()

DevHostServiceAddDevice()的功能前面有所带过,主要是根据deviceInfo创建HdfDevice对象、匹配设备驱动、装载设备驱动、DevHostServiceClnt的devcies链表等。

DevHostServiceAddDevice(struct IDevHostService *inst, struct HdfDeviceInfo *deviceInfo)
|-> struct HdfDevice *device = NULL;
|-> struct DevHostService *hostService = CONTAINER_OF(inst, struct DevHostService, super);
|
|-> device = DevHostServiceGetDevice(hostService, deviceInfo->deviceId);
|
|-> devNode = driverLoader->LoadNode(driverLoader, deviceInfo);
|                            |-> HdfDriverLoaderLoadNode()
|                                |-> 
|                                |-> 
|                                |-> driverEntry = loader->GetDriverEntry(deviceInfo);
|                                |                          |-> HdfDriverLoaderGetDriverEntry()
|                                | 
|                                |-> devNode = HdfDeviceNodeNewInstance();
|                                |-> devNode->driverEntry = driverEntry;
|                                |-> devNode->deviceInfo = deviceInfo;
|                                |-> devNode->deviceObject.xx = xx;
|                                | // 绑定HdfDevice与DeviceIoService
|                                | // Device -> service -> Dispatch
|                                |-> driverEntry->Bind(&devNode->deviceObject)
| // 将服务于设备相关联
|-> devNode->hostService = hostService;
| // 挂载DevNode到设备(同一接口设备类)的节点列表(一个设备类中的一个具体设备)
|-> device->super.Attach(&device->super, devNode);

2.4 HdfDevice

2.4.1 HdfDevice 及接口

HdfDevice为Host下的设备在Host域内的表示,内容如下:

struct IHdfDevice {
    struct HdfObject object;
	// 挂载HdfDeviceNode到HdfDevice的node链表
    int (*Attach)(struct IHdfDevice *, struct HdfDeviceNode *);
    void (*Detach)(struct IHdfDevice *, struct HdfDeviceNode *);
};

struct HdfDevice {
    struct IHdfDevice super;
    struct DListHead node;
    struct DListHead devNodes;  // 某接口相同的设备类的具体设备节点,如I2C总线上挂着设备0,设备1
    uint16_t deviceId;          // 接口相同的设备类,例如UART、I2C等。
    uint16_t hostId;            // 应用子设备系统类,例如:display、Input、Network、Sensor、storage等。
};

2.4.2 HdfDevice 构建流程

比较简单,分配对象内存空间,然后初始化接口和其中的链表:

void HdfDeviceConstruct(struct HdfDevice *device)
{
    device->super.Attach = HdfDeviceAttach;
    DListHeadInit(&device->devNodes);
}

struct HdfObject *HdfDeviceCreate()
{
    struct HdfDevice *device =
        (struct HdfDevice *)OsalMemCalloc(sizeof(struct HdfDevice));
    if (device != NULL) {
        HdfDeviceConstruct(device);
    }
    return (struct HdfObject *)device;
}

HdfDevice为Host域内一个设备的表示,一个HdfDevice可以对应多个DeviceNode节点,但是一个DeviceNode节点只对应一个设备驱动。即用户可以将设备驱动程序进行分层,协同完成对设备的支撑。

2.4.3 IHdfDevice 接口 Attach 简介

HdfDeviceAttach()的功能是(1)将设备Node节点挂载到设备的DevNode检点链表上;(2)然后启动节点,即初始化驱动、发布设备服务等。

static int HdfDeviceAttach(struct IHdfDevice *devInst, struct HdfDeviceNode *devNode)
{
    struct HdfDevice *device = (struct HdfDevice *)devInst;
    struct IDeviceNode *nodeIf = (struct IDeviceNode *)devNode;
    if (device == NULL || nodeIf == NULL || nodeIf->LaunchNode == NULL) {
        HDF_LOGE("failed to attach device, input params invalid");
        return HDF_ERR_INVALID_PARAM;
    }
    DListInsertTail(&devNode->entry, &device->devNodes);
    return nodeIf->LaunchNode(devNode, devInst);
}

2.5 HdfDeviceNode(DeviceNodeExt)

设备节点,对应着一个设备服务节点,与DriverEntry一一对应。

2.5.1 HdfDeviceNode与DeviceNodeExt对象类型定义

现在才是真正与驱动一一对应的设备节点,代表着一个服务设备。

struct IDeviceNode {
    struct HdfObject object;
	// 发布设备服务
    int (*PublishService)(struct HdfDeviceNode *, const char *);
	// 启动设备节点
    int (*LaunchNode)(struct HdfDeviceNode *, struct IHdfDevice *);
};

struct HdfDeviceNode {
    struct IDeviceNode super;
    struct DListHead entry;
    struct PowerStateToken *powerToken;
    struct DevHostService *hostService;
    struct HdfDeviceObject deviceObject;
    struct IHdfDeviceToken *token;
    struct HdfDriverEntry *driverEntry;
    const struct HdfDeviceInfo *deviceInfo;
};

struct DeviceNodeExt {
    struct HdfDeviceNode super;
    struct HdfIoService *ioService;
};

2.5.2 DeviceNodeExt 构建流程

DeviceNodeExt包含HdfDeviceNode,在C++上表现为继承关系,构建过程如下:

DeviceNodeExtCreate()
|-> struct DeviceNodeExt *instance =
|            (struct DeviceNodeExt *)OsalMemCalloc();
|
|-> DeviceNodeExtConstruct()
    |-> HdfDeviceNodeConstruct()
    |    |-> struct IDeviceNode *nodeIf = &devNode->super;
    |    |-> devNode->token = HdfDeviceTokenNewInstance();
    |    |-> nodeIf->LaunchNode = HdfDeviceLaunchNode;
    |    |-> nodeIf->PublishService = HdfDeviceNodePublishPublicService; // 被覆盖
    |
    |-> nodeIf->PublishService = DeviceNodeExtPublishService;

2.5.3 HdfDeviceNode 接口简介
(1)LaunchNode : HdfDeviceLaunchNode()

HdfDeviceLaunchNode()功能为启动设备节点,初始化设备驱动吗,间接地调用PublishService接口发布设备服务。

HdfDeviceLaunchNode(struct HdfDeviceNode *devNode, struct IHdfDevice *devInst)
|-> device = (struct HdfDevice *)devInst;
|-> driverEntry = devNode->driverEntry;
|
|    // (1)初始化设备驱动
|-> driverEntry->Init(&devNode->deviceObject);
|    // (2)发布设备服务,挂载
|-> HdfDeviceNodePublishService()
|    |  // 将设备节点发布到系统设备节点,并添加服务到DevSvcMgr的服务链表
|    |-> // nodeIf->PublishService()
|    |-> HdfDeviceNodePublishLocalService()
|
|    // (3)挂载HDFDevice到DevMgr的设备链表
|-> deviceToken = devNode->token;
|    // 挂载DevNode(通过DeviceToken)到DevHostServiceClnt的device链表上。
|-> DevmgrServiceClntAttachDevice()
    |-> DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
    |-> devMgrSvcIf = inst->devMgrSvcIf;
    | // 将Device挂载DevMgr的设备链表上,以DeviceTokenClnt的形式挂载
    |-> devMgrSvcIf->AttachDevice(devMgrSvcIf, deviceInfo, deviceToken);

(2)PublishService : HdfDeviceNodePublishPublicService()

发布设备服务即为发布设备节点(DevNode)头部的HdfObject

DeviceNodeExtPublishService(struct HdfDeviceNode *inst, const char *serviceName)
|-> HdfDeviceNodePublishPublicService() // 发布Public服务
|    |-> DevSvcManagerClntAddService()
|        |-> devSvcMgrClnt = DevSvcManagerClntGetInstance();
|        |-> serviceManager = devSvcMgrClnt->devSvcMgrIf; // SvcMgrClnt即为SvcMgr的代理
|        |   // 添加设备服务到设备服务管理器
|        |-> serviceManager->AddService(serviceManager, svcName, service);
|    
|    // 创建设备节点,返回与之关联的VnodeAdapter的ioService域
|-> devNodeExt->ioService = HdfIoServicePublish()
|-> static struct HdfIoDispatcher dispatcher = {
|->        .Dispatch = DeviceNodeExtDispatch
|-> };
|-> devNodeExt->ioService->dispatcher = &dispatcher;

2.6 HdfDriverEntry

HdfDriverEntry即设备驱动对象,对应一个设备节点。

struct HdfDriverEntry {
    // Driver version
    int32_t moduleVersion;
    
    // Driver module name, to match the driver information in .hcs file
    const char *moduleName;

    //to bind DriverIoService to HdfDevService
    int32_t (*Bind)(struct HdfDeviceObject *deviceObject); // 

    // Initializes the driver.
    int32_t (*Init)(struct HdfDeviceObject *deviceObject);
    
    // Releases driver resources
    void (*Release)(struct HdfDeviceObject *deviceObject);
};

3 总结

至此,本文已经介绍了DevMgrService构建过程中遇到的绝大部分对象类型,其目的是先为读者勾画出每个对象类型的功能,使读者在阅读源码的初始阶段,可以在不深入调入流程的情况下,对DevMgrService的构建流程有个大概的印象,而不是被代码牵引,一层层向下深入,最后被众多的对象所淹没。

以此铺垫,在下一篇文章中,将介绍DevMgrService的构建过程,众多的对象类型,诸如DevHostServiceClnt、DevHostService、HdfDevice、HdfDeviceNode、HdfDriverEntry以及HdfDeviceToken等,将关联成一张负责的关系网。

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值