深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
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;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
};
|-> devNodeExt->ioService->dispatcher = &dispatcher;
#### 2.6 HdfDriverEntry
HdfDriverEntry即设备驱动对象,对应一个设备节点。
struct HdfDriverEntry {
// Driver version
int32_t moduleVersion;
[外链图片转存中…(img-X4Gopsse-1715654618706)]
[外链图片转存中…(img-EmRIfP72-1715654618707)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!