【OpenHarmony】HDF 核心框架
HDF 核心框架(drivers_hdf_core)架构
1. 模块概述
源码:https://gitee.com/openharmony/drivers_hdf_core
1.1 功能与目标
主要功能:
- 驱动生命周期管理:提供驱动加载、初始化、绑定、发布与卸载的完整生命周期控制。
- 服务发布与发现:通过设备管理服务(DevmgrService)和服务管理器(DevSvcManager)实现驱动服务的注册、发现与按需加载。
- IPC/IDL 抽象层:支持用户态和内核态驱动通信,提供跨进程调用框架(HdfRemoteService)。
- 配置解析与驱动安装:解析 HCS 配置文件,按优先级与预加载策略驱动驱动程序。
- 电源与事件管理:支持系统电源状态转换(SUSPEND/RESUME/DOZE),并自顶向下分发到各宿主与设备节点。
- 平台抽象与模型框架:提供 GPIO/I2C/SPI/UART 等平台驱动统一抽象接口,以及 Audio/Input/Display/Sensor 等模型框架。
目标:
- 实现"一次开发,多系统部署",支持轻量(Lite)与标准(Full)两种形态。
- 提供稳定的硬件抽象层(HAL/HDI),隔离硬件差异,简化上层应用开发。
1.2 系统位置
┌──────────────────────────────────────────────────┐
│ 应用层 / 系统服务(System Services) │
└──────────────┬───────────────────────────────────┘│ HDI/IDL 接口调用
┌──────────────▼───────────────────────────────────┐
│ HDF 核心框架(本模块) │
│ ┌─────────────────────────────────────────────┐ │
│ │ DevmgrService (设备管理) │ │
│ │ DevSvcManager (服务注册与发现) │ │
│ │ DevHostService (驱动宿主进程) │ │
│ │ HdfDeviceNode (设备节点/驱动实例) │ │
│ └─────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Platform 层 (GPIO/I2C/SPI/UART...) │ │
│ │ Model 层 (Audio/Input/Display/Sensor...) │ │
│ └─────────────────────────────────────────────┘ │
└──────────────┬───────────────────────────────────┘│ OSAL (操作系统抽象层)
┌──────────────▼───────────────────────────────────┐
│ 内核适配层 / 硬件寄存器访问 │
└──────────────────────────────────────────────────┘
角色定位:
- 核心模块:HDF 框架本身是驱动子系统的核心,负责驱动加载、服务管理、IPC 通道等基础设施。
- 上层接口:向系统服务和应用提供 HDI(Hardware Driver Interface)。
- 下层适配:通过 OSAL 适配不同内核(Linux/LiteOS)。
1.3 设计思路与模式
核心设计思路:
-
分层解耦:
- Manager 层:全局设备管理器(DevmgrService),负责启动宿主、按需加载驱动、电源状态分发。
- Host 层:驱动宿主进程(DevHostService),承载设备集合(HdfDevice),隔离驱动故障。
- Device/Node 层:设备(HdfDevice)可包含多个设备节点(HdfDeviceNode),每个节点对应一个驱动实例。
- Service 层:服务管理器(DevSvcManager)维护全局服务目录,支持服务发布、订阅与查询。
-
对象工厂模式:
HdfObjectManager
根据对象类型 ID(HDF_OBJECT_ID_*
)调用对应的HdfObjectCreator
创建/释放实例。- 支持 Lite 和 Full 两套对象工厂配置(
devlite_object_config.c
/devhost_object_config.c
)。
-
配置驱动:
- 使用 HCS(HDF Configuration Source)描述驱动层级(host -> device -> deviceNode)。
- 解析后生成
HdfDeviceInfo
,按优先级与预加载策略(DEVICE_PRELOAD_ENABLE/DISABLE
)调度加载。
-
服务发布策略:
SERVICE_POLICY_NONE
:无服务。SERVICE_POLICY_PUBLIC
:对内核和用户态公开。SERVICE_POLICY_CAPACITY
:对用户态和内核公开(容量策略)。SERVICE_POLICY_PRIVATE
:仅内部可见,不对外发布。
-
常见设计模式:
- 工厂模式:
HdfObjectManager
创建 DevmgrService/DevHostService/HdfDevice/DriverLoader 等。 - 观察者模式:
HdfServiceObserver
监听服务状态变化;电源事件通过PmNotify
逐层传递。 - 门面模式:
HdfIoService
统一对外暴露服务接口。 - 策略模式:服务发布策略决定服务可见性和发布方式。
- 工厂模式:
1.4 图示:系统框图
2. 模块结构
2.1 源文件与头文件
2.1.1 核心管理层(framework/core/manager)
- devmgr_service.h / devmgr_service.c:设备管理服务,启动宿主进程、按需加载驱动、电源状态分发。
- devsvc_manager.h / devsvc_manager.c:服务管理器,维护全局服务注册表(服务名 -> HdfDeviceObject)。
- hdf_driver_installer.c:驱动安装器,调用
StartDeviceHost
启动宿主进程。
2.1.2 驱动宿主层(framework/core/host)
- devhost_service.h / devhost_service.c:宿主服务,承载设备集合,处理
AddDevice/DelDevice/PmNotify
。 - hdf_device.h / hdf_device.c:设备对象
HdfDevice
,包含多个设备节点HdfDeviceNode
。 - hdf_device_node.h / hdf_device_node.c:设备节点,封装驱动实例、服务对象、电源令牌,执行
Bind/Init/Publish
。 - hdf_driver_loader.h / hdf_driver_loader.c:驱动加载器,根据模块名加载驱动动态库并返回
HdfDriver
。 - hdf_device_object.c:设备对象辅助函数,如
HdfDeviceObjectPublishService
。
2.1.3 公共与共享层(framework/core/common & shared)
- devlite_object_config.c:Lite 形态对象工厂配置(Devmgr/DevHost/DriverLoader 等)。
- hdf_attribute.c:HCS 配置解析,生成宿主、设备、节点信息。
- hdf_object_manager.h / hdf_object_manager.c:对象管理器,根据对象 ID 创建实例。
- hdf_io_service.h / hdf_io_service.c:IO 服务抽象,提供
HdfIoServicePublish/Obtain/Remove
。
2.1.4 接口定义层(interfaces/inner_api)
- hdf_device_desc.h:定义
HdfDriverEntry
(驱动入口)、HdfDeviceObject
(设备对象)、IDeviceIoService
(服务接口)。 - hdf_io_service_if.h:客户端 IO 服务接口,
HdfIoServiceBind/Dispatch
。 - hdf_device.h / hdf_device_node.h:设备与设备节点内部定义(devid_t/IHdfDevice/IDeviceNode)。
2.1.5 适配层(adapter/uhdf2)
- devhost_object_config.c:Full 形态对象工厂配置(Proxy/Stub)。
- devmgr_service_stub.c:设备管理服务远程调用存根,发布
HDI.IDeviceManager.V1_0
。 - devhost_service_full.c:宿主服务 Full 实现,注册系统电源事件监听。
2.1.6 平台与模型层(framework/support & model)
- platform/include/fwk/platform_core.h:平台模块类型枚举(GPIO/I2C/SPI/UART…)。
- platform/include/gpio/gpio_core.h:GPIO 控制器结构
GpioCntlr
与方法表GpioMethod
。 - model/audio/core/include/audio_core.h:音频框架核心,
AudioCard/AudioSapmComponent/AudioKcontrol
。 - model/input/driver/input_config.h:输入框架配置与设备管理。
2.2 类、结构体、函数与方法
2.2.1 核心结构体
HdfDriverEntry (interfaces/inner_api/host/shared/hdf_device_desc.h:202-240)
struct HdfDriverEntry {int32_t moduleVersion; // 驱动版本const char *moduleName; // 模块名(与 HCS 配置 moduleName 匹配)int32_t (*Bind)(struct HdfDeviceObject *deviceObject); // 绑定服务接口int32_t (*Init)(struct HdfDeviceObject *deviceObject); // 初始化驱动void (*Release)(struct HdfDeviceObject *deviceObject); // 释放资源
};
用途:驱动开发者必须实现此结构并通过 HDF_INIT(g_xxxDriverEntry)
注册。
HdfDeviceObject (interfaces/inner_api/host/shared/hdf_device_desc.h:95-113)
struct HdfDeviceObject {struct IDeviceIoService *service; // 服务接口对象(由驱动在 Bind 中设置)const struct DeviceResourceNode *property; // 设备配置属性(从 HCS 读取)DeviceClass deviceClass; // 设备类别void *priv; // 驱动私有数据
#ifdef __USER__pthread_rwlock_t mutex; // 用户态服务锁
#endif
};
用途:HDF 传递给驱动的上下文对象,驱动将服务接口绑定到 service
字段。
IDeviceIoService (interfaces/inner_api/host/shared/hdf_device_desc.h:137-169)
struct IDeviceIoService {struct HdfObject object;int32_t (*Open)(struct HdfDeviceIoClient *client);int32_t (*Dispatch)(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply);void (*Release)(struct HdfDeviceIoClient *client);
};
用途:驱动服务必须继承此结构并实现 Dispatch
方法处理用户请求。
HdfDeviceNode (interfaces/inner_api/host/shared/hdf_device_node.h:34-52)
struct HdfDeviceNode {struct IDeviceNode super; // 接口表(PublishService/RemoveService/LaunchNode/UnlaunchNode)struct DListHead entry; // 双链表节点(挂在 HdfDevice.devNodes 上)struct PowerStateToken *powerToken; // 电源状态令牌struct DevHostService *hostService; // 所属宿主服务struct HdfDeviceObject deviceObject; // 设备对象(传给驱动)struct IHdfDeviceToken *token; // 设备令牌(与 DevmgrService 通信)struct HdfDriver *driver; // 驱动对象(包含 HdfDriverEntry)struct HdfDevice *device; // 所属设备char *servName; // 服务名const char *servInfo; // 服务信息char *driverName; // 驱动名devid_t devId; // 设备 ID(host<<24 | device<<8 | node)uint16_t policy; // 服务发布策略uint16_t permission; // 设备节点权限uint8_t devStatus; // 设备状态(NONE/INITED/LAUNCHED)bool servStatus; // 服务是否已发布char *interfaceDesc; // 接口描述符(IDL)
};
用途:设备节点是驱动实例的核心封装,执行生命周期管理(Bind/Init/Publish)。
HdfDevice (interfaces/inner_api/host/shared/hdf_device.h:51-57)
struct HdfDevice {struct IHdfDevice super; // 接口表(Attach/Detach/GetDeviceNode)struct DListHead node; // 挂在 DevHostService.devices 上struct DListHead devNodes; // 设备节点链表devid_t deviceId; // 设备 IDuint16_t devidIndex; // 设备节点索引
};
用途:承载多个设备节点,按设备 ID 组织。
DevHostService (framework/core/host/include/devhost_service.h:21-28)
struct DevHostService {struct IDevHostService super; // 接口表(AddDevice/DelDevice/StartService/PmNotify)uint16_t hostId; // 宿主 IDconst char *hostName; // 宿主名struct DListHead devices; // 设备链表struct HdfServiceObserver observer; // 服务观察者(本地服务发布)struct HdfSysEventNotifyNode sysEventNotifyNode; // 系统事件监听节点
};
用途:驱动宿主进程的核心服务对象,管理设备集合,处理电源事件。
DevmgrService (framework/core/manager/include/devmgr_service.h:16-20)
struct DevmgrService {struct IDevmgrService super; // 接口表(AttachDevice/LoadDevice/UnloadDevice/PowerStateChange...)struct DListHead hosts; // 宿主客户端链表(DevHostServiceClnt)struct OsalMutex devMgrMutex; // 互斥锁
};
用途:全局设备管理器,启动宿主、按需加载驱动、分发电源事件。
DevSvcManager (framework/core/manager/include/devsvc_manager.h:17-23)
struct DevSvcManager {struct IDevSvcManager super; // 接口表(AddService/GetService/RemoveService/SubscribeService...)struct DListHead services; // 服务记录链表(DevSvcRecord)struct HdfServiceObserver observer;struct DListHead svcstatListeners; // 服务状态监听器struct OsalMutex mutex;
};
用途:全局服务注册表,按服务名哈希查找服务对象。
2.2.2 关键函数与方法
驱动生命周期
-
DeviceDriverBind(HdfDeviceNode *devNode)
(hdf_device_node.c:65-88)
调用驱动的Bind
方法,驱动将服务接口绑定到deviceObject.service
。 -
HdfDeviceLaunchNode(HdfDeviceNode *devNode)
(hdf_device_node.c:90-127)
执行完整生命周期:Bind -> Init -> PublishService -> AttachDevice
。 -
HdfDeviceNodePublishService(HdfDeviceNode *devNode)
(hdf_device_node.c:44-63)
根据policy
策略发布服务(本地 + 全局)。
服务注册与发现
-
DevSvcManagerAddService(IDevSvcManager*, HdfDeviceObject*, HdfServiceInfo*)
(devsvc_manager.c:85-129)
将服务对象注册到全局服务表,生成哈希键(服务名)。 -
DevSvcManagerClntGetService(const char *svcName)
(devsvc_manager_clnt.c:57-72)
按服务名查找服务对象,触发按需加载(若服务未注册)。 -
HdfIoServicePublish(const char *serviceName, uint32_t mode)
发布 IO 服务并创建设备节点(/dev/hdf/xxx
)。
宿主与设备管理
-
DevmgrServiceStartService(IDevmgrService *inst)
(devmgr_service.c:429-442)
启动所有宿主进程(按 HCS 配置优先级)。 -
DevHostServiceAddDevice(IDevHostService*, HdfDeviceInfo*)
(devhost_service.c:63-114)
宿主接收设备信息,加载驱动,创建设备节点并调用LaunchNode
。 -
DevmgrServiceLoadDevice(IDevmgrService*, const char *serviceName)
(devmgr_service.c:92-130)
按需加载驱动:启动宿主(若未运行)-> 调用宿主AddDevice
。
电源管理
-
DevmgrServicePowerStateChange(IDevmgrService*, HdfPowerState)
(devmgr_service.c:444-481)
自顶向下分发电源状态:遍历所有宿主 -> 调用PmNotify
。 -
DevHostServicePmNotify(IDevHostService*, uint32_t state)
(devhost_service.c:199-225)
宿主接收电源事件,遍历设备集合 -> 调用设备电源状态切换。
对象工厂
-
HdfObjectManagerGetObject(int objectId)
根据对象 ID 调用对应的Create
工厂方法(如DevmgrServiceCreate/DevHostServiceCreate
)。 -
HdfObjectManagerPutObject(HdfObject *object)
调用对应的Release
方法释放对象。
2.2.3 继承与多态
HDF 使用 C 语言模拟的面向对象与多态:
- 接口表(vtable):如
IDevHostService
、IDevmgrService
定义方法集合,具体实现(Lite/Full)填充不同函数指针。 - CONTAINER_OF 宏:从接口指针获取具体实现结构体指针(类似向下转型)。
示例:
struct IDevHostService {int (*AddDevice)(struct IDevHostService *inst, const struct HdfDeviceInfo *deviceInfo);int (*DelDevice)(struct IDevHostService *inst, devid_t devId);int (*StartService)(struct IDevHostService *inst);int (*PmNotify)(struct IDevHostService *inst, uint32_t state);
};struct DevHostService {struct IDevHostService super; // 继承接口uint16_t hostId;// ...
};// 构造函数中填充方法
void DevHostServiceConstruct(struct DevHostService *service) {service->super.AddDevice = DevHostServiceAddDevice;service->super.DelDevice = DevHostServiceDelDevice;service->super.StartService = DevHostServiceStartService;service->super.PmNotify = DevHostServicePmNotify;
}
2.3 类图
2.4 图示:模块内部依赖框图
3. 模块间交互
3.1 交互描述
3.1.1 配置加载流程
- 系统启动:
DeviceManagerStart()
初始化DevmgrService
。 - 解析 HCS:
HdfAttributeManagerGetDeviceList()
读取device_info.hcs
,生成宿主/设备/节点树。 - 启动宿主:
DriverInstaller.StartDeviceHost()
按优先级启动宿主进程(Lite 直接创建线程,Full 创建独立进程)。 - 宿主 Attach:宿主启动后调用
DevmgrServiceClntAttachDeviceHost()
向 Manager 注册。
3.1.2 驱动加载流程
- 接收设备信息:
DevHostServiceAddDevice()
接收HdfDeviceInfo
。 - 加载驱动模块:
DriverLoader.GetDriver(moduleName)
加载动态库(.so
),获取HdfDriverEntry
。 - 创建设备节点:
HdfDeviceNodeNewInstance()
创建设备节点,关联驱动。 - Attach 到设备:
HdfDevice.Attach()
将节点加入设备节点链表。 - 执行生命周期:
HdfDeviceLaunchNode()
依次调用Bind -> Init -> PublishService -> AttachDevice
。
3.1.3 服务发布流程
- 驱动绑定服务:驱动在
Bind
中将IDeviceIoService
实例赋值给deviceObject.service
。 - 发布本地服务:
HdfServiceObserverPublishService()
注册到宿主内部服务观察者。 - 发布全局服务:
DevSvcManagerClntAddService()
->DevSvcManager.AddService()
注册到全局服务表。 - 创建设备节点:
HdfIoServicePublish()
在/dev/hdf/
下创建字符设备节点(Full 形态)。
3.1.4 服务发现与按需加载
- 客户端请求:应用调用
HdfIoServiceBind(serviceName)
。 - 查找服务:
DevSvcManagerClntGetService()
在全局服务表中查找。 - 按需加载:若服务未注册,调用
DevmgrServiceLoadDevice(serviceName)
:- 查找配置中的
HdfDeviceInfo
。 - 启动宿主(若未运行)。
- 调用
DevHostServiceAddDevice()
加载驱动并发布服务。
- 查找配置中的
- 返回服务对象:返回
HdfIoService
或HdfRemoteService
。
3.1.5 IPC/IDL 机制
- 用户态 <-> 内核态:通过
/dev/hdf/*
设备节点,使用ioctl(HDF_WRITE_READ)
传递HdfWriteReadBuf
。 - 进程间(Full 形态):通过
HdfRemoteService
(基于共享内存/Binder),IDL 自动生成 Proxy/Stub。 - 接口描述符:Full 形态服务需设置
interfaceDesc
(如"HDI.IDeviceManager.V1_0"
),用于版本匹配。
3.1.6 异步与事件驱动
- 电源事件:
HdfSysEventNotifyRegister()
监听内核电源事件(KEVENT_POWER_SUSPEND/RESUME
),转换为POWER_STATE_*
后分发。 - 服务订阅:驱动调用
HdfDeviceSubscribeService()
,当被订阅服务加载后,回调SubscriberCallback.OnServiceConnected()
。 - 热插拔:输入、显示等模型框架内部实现设备热插拔,通知 DeviceManager 进行设备增删。
3.1.7 多线程处理
- Lite 形态:宿主运行在独立线程(
OsalThreadCreate()
),共享地址空间。 - Full 形态:宿主运行在独立进程(
fork/exec
),通过 IPC 通信。 - 服务调用:Full 形态通过 IPC 线程池处理并发请求;Lite 形态直接调用。
3.2 图示:外部依赖框图
4. 状态机转换图
4.1 状态机模型
HDF 框架中主要有两个状态机模型:
4.1.1 设备节点生命周期状态机
状态定义 (hdf_device_node.h:54-58):
enum DevNodeStaus {DEVNODE_NONE = 0, // 未初始化DEVNODE_INITED, // 已初始化(已创建但未启动)DEVNODE_LAUNCHED, // 已启动(Bind/Init 完成)
};
4.1.2 电源状态机
状态定义 (hdf_pm.h):
enum HdfPowerState {POWER_STATE_SUSPEND = 0, // 系统挂起POWER_STATE_RESUME, // 系统恢复POWER_STATE_DOZE_SUSPEND, // 显示关闭(浅度休眠)POWER_STATE_DOZE_RESUME, // 显示开启(浅度唤醒)POWER_STATE_MAX
};
4.2 图示:状态机树图
4.3 状态机切换规则
4.3.1 设备节点生命周期切换
当前状态 | 事件/条件 | 目标状态 | 触发函数 |
---|---|---|---|
DEVNODE_NONE | HdfDeviceNodeNewInstance() 成功 | DEVNODE_INITED | HdfDeviceNodeNewInstance() |
DEVNODE_INITED | 调用 HdfDeviceLaunchNode() | DEVNODE_LAUNCHED | HdfDeviceLaunchNode() |
DEVNODE_LAUNCHED | 调用 HdfDeviceNodeFreeInstance() 或异常 | Released | HdfDeviceNodeFreeInstance() |
DEVNODE_INITED | 异常或卸载 | Released | HdfDeviceNodeFreeInstance() |
状态切换:
- NONE -> INITED:创建设备节点对象,分配资源,初始化
deviceObject
。 - INITED -> LAUNCHED:执行驱动生命周期(
Bind
->Init
->PublishService
->AttachDevice
)。 - LAUNCHED -> Released:调用驱动
Release()
,移除服务,释放资源。
事件触发:
- 配置加载:HCS 解析后,按
preload
策略(DEVICE_PRELOAD_ENABLE
)自动触发LaunchNode
。 - 按需加载:应用请求服务时,触发
DevmgrServiceLoadDevice()
。 - 卸载请求:
DevmgrService.UnloadDevice()
或宿主进程退出。 - 异常:驱动
Init
失败、服务发布失败等。
转移条件:
- INITED -> LAUNCHED:
Bind
返回HDF_SUCCESS
且Init
返回HDF_SUCCESS
。 - LAUNCHED -> Released:显式卸载或异常(如宿主崩溃)。
4.3.2 电源状态切换
当前状态 | 系统事件 | 目标状态 | 处理函数 |
---|---|---|---|
RESUME | KEVENT_POWER_SUSPEND | SUSPEND | DevHostServicePmNotify(POWER_STATE_SUSPEND) |
SUSPEND | KEVENT_POWER_RESUME | RESUME | DevHostServicePmNotify(POWER_STATE_RESUME) |
RESUME | KEVENT_POWER_DISPLAY_OFF | DOZE_SUSPEND | DevHostServicePmNotify(POWER_STATE_DOZE_SUSPEND) |
DOZE_SUSPEND | KEVENT_POWER_DISPLAY_ON | DOZE_RESUME | DevHostServicePmNotify(POWER_STATE_DOZE_RESUME) |
事件触发:
- 内核电源管理子系统发送
KEVENT_POWER_*
事件。 - Full 形态:
HdfSysEventNotifyNode.callback
接收事件。 - Lite 形态:直接调用
DevmgrServicePowerStateChange()
。
转移条件:
- 系统进入深度睡眠 ->
SUSPEND
。 - 系统唤醒 ->
RESUME
。 - 显示关闭但系统保持浅度睡眠 ->
DOZE_SUSPEND
。
处理顺序:
- 挂起(SUSPEND):按宿主优先级逆序处理(高优先级最后挂起)。
- 唤醒(RESUME):按宿主优先级正序处理(高优先级最先唤醒)。
4.4 图示:状态机转换图
4.4.1 设备节点生命周期状态机
4.4.2 电源状态机
5. 接口设计
5.1 公共接口(对外暴露)
5.1.1 服务发布接口
HdfIoServicePublish
struct HdfIoService *HdfIoServicePublish(const char *serviceName, uint32_t mode);
- 功能:发布 IO 服务并创建设备节点(
/dev/hdf/serviceName
)。 - 参数:
serviceName
:服务名(需全局唯一)。mode
:设备节点权限(如0666
)。
- 返回值:成功返回
HdfIoService
指针,失败返回NULL
。 - 异常处理:
- 服务名为空或超长 -> 返回
NULL
。 - 权限模式非法 -> 返回
NULL
。 - 设备节点创建失败 -> 返回
NULL
。
- 服务名为空或超长 -> 返回
- 典型用法:
struct HdfIoService *ioService = HdfIoServicePublish("my_service", 0666); if (ioService == NULL) {HDF_LOGE("Failed to publish service");return HDF_FAILURE; } ioService->dispatcher = &g_myDispatcher; ioService->target = myPrivData;
HdfIoServiceRemove
void HdfIoServiceRemove(struct HdfIoService *service);
- 功能:移除已发布的 IO 服务。
- 参数:
service
- 待移除的服务对象。 - 异常处理:若
service
为空,直接返回。
5.1.2 服务获取接口
DevSvcManagerClntGetService
const struct HdfObject *DevSvcManagerClntGetService(const char *svcName);
- 功能:按服务名获取服务对象(支持按需加载)。
- 参数:
svcName
- 服务名。 - 返回值:成功返回服务对象(
HdfObject*
),失败返回NULL
。 - 异常处理:
- 服务名为空 -> 返回
NULL
。 - 服务未注册且按需加载失败 -> 返回
NULL
。
- 服务名为空 -> 返回
- 典型用法:
const struct HdfObject *service = DevSvcManagerClntGetService("my_service"); if (service == NULL) {HDF_LOGE("Service not found");return HDF_FAILURE; } struct IDeviceIoService *ioService = (struct IDeviceIoService *)service; ioService->Dispatch(client, cmdId, data, reply);
HdfIoServiceBind (用户态)
struct HdfIoService *HdfIoServiceBind(const char *serviceName);
- 功能:绑定到指定服务(打开设备节点
/dev/hdf/serviceName
)。 - 参数:
serviceName
- 服务名。 - 返回值:成功返回
HdfIoService
指针,失败返回NULL
。 - 异常处理:
- 设备节点不存在 -> 返回
NULL
。 - 权限不足 -> 返回
NULL
。
- 设备节点不存在 -> 返回
5.1.3 按需加载接口
HdfLoadDriverByServiceName
int32_t HdfLoadDriverByServiceName(const char *serviceName);
- 功能:按服务名按需加载驱动。
- 参数:
serviceName
- 服务名。 - 返回值:
HDF_SUCCESS
或错误码。 - 异常处理:
- 服务名未在配置中 -> 返回
HDF_DEV_ERR_NO_DEVICE
。 - 驱动
preload
策略非DEVICE_PRELOAD_DISABLE
-> 返回HDF_DEV_ERR_NORANGE
。 - 宿主启动失败 -> 返回
HDF_FAILURE
。
- 服务名未在配置中 -> 返回
5.1.4 设备管理接口(ioctl 命令)
typedef enum {DEVMGR_LOAD_SERVICE = 0, // 加载驱动DEVMGR_UNLOAD_SERVICE, // 卸载驱动DEVMGR_GET_SERVICE, // 获取服务DEVMGR_LIST_ALL_SERVICE, // 列出所有服务DEVMGR_LIST_ALL_DEVICE, // 列出所有设备
} DevMgrCmd;
- 用途:通过
ioctl(fd, HDF_WRITE_READ, &buf)
向dev_mgr
发送管理命令。
5.2 驱动入口接口(由驱动实现)
5.2.1 HdfDriverEntry
struct HdfDriverEntry {int32_t moduleVersion;const char *moduleName;int32_t (*Bind)(struct HdfDeviceObject *deviceObject);int32_t (*Init)(struct HdfDeviceObject *deviceObject);void (*Release)(struct HdfDeviceObject *deviceObject);
};
Bind
int32_t (*Bind)(struct HdfDeviceObject *deviceObject);
- 功能:绑定服务接口到
deviceObject->service
。 - 参数:
deviceObject
- HDF 传入的设备对象。 - 返回值:
HDF_SUCCESS
或错误码。 - 异常处理:
- 资源分配失败 -> 返回
HDF_ERR_MALLOC_FAIL
。 - 服务对象构造失败 -> 返回
HDF_FAILURE
。
- 资源分配失败 -> 返回
- 示例:
int32_t MyDriverBind(struct HdfDeviceObject *deviceObject) {struct MyService *service = (struct MyService *)OsalMemCalloc(sizeof(struct MyService));if (service == NULL) {return HDF_ERR_MALLOC_FAIL;}service->ioService.Dispatch = MyDispatch;deviceObject->service = &service->ioService.object;return HDF_SUCCESS; }
Init
int32_t (*Init)(struct HdfDeviceObject *deviceObject);
- 功能:初始化驱动(如注册中断、使能硬件时钟等)。
- 参数:
deviceObject
- 设备对象(同Bind
)。 - 返回值:
HDF_SUCCESS
或错误码。 - 异常处理:
- 硬件初始化失败 -> 返回
HDF_FAILURE
。 - 配置参数非法 -> 返回
HDF_ERR_INVALID_PARAM
。
- 硬件初始化失败 -> 返回
- 示例:
int32_t MyDriverInit(struct HdfDeviceObject *deviceObject) {struct MyService *service = CONTAINER_OF(deviceObject->service, struct MyService, ioService);// 读取配置if (MyHardwareInit(service) != HDF_SUCCESS) {return HDF_FAILURE;}return HDF_SUCCESS; }
Release
void (*Release)(struct HdfDeviceObject *deviceObject);
- 功能:释放驱动资源(卸载或异常时调用)。
- 参数:
deviceObject
- 设备对象。 - 异常处理:需保证幂等,即使多次调用也不崩溃。
- 示例:
void MyDriverRelease(struct HdfDeviceObject *deviceObject) {struct MyService *service = CONTAINER_OF(deviceObject->service, struct MyService, ioService);MyHardwareUninit(service);OsalMemFree(service); }
5.2.2 注册宏
#define HDF_INIT(module) HDF_DRIVER_INIT(module)
- 用途:注册驱动入口,框架自动发现。
- 示例:
struct HdfDriverEntry g_myDriverEntry = {.moduleVersion = 1,.moduleName = "my_driver",.Bind = MyDriverBind,.Init = MyDriverInit,.Release = MyDriverRelease, }; HDF_INIT(g_myDriverEntry);
5.3 数据交换接口
5.3.1 IDeviceIoService.Dispatch
int32_t (*Dispatch)(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply);
- 功能:处理用户请求,解析命令码
cmdId
,从data
读取参数,向reply
写入返回值。 - 参数:
client
:客户端对象(包含device
和priv
)。cmdId
:命令码(驱动自定义)。data
:输入参数缓冲区(序列化)。reply
:输出参数缓冲区(序列化)。
- 返回值:
HDF_SUCCESS
或错误码。 - 异常处理:
- 无效命令码 -> 返回
HDF_ERR_NOT_SUPPORT
。 - 参数解析失败 -> 返回
HDF_ERR_INVALID_PARAM
。 - 硬件操作失败 -> 返回驱动自定义错误码。
- 无效命令码 -> 返回
- 示例:
int32_t MyDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) {struct MyService *service = CONTAINER_OF(client->device->service, struct MyService, ioService);switch (cmdId) {case CMD_READ:return MyReadHandler(service, data, reply);case CMD_WRITE:return MyWriteHandler(service, data, reply);default:return HDF_ERR_NOT_SUPPORT;} }
5.3.2 HdfSBuf 序列化接口
bool HdfSbufReadUint32(struct HdfSBuf *sbuf, uint32_t *value);
bool HdfSbufWriteUint32(struct HdfSBuf *sbuf, uint32_t value);
bool HdfSbufReadString(struct HdfSBuf *sbuf, const char **value);
bool HdfSbufWriteString(struct HdfSBuf *sbuf, const char *value);
- 用途:在
Dispatch
中解析/构造请求/响应数据。
5.4 图示:接口调用时序图
5.4.1 服务发布时序
5.4.2 服务获取与按需加载时序
5.4.3 Dispatch 调用时序
附录:配置示例与开发建议
A.1 HCS 配置示例
root {device_info {match_attr = "hdf_manager";platform :: host {hostName = "platform_host";priority = 50; // 优先级 0-200,值越小优先级越高device_gpio :: device {device0 :: deviceNode {policy = 2; // SERVICE_POLICY_CAPACITYpriority = 10;preload = 0; // DEVICE_PRELOAD_ENABLEpermission = 0660;moduleName = "HDF_PLATFORM_GPIO";serviceName = "HDF_PLATFORM_GPIO_MANAGER";deviceMatchAttr = "hisilicon_pl061_driver";}}}}
}
字段说明:
hostName
:宿主名,全局唯一。priority
:加载优先级(宿主/设备节点),0 最高,200 最低。policy
:服务发布策略(0 无/1 公开/2 容量)。preload
:预加载策略(0 启动时加载/2 按需加载)。permission
:设备节点权限(八进制)。moduleName
:驱动模块名,需与HdfDriverEntry.moduleName
一致。serviceName
:对外服务名,全局唯一。deviceMatchAttr
:设备匹配属性,用于关联设备配置树。
A.2 驱动开发建议
- 模块命名:
moduleName
需全局唯一,建议格式VENDOR_MODULE_NAME
(如HISILICON_GPIO
)。 - 服务发布策略:
- 仅内核使用 ->
SERVICE_POLICY_PUBLIC
。 - 用户态可访问 ->
SERVICE_POLICY_CAPACITY
。 - 不对外发布 ->
SERVICE_POLICY_PRIVATE
。
- 仅内核使用 ->
- 资源管理:
- 在
Bind
中分配资源,在Release
中释放。 - 若
Init
失败,框架会自动调用Release
。
- 在
- 并发保护:
Dispatch
可能被多线程并发调用,需加锁保护共享数据。- 推荐使用
OsalSpinLock
(中断上下文)或OsalMutex
(进程上下文)。
- 电源管理:
- 若驱动需支持电源管理,实现
IPowerEventListener
并注册:HdfDeviceNodeAddPowerStateListener(devNode, &g_myPowerListener);
- 若驱动需支持电源管理,实现
- 错误处理:
- 返回标准错误码(
HDF_SUCCESS/HDF_FAILURE/HDF_ERR_*
)。 - 记录详细日志(
HDF_LOGE/HDF_LOGW/HDF_LOGI
)。
- 返回标准错误码(
A.3 常见问题排查
问题 | 可能原因 | 排查方法 |
---|---|---|
驱动未加载 | preload 设置错误 | 检查 HCS 配置,确认为 0 (自动加载)或按需加载时服务名正确 |
服务发布失败 | policy 为 SERVICE_POLICY_NONE | 修改为 PUBLIC/CAPACITY |
Dispatch 未调用 | service 字段未设置 | 检查 Bind 中是否正确赋值 deviceObject->service |
电源事件未响应 | 未注册电源监听器 | 调用 HdfDeviceNodeAddPowerStateListener() |
宿主崩溃 | 驱动访问空指针 | 启用 coredump,检查驱动代码 |