2 Star 4 Fork 6

yue / hdi_develop_guide

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
hdi_develop_guide_by_mini_system.md 13.16 KB
一键复制 编辑 原始数据 按行查看 历史
yue 提交于 2023-06-28 22:10 . 添加mini和small系统下HDI指导

mini(L0)系统HDI开发指导

简介

在mini系统上,HDI支持C,本文讲述如何在L0系统上进行HDI的开发。

HDI开发步骤

本文档以开发实例展示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;
};

idl编译配置

//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"
}

创建HDI接口部件

这里给出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":[] }
      ]
    }

idl编译及生成产物

以上配置完成后,即可指定部件名进行编译

./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                 # 自定义类型头文件

HDI服务实现

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":[] }
      ]
    }

idl编译及生成产物

以上配置完成后,即可指定部件名进行编译

./build.sh --product-name iotlink_demo --build-target drivers_peripheral_bar

HDI接口调用

本章节主要介绍HDI接口调用方式。

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);
1
https://gitee.com/yueyan233/hdi_develop_guide.git
git@gitee.com:yueyan233/hdi_develop_guide.git
yueyan233
hdi_develop_guide
hdi_develop_guide
master

搜索帮助