在mini系统上,HDI支持C,本文讲述如何在L0系统上进行HDI的开发。
本文档以开发实例展示HDI开发流程。
idl语法说明请参考:LINK
idl接口定义:
在drivers_interface仓下添加对应模块的idl文件。
$ tree ./drivers/interface/bar/
./drivers/interface/bar/
├── bundle.json
└── v1_0
├── BUILD.gn #编译IDL的BUILD.gn配置文件
├── IBar.idl #接口定义IDL
├── IBarCallback.idl #接口回调IDL
└── Types.idl #自定义类型IDL
//drivers/interface/bar/v1_0/IBar.idl
package ohos.hdi.bar.v1_0;
import ohos.hdi.bar.v1_0.Types;
import ohos.hdi.bar.v1_0.IBarCallback;
interface IBar {
Ping([in] String sendMsg, [out] String recvMsg);
GetData([out] struct BarInfo info);
SendCallback([in] IBarCallback cb);
}
//drivers/interface/bar/v1_0/IBarCallback.idl
package ohos.hdi.bar.v1_0;
[callback] interface IBarCallback {
Notify([in] String msg);
};
//drivers/interface/bar/v1_0/Types.idl
package ohos.hdi.bar.v1_0;
enum BarType {
TYPE_ONE,
TYPE_TWO,
TYPE_THREE,
};
struct BarInfo {
unsigned int id;
String name;
enum BarType type;
};
//drivers/interface/bar/v1_0/BUILD.gn
import("//drivers/interface/interface.gni")
interface("bar") {
sources = [
"IBar.idl",
"IBarCallback.idl",
"Types.idl",
]
language = "c"
subsystem_name = "hdf"
part_name = "drivers_interface_bar"
}
这里给出bundle.json模板进行参考,添加部件配置://drivers/interface/bar/bundle.json
{
"name": "drivers_interface_bar",
"description": "bar device driver interface",
"version": "3.2",
"license": "Apache License 2.0",
"component": {
"name": "drivers_interface_bar",
"subsystem": "hdf",
"syscap": [""],
"adapter_system_type": ["mini"], #注意,这里填mini,表示部件支持mini系统
"rom": "675KB",
"ram": "1024KB",
"deps": {
"components": [
"hdf_core",
"hiviewdfx_hilog_native",
"c_utils"
],
"third_part": [
"bounds_checking_function"
]
},
"build": {
"sub_component": [
"//drivers/interface/bar/v1_0:bar_idl_target"
],
"test": [
],
"inner_kits": [
{
"name": "//drivers/interface/bar/v1_0:bar_idl_headers",
"header": {
"header_files": [
],
"header_base": "//drivers/interface/bar"
}
}
]
}
}
}
部件编译入口配置
以master分支,iotlink_demo产品为例:
//vendor/chipsea/iotlink_demo/config.json,在hdf子系统下添加drivers_interface_foo部件
{
"subsystem": "hdf",
"components": [
{ "component": "drivers_interface_bar", "features":[] }
]
}
以上配置完成后,即可指定部件名进行编译
./build.sh --product-name iotlink_demo --build-target drivers_interface_bar
编译成功后,可在//out/hispark_taurus/ipcamera_hispark_taurus/gen/drivers/interface/foo/v1_0目录下生成HDI源码:
$ tree ./out/cst85_wblink/iotlink_demo/gen/drivers/interface/bar/
./out/cst85_wblink/iotlink_demo/gen/drivers/interface/bar/
└── v1_0
├── bar_callback_service.c # 接口回调实现源文件(参考代码)
├── bar_callback_service.h # 接口回调实现头文件(参考代码)
├── bar_driver.c # 驱动加载入口(参考代码)
├── bar_service.c # 接口实现源文件(参考代码)
├── bar_service.h # 接口实现头文件(参考代码)
├── ibar.h # 接口头文件
├── ibar_callback.h # 接口回调头文件
└── types.h # 自定义类型头文件
OH提供的HDI接口,其实现应当在//drivers/peripheral/
下的对应模块中。
按需新增驱动模块目录,以下为参考:
//drivers/peripheral/bar
$ tree ./drivers/peripheral/bar/
./drivers/peripheral/bar/
├── BUILD.gn
├── bundle.json # 部件配置
├── hdi_service # 服务实现目录
│ ├── BUILD.gn
│ ├── bar_driver.c # 驱动入口
│ ├── bar_service.c # 接口实现代码
│ └── bar_service.h
└── test
└── bar_test.c 测试用例
bar_service.h/.cpp为接口实现代码,参考idl生成代码,按需修改。
接口实现
//drivers/peripheral/bar/hdi_service/bar_service.h
#ifndef OHOS_HDI_BAR_V1_0_BARSERVICE_H
#define OHOS_HDI_BAR_V1_0_BARSERVICE_H
#include "v1_0/ibar.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct BarService { // 接口实现类
struct IBar super;
// please add private data here
};
struct BarService *BarServiceGet(void); // 获取HDI对象的对外接口
void BarServiceRelease(struct BarService *instance); // 释放HDI对象的对外接口
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif // OHOS_HDI_BAR_V1_0_BARSERVICE_H
//drivers/peripheral/bar/hdi_service/bar_service.c
#include "bar_service.h"
#include <hdf_base.h>
#include <hdf_log.h>
#include <osal_mem.h>
#include <securec.h>
#define HDF_LOG_TAG bar_service
#define CHECK_NULL_PTR_RET(ptr) do { \
if (ptr == NULL) { \
HDF_LOGE("[%s:%d]: null pointer", __func__, __LINE__);\
return HDF_FAILURE; \
} \
} while(false)
static int32_t BarPing(struct IBar *self, const char* sendMsg, char* recvMsg, uint32_t recvMsgLen)
{
CHECK_NULL_PTR_RET(self);
CHECK_NULL_PTR_RET(sendMsg);
CHECK_NULL_PTR_RET(recvMsg);
if (strcpy_s(recvMsg, recvMsgLen, sendMsg) != EOK) {
HDF_LOGE("[%s:%d]: failed to copy str", __func__, __LINE__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t BarGetData(struct IBar *self, struct BarInfo* info)
{
CHECK_NULL_PTR_RET(self);
CHECK_NULL_PTR_RET(info);
info->id = 1;
info->name = strdup("bar");
info->type = TYPE_THREE;
return HDF_SUCCESS;
}
static int32_t BarSendCallback(struct IBar *self, struct IBarCallback* cb)
{
CHECK_NULL_PTR_RET(self);
CHECK_NULL_PTR_RET(cb);
int32_t ret = cb->Notify(cb, "callback notify");
if (ret != HDF_SUCCESS) {
HDF_LOGE("[%s:%d]: failed to notify with callback interface", __func__, __LINE__);
return ret;
}
// no need to release callback
return HDF_SUCCESS;
}
static int32_t BarGetVersion(struct IBar *self, uint32_t* majorVer, uint32_t* minorVer)
{
*majorVer = IBAR_MAJOR_VERSION;
*minorVer = IBAR_MINOR_VERSION;
return HDF_SUCCESS;
}
struct BarService *BarServiceGet(void)
{
struct BarService *service = (struct BarService *)OsalMemCalloc(sizeof(struct BarService));
if (service == NULL) {
HDF_LOGE("%s: failed to malloc service object", __func__);
}
service->super.Ping = BarPing;
service->super.GetData = BarGetData;
service->super.SendCallback = BarSendCallback;
service->super.GetVersion = BarGetVersion;
return service;
}
void BarServiceRelease(struct BarService *instance)
{
if (instance == NULL) {
return;
}
OsalMemFree(instance);
}
//drivers/peripheral/bar/hdi_service/bar_driver.c
#include <hdf_device_desc.h>
#include <hdf_log.h>
#include "v1_0/bar_service.h"
#define HDF_LOG_TAG bar_driver
static int HdfBarDriverBind(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("%s: driver bind start", __func__);
struct BarService *serviceImpl = BarServiceGet(); // 获取接口实现对象
if (serviceImpl == NULL) {
HDF_LOGE("%s: failed to get service impl", __func__);
return HDF_FAILURE;
}
deviceObject->service = &serviceImpl->super.service; // 绑定到设备对象中
return HDF_SUCCESS;
}
static int HdfBarDriverInit(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("%s: driver init start", __func__);
return HDF_SUCCESS;
}
static void HdfBarDriverRelease(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("%s: driver release start", __func__);
if (deviceObject == NULL || deviceObject->service == NULL) {
HDF_LOGE("%s: invalid device object", __func__);
return;
}
struct BarService *serviceImpl = (struct BarService *)deviceObject->service;
if (serviceImpl != NULL) {
BarServiceRelease(serviceImpl);
}
}
struct HdfDriverEntry g_barDriverEntry = {
.moduleVersion = 1,
.moduleName = "BAR_SERVICE",
.Bind = HdfBarDriverBind,
.Init = HdfBarDriverInit,
.Release = HdfBarDriverRelease,
};
HDF_INIT(g_barDriverEntry);
//drivers/peripheral/bar/hdi_service/BUILD.gn
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//drivers/hdf_core/adapter/khdf/liteos_m/hdf.gni")
module_switch = defined(LOSCFG_DRIVERS_HDF)
hdf_driver("bar_driver") {
sources = [
"bar_driver.c",
"bar_service.c",
]
include_dirs = [ "$HDF_FRAMEWORKS_PATH/include/util" ]
deps = [ "//drivers/interface/bar/v1_0:bar_idl_headers" ]
}
//drivers/peripheral/bar/BUILD.gn
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
group("bar_entry") {
deps = [ "//drivers/peripheral/bar/hdi_service:bar_driver" ]
}
部件配置
新建drivers/peripheral/bar/build.json
用于定义新增的drivers_peripheral_bar部件:
{
"name": "drivers_peripheral_bar",
"description": "bar device driver",
"version": "3.1",
"license": "Apache License 2.0",
"component": {
"name": "drivers_peripheral_bar",
"subsystem": "hdf",
"syscap": [""],
"adapted_system_type": ["mini"], # mini表示此部件支持mini系统
"rom": "675KB",
"ram": "7400KB",
"deps": {
"components": [
"hdf_core",
"hiviewdfx_hilog_native",
"c_utils"
],
"third_part": [
"bounds_checking_function"
]
},
"build": {
"sub_component": [
"//drivers/peripheral/bar:bar_entry"
],
"test": [],
"inner_kits": [
]
}
}
}
以master分支,iotlink_demo产品为例:
//vendor/chipsea/iotlink_demo/config.json,在hdf子系统下添加drivers_interface_foo部件
{
"subsystem": "hdf",
"components": [
{ "component": "drivers_peripheral_bar", "features":[] }
]
}
以上配置完成后,即可指定部件名进行编译
./build.sh --product-name iotlink_demo --build-target drivers_peripheral_bar
本章节主要介绍HDI接口调用方式。
#include "v1_0/ibar.h"
struct IBar *bar = (struct IBar *)DevSvcManagerClntGetService("BAR_SERVICE"); //注意BAR_SERVICE 与bar_driver.c里的moduleName相同
const uint32_t recvMsgLen = 10;
char recvMsg[recvMsgLen] = { 0 };
int32_t ret = bar->Ping(bar, "send message", recvMsg, recvMsgLen);
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。