未验证 提交 e95d38ce 编写于 作者: O openharmony_ci 提交者: Gitee

!10695 HDF驱动框架部分开发指南优化

Merge pull request !10695 from Zhang/master
......@@ -4,6 +4,7 @@
- HDF驱动框架
- [HDF开发概述](driver-hdf-overview.md)
- [驱动开发](driver-hdf-development.md)
- [驱动加载](driver-hdf-load.md)
- [驱动服务管理](driver-hdf-servicemanage.md)
- [驱动消息机制管理](driver-hdf-message-management.md)
- [配置管理](driver-hdf-manage.md)
......
......@@ -3,7 +3,7 @@
## 驱动模型介绍
HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个Host里面,开发者也可以将驱动功能分层独立开发和部署,支持一个驱动多个Node。HDF驱动模型如下图所示:
HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个Host(设备容器)里面,用于管理一组设备的启动加载等过程。在划分Host时,驱动程序是部署在一个Host还是部署在不同的Host,主要考虑驱动程序之间是否存在耦合性,如果两个驱动程序之间存在依赖,可以考虑将这部分驱动程序部署在一个Host里面,否则部署到独立的Host中是更好的选择。Device对应一个真实的物理设备。DeviceNode是设备的一个部件,Device至少有一个DeviceNode。每个DeviceNode可以发布一个设备服务。驱动即驱动程序,每个DevicdNode唯一对应一个驱动,实现和硬件的功能交互。HDF驱动模型如下图所示:
**图1** HDF驱动模型
......@@ -12,7 +12,7 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
## 驱动开发步骤
基于HDF框架的驱动开发主要分为三个部分:驱动实现、驱动编译和驱动配置。详细开发流程如下所示:
基于HDF框架的驱动开发主要分为三个部分:驱动实现、驱动编译脚本编写和驱动配置。详细开发流程如下所示:
1. 驱动实现
......@@ -20,24 +20,24 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
- 驱动业务代码
```
```c
#include "hdf_device_desc.h" // HDF框架对驱动开发相关能力接口的头文件
#include "hdf_log.h" // HDF框架提供的日志接口头文件
#define HDF_LOG_TAG "sample_driver" // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签。
#define HDF_LOG_TAG sample_driver // 打印日志所包含的标签,如果不定义则用默认定义的HDF_TAG标签。
// 驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架。
// 将驱动对外提供的服务能力接口绑定到HDF框架。
int32_t HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
{
HDF_LOGD("Sample driver bind success");
return 0;
return HDF_SUCCESS;
}
// 驱动自身业务初始化的接口
int32_t HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
{
HDF_LOGD("Sample driver Init success");
return 0;
return HDF_SUCCESS;
}
// 驱动资源释放的接口
......@@ -49,7 +49,7 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
```
- 驱动入口注册到HDF框架
```
```c
// 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量。
struct HdfDriverEntry g_sampleDriverEntry = {
.moduleVersion = 1,
......@@ -63,7 +63,7 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
HDF_INIT(g_sampleDriverEntry);
```
2. 驱动编译
2. 驱动编译脚本编写
- LiteOS
......@@ -74,8 +74,8 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
驱动代码的编译必须要使用HDF框架提供的Makefile模板进行编译。
```
include $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mk # 【必需】导入hdf预定义内容
```c
include $(LITEOSTOPDIR)/../../drivers/hdf_core/adapter/khdf/liteos/lite.mk # 【必需】导入hdf预定义内容
MODULE_NAME := #生成的结果文件
LOCAL_INCLUDE := #本驱动的头文件目录
LOCAL_SRCS := #本驱动的源代码文件
......@@ -83,22 +83,22 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
include $(HDF_DRIVER) #导入Makefile模板完成编译
```
编译结果文件链接到内核镜像,添加到**drivers/adapter/khdf/liteos**目录下的**hdf_lite.mk**里面,示例如下:
编译结果文件链接到内核镜像,添加到**drivers/hdf_core/adapter/khdf/liteos**目录下的**hdf_lite.mk**里面,示例如下:
```
```c
LITEOS_BASELIB += -lxxx #链接生成的静态库
LIB_SUBDIRS += #驱动代码Makefile的目录
```
- BUILD.gn部分:
添加模块BUILD.gn参考定义如下内容
添加模块BUILD.gn,可参考如下示例
```
```c
import("//build/lite/config/component/lite_component.gni")
import("//drivers/adapter/khdf/liteos/hdf.gni")
import("//drivers/hdf_core/adapter/khdf/liteos/hdf.gni")
module_switch = defined(LOSCFG_DRIVERS_HDF_xxx)
module_name = "xxx"
hdf_driver(module_name) {
......@@ -109,42 +109,42 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
}
config("public") { #定义依赖的头文件配置
include_dirs = [
"xxx/xxx/xxx", #依赖的头文件目录
"xxx/xxx/xxx", #依赖的头文件目录
]
}
```
把新增模块的BUILD.gn所在的目录添加到**/drivers/adapter/khdf/liteos/BUILD.gn**里面:
把新增模块的BUILD.gn所在的目录添加到**/drivers/hdf_core/adapter/khdf/liteos/BUILD.gn**里面:
```
```c
group("liteos") {
public_deps = [ ":$module_name" ]
deps = [
"xxx/xxx", #新增模块BUILD.gn所在的目录,目录结构相对于/drivers/adapter/khdf/liteos
"xxx/xxx", #新增模块BUILD.gn所在的目录,目录结构相对于/drivers/hdf_core/adapter/khdf/liteos
]
}
```
- Linux
如果需要定义模块控制宏,需要在模块目录xxx里面添加Kconfig文件,并把Kconfig文件路径添加到**drivers/adapter/khdf/linux/Kconfig**里面:
如果需要定义模块控制宏,需要在模块目录xxx里面添加Kconfig文件,并把Kconfig文件路径添加到**drivers/hdf_core/adapter/khdf/linux/Kconfig**里面:
```
```c
source "drivers/hdf/khdf/xxx/Kconfig" #目录为hdf模块软链接到kernel里面的目录
```
添加模块目录到**drivers/adapter/khdf/linux/Makefile**:
添加模块目录到**drivers/hdf_core/adapter/khdf/linux/Makefile**:
```
```c
obj-$(CONFIG_DRIVERS_HDF) += xxx/
```
在模块目录xxx里面添加Makefile文件,在Makefile文件里面添加模块代码编译规则:
```
```c
obj-y += xxx.o
```
......@@ -189,7 +189,7 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
device0 :: deviceNode { // sample驱动的DeviceNode节点
policy = 1; // policy字段是驱动服务发布的策略,在驱动服务管理章节有详细介绍。
priority = 100; // 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序。
preload = 0; // 驱动按需加载字段,在本章节最后的说明有详细介绍
preload = 0; // 驱动按需加载字段。
permission = 0664; // 驱动创建设备节点权限
moduleName = "sample_driver"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致。
serviceName = "sample_service"; // 驱动对外发布服务的名称,必须唯一。
......@@ -211,7 +211,9 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
>
> - 进程的uid在文件**base/startup/init_lite/services/etc/passwd**中配置,进程的gid在文件**base/startup/init_lite/services/etc/group**中配置,进程uid和gid配置参考:[系统服务用户组添加方法](https://gitee.com/openharmony/startup_init_lite/wikis)。
>
> - caps值:比如业务模块要配置CAP_DAC_OVERRIDE,此处需要填写caps = ["DAC_OVERRIDE"],不能填写为caps = ["CAP_DAC_OVERRIDE"]。
> - caps值:格式为caps = ["xxx"],如果要配置CAP_DAC_OVERRIDE,此处需要填写caps = ["DAC_OVERRIDE"],不能填写为caps = ["CAP_DAC_OVERRIDE"]。
>
> - preload:驱动按需加载字段,参考[驱动加载](../driver/driver-hdf-load.md)。
- 驱动私有配置信息(可选)
......@@ -229,7 +231,7 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
}
```
配置信息定义之后,需要将该配置文件添加到板级配置入口文件hdf.hcs(这一块可以通过OpenHarmony驱动子系统在DevEco集成驱动开发套件工具一键式配置,具体使用方法参考驱动开发套件中的介绍),示例如下:
配置信息定义之后,需要将该配置文件添加到板级配置入口文件hdf.hcs,示例如下:
```
......@@ -237,27 +239,3 @@ HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心
#include "sample/sample_config.hcs"
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>
> 驱动加载方式支持按需加载和按序加载两种方式,具体使用方法如下:
>
> - 按需加载
>
> ```
> typedef enum {
> DEVICE_PRELOAD_ENABLE = 0,
> DEVICE_PRELOAD_ENABLE_STEP2,
> DEVICE_PRELOAD_DISABLE,
> DEVICE_PRELOAD_INVALID
> } DevicePreload;
> ```
>
> - 配置文件中preload字段配成0(DEVICE_PRELOAD_ENABLE),则系统启动过程中默认加载。
>
> - 配成1(DEVICE_PRELOAD_ENABLE_STEP2),当系统支持快启的时候,则在系统完成之后再加载这一类驱动,否则和DEVICE_PRELOAD_ENABLE含义相同。
>
> - 配成2(DEVICE_PRELOAD_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务(参考[消息机制](../driver/driver-hdf-message-management.md))时,如果驱动服务不存在,HDF框架会尝试动态加载该驱动。
>
> - 按序加载(需要驱动为默认加载)
>
> 配置文件中的priority(取值范围为整数0到200)是用来表示host和驱动的优先级。不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高。
# 驱动加载
## 驱动加载概述
HDF驱动框架提供把和配置的设备列表匹配成功的驱动程序加载起来的功能。
## 驱动加载策略
支持按需加载和按序加载两种策略,具体设备的加载策略由配置文件(参考[驱动开发](../driver/driver-hdf-development.md))中的preload字段来控制,配置值参考如下:
```c
typedef enum {
DEVICE_PRELOAD_ENABLE = 0,
DEVICE_PRELOAD_ENABLE_STEP2 = 1,
DEVICE_PRELOAD_DISABLE = 2,
DEVICE_PRELOAD_INVALID
} DevicePreload;
```
### 按需加载
- preload字段配置为0(DEVICE_PRELOAD_ENABLE),则系统启动过程中默认加载。
- preload字段配置为1(DEVICE_PRELOAD_ENABLE_STEP2),当系统支持快速启动的时候,则在系统完成之后再加载这一类驱动,否则和DEVICE_PRELOAD_ENABLE含义相同。
- preload字段配置为2(DEVICE_PRELOAD_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务(参考[消息机制](../driver/driver-hdf-message-management.md))时,如果驱动服务不存在,HDF框架会尝试动态加载该驱动。
### 按序加载(默认加载策略)
配置文件中的priority(取值范围为整数0到200)是用来表示host(驱动容器)和驱动的优先级。不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高。
......@@ -57,7 +57,7 @@ HCS主要分为属性(Attribute)和节点(Node)两种结构。
- value的可用格式如下:
- 数字常量,支持二进制、八进制、十进制、十六进制数,具体参考数据类型节。
- 数字常量,支持二进制、八进制、十进制、十六进制数,具体参考[数据类型](#数据类型)节。
- 字符串,内容使用双引号("")引用。
- 节点引用。
......@@ -83,7 +83,7 @@ HCS主要分为属性(Attribute)和节点(Node)两种结构。
- root节点中必须包含module属性,其值应该为一个字符串,用于表征该配置所属模块。
- 节点中可以增加match_attr属性,其值为一个全局唯一的字符串。在解析配置时可以调用查找接口以该属性的值查找到包含该属性的节点。
- 节点中可以增加match_attr属性,其值为一个全局唯一的字符串。当驱动程序在解析配置时可以以该属性的值为参数调用查找接口查找到包含该属性的节点。
### 数据类型
......@@ -97,7 +97,7 @@ HCS主要分为属性(Attribute)和节点(Node)两种结构。
- 八进制,0前缀,示例:0664。
- 十进制 ,无前缀,且支持有符号与无符号,示例:1024,+1024均合法。负值在读取时注意使用有符号数读取接口。
- 十进制 ,无前缀,且支持有符号与无符号,示例:1024,+1024均合法。驱动程序在读取负值时注意使用有符号数读取接口。
- 十六进制,0x前缀,示例:0xff00、0xFF。
......
......@@ -39,19 +39,19 @@
3. 在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。
```
```c
// Dispatch是用来处理用户态发下来的消息
int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
int32_t SampleDriverDispatch(struct HdfDeviceIoClient *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{
HDF_LOGE("sample driver lite A dispatch");
return 0;
HDF_LOGI("sample driver lite A dispatch");
return HDF_SUCCESS;
}
int32_t SampleDriverBind(struct HdfDeviceObject *device)
{
HDF_LOGE("test for lite os sample driver A Open!");
HDF_LOGI("test for lite os sample driver A Open!");
if (device == NULL) {
HDF_LOGE("test for lite os sample driver A Open failed!");
return -1;
return HDF_FAILURE;
}
static struct ISampleDriverService sampleDriverA = {
.ioService.Dispatch = SampleDriverDispatch,
......@@ -59,36 +59,36 @@
.ServiceB = SampleDriverServiceB,
};
device->service = (struct IDeviceIoService *)(&sampleDriverA);
return 0;
return HDF_SUCCESS;
}
```
4. 驱动定义消息处理函数中的cmd类型。
```
```c
#define SAMPLE_WRITE_READ 1 // 读写操作码1
```
5. 用户态获取服务接口并发送消息到驱动。
```
```c
int SendMsg(const char *testMsg)
{
if (testMsg == NULL) {
HDF_LOGE("test msg is null");
return -1;
return HDF_FAILURE;
}
struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
if (serv == NULL) {
HDF_LOGE("fail to get service");
return -1;
return HDF_FAILURE;
}
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
struct HdfSBuf *data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("fail to obtain sbuf data");
return -1;
return HDF_FAILURE;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
if (reply == NULL) {
HDF_LOGE("fail to obtain sbuf reply");
ret = HDF_DEV_ERR_NO_MEMORY;
......@@ -105,8 +105,8 @@
goto out;
}
out:
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
HdfSbufRecycle(data);
HdfSbbufRecycle(reply);
HdfIoServiceRecycle(serv);
return ret;
}
......@@ -115,31 +115,31 @@
6. 用户态接收该驱动上报的消息。
1. 用户态编写驱动上报消息的处理函数。
```
```c
static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
{
OsalTimespec time;
OsalGetTime(&time);
HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec);
HDF_LOGI("%{public}s received event at %{public}llu.%{public}llu", (char *)priv, time.sec, time.usec);
const char *string = HdfSbufReadString(data);
if (string == NULL) {
HDF_LOGE("fail to read string in event data");
return -1;
return HDF_FAILURE;
}
HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string);
return 0;
HDF_LOGI("%{public}s: dev event received: %{public}d %{public}s", (char *)priv, id, string);
return HDF_SUCCESS;
}
```
2. 用户态注册接收驱动上报消息的操作方法。
```
```c
int RegisterListen()
{
struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
if (serv == NULL) {
HDF_LOGE("fail to get service");
return -1;
return HDF_FAILURE;
}
static struct HdfDevEventlistener listener = {
.callBack = OnDevEventReceived,
......@@ -147,20 +147,20 @@
};
if (HdfDeviceRegisterEventListener(serv, &listener) != 0) {
HDF_LOGE("fail to register event listener");
return -1;
return HDF_FAILURE;
}
......
HdfDeviceUnregisterEventListener(serv, &listener);
HdfIoServiceRecycle(serv);
return 0;
return HDF_SUCCESS;
}
```
3. 驱动上报事件。
```
int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
```c
int32_t SampleDriverDispatch(HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{
... // process api call here
return HdfDeviceSendEvent(deviceObject, cmdCode, data);
return HdfDeviceSendEvent(client->device, cmdCode, data);
}
```
......@@ -3,7 +3,7 @@
## 简介
HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理和驱动消息机制。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。
HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。
## 驱动加载
......@@ -27,3 +27,8 @@ HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对
## 驱动消息机制
HDF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息。
## 配置管理
HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。
\ No newline at end of file
......@@ -51,7 +51,7 @@ root {
基于HDF框架编写的sample驱动代码如下(编译参考[驱动开发](../driver/driver-hdf-development.md)):
```
```c
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
......@@ -59,34 +59,34 @@ root {
#include "hdf_base.h"
#include "hdf_device_desc.h"
#define HDF_LOG_TAG "sample_driver"
#define HDF_LOG_TAG sample_driver
#define SAMPLE_WRITE_READ 123
int32_t HdfSampleDriverDispatch(
struct HdfDeviceObject *deviceObject, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
static int32_t HdfSampleDriverDispatch(
struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
{
HDF_LOGE("%s: received cmd %d", __func__, id);
HDF_LOGI("%{public}s: received cmd %{public}d", __func__, id);
if (id == SAMPLE_WRITE_READ) {
const char *readData = HdfSbufReadString(data);
if (readData != NULL) {
HDF_LOGE("%s: read data is: %s", __func__, readData);
HDF_LOGE("%{public}s: read data is: %{public}s", __func__, readData);
}
if (!HdfSbufWriteInt32(reply, INT32_MAX)) {
HDF_LOGE("%s: reply int32 fail", __func__);
HDF_LOGE("%{public}s: reply int32 fail", __func__);
}
return HdfDeviceSendEvent(deviceObject, id, data);
return HdfDeviceSendEvent(client->device, id, data);
}
return HDF_FAILURE;
}
void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
static void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
{
// release resources here
return;
}
int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
static int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
{
if (deviceObject == NULL) {
return HDF_FAILURE;
......@@ -98,17 +98,17 @@ int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
return HDF_SUCCESS;
}
int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
static int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
{
if (deviceObject == NULL) {
HDF_LOGE("%s::ptr is null!", __func__);
HDF_LOGE("%{public}s::ptr is null!", __func__);
return HDF_FAILURE;
}
HDF_LOGE("Sample driver Init success");
HDF_LOGI("Sample driver Init success");
return HDF_SUCCESS;
}
struct HdfDriverEntry g_sampleDriverEntry = {
static struct HdfDriverEntry g_sampleDriverEntry = {
.moduleVersion = 1,
.moduleName = "sample_driver",
.Bind = HdfSampleDriverBind,
......@@ -122,10 +122,10 @@ HDF_INIT(g_sampleDriverEntry);
## 编写用户程序和驱动交互代码
基于HDF框架编写的用户态程序和驱动交互的代码如下(代码可以放在目录drivers/adapter/uhdf下面编译,build.gn可以参考drivers/framework/sample/platform/uart/dev/build.gn):
基于HDF框架编写的用户态程序和驱动交互的代码如下(代码可以放在目录drivers/hdf_core/adapter/uhdf下面编译,BUILD.gn可以参考drivers/hdf_core/framework/sample/platform/uart/dev/BUILD.gn):
```
```c
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
......@@ -134,7 +134,7 @@ HDF_INIT(g_sampleDriverEntry);
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h"
#define HDF_LOG_TAG "sample_test"
#define HDF_LOG_TAG sample_test
#define SAMPLE_SERVICE_NAME "sample_service"
#define SAMPLE_WRITE_READ 123
......@@ -149,7 +149,7 @@ static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
g_replyFlag = 1;
return HDF_FAILURE;
}
HDF_LOGE("%s: dev event received: %u %s", (char *)priv, id, string);
HDF_LOGI("%{public}s: dev event received: %{public}u %{public}s", (char *)priv, id, string);
g_replyFlag = 1;
return HDF_SUCCESS;
}
......@@ -157,13 +157,13 @@ static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
static int SendEvent(struct HdfIoService *serv, char *eventData)
{
int ret = 0;
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
struct HdfSBuf *data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("fail to obtain sbuf data");
return 1;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
if (reply == NULL) {
HDF_LOGE("fail to obtain sbuf reply");
ret = HDF_DEV_ERR_NO_MEMORY;
......@@ -188,10 +188,10 @@ static int SendEvent(struct HdfIoService *serv, char *eventData)
ret = HDF_ERR_INVALID_OBJECT;
goto out;
}
HDF_LOGE("Get reply is: %d", replyData);
HDF_LOGI("Get reply is: %{public}d", replyData);
out:
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
HdfSbufRecycle(data);
HdfSbufRecycle(reply);
return ret;
}
......@@ -237,8 +237,8 @@ int main()
>
> deps = [
>
> "//drivers/adapter/uhdf/manager:hdf_core",
> "//drivers/hdf_core/adapter/uhdf/manager:hdf_core",
>
> "//drivers/adapter/uhdf/posix:hdf_posix_osal",
> "//drivers/hdf_core/adapter/uhdf/posix:hdf_posix_osal",
>
> ]
......@@ -8,7 +8,7 @@ HDF框架定义了驱动对外发布服务的策略,由配置文件中的polic
```
```c
typedef enum {
/* 驱动不提供服务 */
SERVICE_POLICY_NONE = 0,
......@@ -28,7 +28,7 @@ typedef enum {
## 使用场景
当驱动以接口的形式对外提供能力时,可以使用HDF框架的驱动服务管理能力。
当驱动需要以接口的形式对外提供能力时,可以使用HDF框架的驱动服务管理能力。
## 接口说明
......@@ -50,7 +50,7 @@ typedef enum {
1. 驱动服务编写。
```
```c
// 驱动服务结构的定义
struct ISampleDriverService {
struct IDeviceIoService ioService; // 服务结构的首个成员必须是IDeviceIoService类型的成员。
......@@ -62,66 +62,69 @@ typedef enum {
int32_t SampleDriverServiceA(void)
{
// 驱动开发者实现业务逻辑
return 0;
return HDF_SUCCESS;
}
int32_t SampleDriverServiceB(uint32_t inputCode)
{
// 驱动开发者实现业务逻辑
return 0;
return HDF_SUCCESS;
}
```
2. 驱动服务绑定到HDF框架中,实现HdfDriverEntry中的Bind指针函数。
2. 驱动服务绑定。
开发者实现HdfDriverEntry中的Bind指针函数,如下的SampleDriverBind,把驱动服务绑定到HDF框架中。
```
```c
int32_t SampleDriverBind(struct HdfDeviceObject *deviceObject)
{
// deviceObject为HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。
if (deviceObject == NULL) {
HDF_LOGE("Sample device object is null!");
return -1;
return HDF_FAILURE;
}
static struct ISampleDriverService sampleDriverA = {
.ServiceA = SampleDriverServiceA,
.ServiceB = SampleDriverServiceB,
};
deviceObject->service = &sampleDriverA.ioService;
return 0;
return HDF_SUCCESS;
}
```
3. 驱动服务获取。
驱动服务的获取有两种方式,HDF框架提供接口直接获取和订阅机制获取。
应用程序开发者获取驱动服务有两种方式:通过HDF接口直接获取和通过HDF提供的订阅机制获取。
- 通过HDF接口直接获取
当明确驱动已经加载完成时,获取该驱动的服务可以通过HDF框架提供的能力接口直接获取,如下所示:
驱动服务获取者明确驱动已经加载完成时,获取该驱动的服务可以通过HDF框架提供的能力接口直接获取,如下所示:
```
```c
const struct ISampleDriverService *sampleService =
(const struct ISampleDriverService *)DevSvcManagerClntGetService("sample_driver");
if (sampleService == NULL) {
return -1;
return HDF_FAILURE;
}
sampleService->ServiceA();
sampleService->ServiceB(5);
```
- 通过HDF提供的订阅机制获取
当内核态对驱动(同一个host)加载的时机不感知时,可以通过HDF框架提供的订阅机制来订阅该驱动。当该驱动加载完成时,HDF框架会将被订阅的驱动服务发布给订阅者,实现方式如下所示:
当内核态驱动服务获取者对驱动(同一个host)加载的时机不感知时,可以通过HDF框架提供的订阅机制来订阅该驱动服务。当该驱动加载完成时,HDF框架会将被订阅的驱动服务发布给订阅者(驱动服务获取者),实现方式如下所示:
```
// 订阅回调函数的编写,当被订阅的驱动加载完成后,HDF框架会将被订阅驱动的服务发布给订阅者,通过这个回调函数给订阅者使用
// object为订阅者的私有数据,service为被订阅的服务对象
```c
// 订阅回调函数的编写,当被订阅的驱动加载完成后,HDF框架会将被订阅驱动的服务发布给订阅者,通过这个回调函数给订阅者使用
// object为订阅者的私有数据,service为被订阅的服务对象
int32_t TestDriverSubCallBack(struct HdfDeviceObject *deviceObject, const struct HdfObject *service)
{
const struct ISampleDriverService *sampleService =
(const struct ISampleDriverService *)service;
if (sampleService == NULL) {
return -1;
return HDF_FAILURE;
}
sampleService->ServiceA();
sampleService->ServiceB(5);
......@@ -131,13 +134,13 @@ typedef enum {
{
if (deviceObject == NULL) {
HDF_LOGE("Test driver init failed, deviceObject is null!");
return -1;
return HDF_FAILURE;
}
struct SubscriberCallback callBack;
callBack.deviceObject = deviceObject;
callBack.OnServiceConnected = TestDriverSubCallBack;
int32_t ret = HdfDeviceSubscribeService(deviceObject, "sample_driver", callBack);
if (ret != 0) {
if (ret != HDF_SUCCESS) {
HDF_LOGE("Test driver subscribe sample driver failed!");
}
return ret;
......
......@@ -319,6 +319,7 @@
- HDF驱动框架
- [HDF开发概述](driver/driver-hdf-overview.md)
- [驱动开发](driver/driver-hdf-development.md)
- [驱动加载](driver/driver-hdf-load.md)
- [驱动服务管理](driver/driver-hdf-servicemanage.md)
- [驱动消息机制管理](driver/driver-hdf-message-management.md)
- [配置管理](driver/driver-hdf-manage.md)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册