0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙OpenHarmony【集成三方SDK】 (基于Hi3861开发板)

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-04-24 15:11 次阅读

OpenHarmony致力于打造一套更加开放完善的IoT生态系统,为此OpenHarmony规划了一组目录,用于将各厂商SDK集成到OpenHarmony中。本文档基于Hi3861开发板,向平台开发者介绍将SDK集成到OpenHarmony的方法。

规划目录结构

三方SDK通常由静态库和适配代码构成。SDK的业务逻辑通过硬件模组工具链编译得到静态库libs,每款模组都有其对应的libs。SDK的南向API与OpenHarmony 的API存在使用差异,该差异可通过adapter适配代码屏蔽,不同模组可共用一套adapter。

基于以上特征,在OpenHarmony目录结构中,可以对三方SDK目录做如下划分。

  • 适配代码adapter,放置到domains/iot/link/ 目录下,与模组解耦。
  • 业务库libs,放置到device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/ 目录下,与模组绑定。

平台开发者在适配前,务必先依次完成以下步骤,下面以demolink SDK举例,进行介绍。

  1. 创建厂商目录,domains/iot/link/demolink/、device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/ ,用于厂商隔离。
  2. 创建domains/iot/link/demolink/BUILD.gn ,用于构建适配代码。
  3. 创建device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/libs/ 目录,用于存放业务库libs。

鸿蒙开发指导文档:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]

搜狗高速浏览器截图20240326151547.png

.
├── domains
│   └── iot
│       └── link
│           ├── demolink
│           │   └── BUILD.gn
│           ├── libbuild
│           │   └── BUILD.gn
│           └── BUILD.gn
└── device
     └── hisilicon
         └── hispark_pegasus
             └── sdk_liteos
                 └── 3rd_sdk
                     └── demolink
                         └── libs
HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿

构建业务libs

平台SDK业务一般以静态库的形式提供,平台厂商在获取到OpenHarmony代码后,需要根据对应的硬件模组vendor,编译业务libs,并将编译结果放置在device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/libs/ 目录下。下面介绍业务libs的构建方法。

OpenHarmony已规划用于编译业务libs的目录domains/iot/link/libbuild/ ,该目录中包含domains/iot/link/libbuild/BUILD.gn和domains/iot/link/BUILD.gn文件,目录结构如下。

.
└── domains
    └── iot
        └── link
            ├── demolink
            │   └── BUILD.gn
            ├── libbuild
            │   └── BUILD.gn
            └── BUILD.gn

平台开发者在构建libs前,务必先完成如下步骤。

  1. 在domains/iot/link/libbuild/ 目录下放置业务源码文件,包括.c和.h文件。
    .
    └── domains
        └── iot
            └── link
                ├── demolink
                │   ├── demosdk_adapter.c
                │   ├── demosdk_adapter.h
                │   └── BUILD.gn
                ├── libbuild
                │   ├── demosdk.c
                │   ├── demosdk.h
                │   └── BUILD.gn
                └── BUILD.gn
    
  2. 适配domains/iot/link/libbuild/BUILD.gn,在编译完成后还原该文件。
    在BUILD.gn中,sources为需要参与构建的源文件,include_dirs为依赖的头文件路径,构建的目标结果是生成静态库libdemosdk.a。
    static_library("demosdk") {
        sources = [
            "demosdk.c"
        ]
        include_dirs = [
            "//domains/iot/link/libbuild",
            "//domains/iot/link/demolink"
        ]
    }
    
  3. 适配domains/iot/link/BUILD.gn,在编译完成后还原该文件。
    此BUILD.gn文件用于指定构建条目,需要在features中填入所有需参与编译的静态库条目,使domains/iot/link/libbuild/BUILD.gn参与到构建中来。
    import("//build/lite/config/subsystem/lite_subsystem.gni")
    import("//build/lite/config/component/lite_component.gni")
    lite_subsystem("iot") {
        subsystem_components = [
            ":link"
        ]
    }
    lite_component("link") {
        features = [
            "libbuild:demosdk"
        ]
    }
    

完成以上3点后,需在代码根目录下执行命令“hb build -T //domains/iot/link:iot”,等待执行完成,检查out/hispark_pegasus/wifiiot_hispark_pegasus/libs/目录下是否生成了目标库文件。

将库文件拷贝到device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/libs/ 目录下,并将domains/iot/link/libbuild/ 目录中的.c和.h文件清除。

编写适配代码

代码编写

平台SDK中使用的API通常与OpenHarmony API存在差异,无法直接使用,需要一层适配代码adapter进行中间转换。本节以domains/iot/link/demolink/demosdk_adapter.c中的任务创建接口DemoSdkCreateTask举例,向开发者演示如何在OpenHarmony上编写适配代码。

  1. 查看待适配接口DemoSdkCreateTask的描述、参数、返回值。
    struct TaskPara {
        char *name;
        void *(*func)(char* arg);
        void *arg;
        unsigned char prio;
        unsigned int size;
    };
    
    /*
     * IoT OS 创建线程接口
     * 返回值: 返回0 成功, 其他 失败
     */
    int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para);
    
  2. 查看OpenHarmony API接口文档,选取一个功能类似的接口,并比对参数及用法上的差异。例如本文选取osThreadNew ,通过和DemoSdkCreateTask接口比对,可以发现两接口依赖的参数基本一致,只是参数所归属的结构体不同。
    typedef struct {
        const char                   *name;   ///< name of the thread
        uint32_t                 attr_bits;   ///< attribute bits
        void                      *cb_mem;    ///< memory for control block
        uint32_t                   cb_size;   ///< size of provided memory for control block
        void                   *stack_mem;    ///< memory for stack
        uint32_t                stack_size;   ///< size of stack
        osPriority_t              priority;   ///< initial thread priority (default: osPriorityNormal)
        TZ_ModuleId_t            tz_module;   ///< TrustZone module identifier
        uint32_t                  reserved;   ///< reserved (must be 0)
    } osThreadAttr_t;
    
    /// Create a thread and add it to Active Threads.
    /// param[in]     func          thread function.
    /// param[in]     argument      pointer that is passed to the thread function as start argument.
    /// param[in]     attr          thread attributes; NULL: default values.
    /// return thread ID for reference by other functions or NULL in case of error.
    osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
    
  3. 完成代码差异转换。
    int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para)
    {
        osThreadAttr_t attr = {0};
        osThreadId_t threadId;
        if (handle == 0 || para == 0) {
            return DEMOSDK_ERR;
        }
        if (para- >func == 0) {
            return DEMOSDK_ERR;
        }
        if (para- >name == 0) {
            return DEMOSDK_ERR;
        }
        attr.name = para- >name;
        attr.priority = para- >prio;
        attr.stack_size = para- >size;
        threadId = osThreadNew((osThreadFunc_t)para- >func, para- >arg, &attr);
        if (threadId == 0) {
            printf("osThreadNew failn");
            return DEMOSDK_ERR;
        }
        *(unsigned int *)handle = (unsigned int)threadId;
        return DEMOSDK_OK;
    }
    

脚本编写

开发者在完成代码适配后,还需要在adapter同级目录下新建BUILD.gn文件。该文件可在整包构建时,将适配代码编译成静态库,并链接到bin包中去。在domains/iot/link/demolink/BUILD.gn中,sources中为需要参与构建的源文件,include_dirs中为依赖的头文件路径,构建目标结果是生产静态库libdemolinkadapter.a。

import("//build/lite/config/component/lite_component.gni")
static_library("demolinkadapter") {
    sources = [
        "demosdk_adapter.c"
    ]
    include_dirs = [
        "//kernel/liteos-m/kal/cmsis",
        "//domains/iot/link/demolink"
    ]
}

修改domains/iot/link/BUILD.gn文件,使domain/iot/hilink/BUILD.gn参与到构建系统中。

import("//build/lite/config/subsystem/lite_subsystem.gni")
import("//build/lite/config/component/lite_component.gni")
lite_subsystem("iot") {
    subsystem_components = [
        ":link"
    ]
}
lite_component("link") {
    features = [
        "demolink:demolinkadapter"
    ]
}

编写业务代码

业务libs库和适配代码准备就绪后,还需要编写业务入口函数,调起三方SDK的业务入口。

下面以demolink举例,介绍如何在applications/sample/wifi-iot/app/路径下编写代码,调起demosdk的入口函数。

  1. 目录创建
    开发者编写业务时,务必先在applications/sample/wifi-iot/app/ 路径下新建一个目录(或一套目录结构),用于存放业务源码文件。
    例如:在app下新增业务目录demolink,并在其中创建业务入口代码helloworld.c和编译构建文件BUILD.gn,如下。

    .
    └── applications
        └── sample
            └── wifi-iot
                └── app
                    │── demolink
                    │    │── helloworld.c
                    │    └── BUILD.gn
                    └── BUILD.gn
    
  2. 编写业务代码。
    在helloworld.c文件中编写业务入口函数DemoSdkMain,并调起demolink的业务DemoSdkEntry,最后通过SYS_RUN()调用入口函数完成业务启动。

    #include "hos_init.h"
    #include "demosdk.h"
    
    void DemoSdkMain(void)
    {
        DemoSdkEntry();
    }
    
    SYS_RUN(DemoSdkMain);
    
  3. 编写构建脚本
    新增applications/sample/wifi-iot/app/demolink/BUILD.gn文件,指定源码和头文件路径,编译输出静态库文件libexample_demolink.a。

    static_library("example_demolink") {
        sources = [
            "helloworld.c"
        ]
        include_dirs = [
            "//utils/native/lite/include",
            "//domains/iot/link/libbuild"
        ]
    }
    

    修改applications/sample/wifi-iot/app/BUILD.gn,使demolink参与编译。

    import("//build/lite/config/component/lite_component.gni")
    lite_component("app") {
        features = [
            "demolink:example_demolink"
        ]
    }
    

运行

在代码根目录下,执行命令“hb build”编译输出版本包。最后启动运行,运行结果如图所示,与demolink预期相符。

ready to OS start
sdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00
formatting spiffs...
FileSystem mount ok.
wifi init success!
it is demosdk entry.
it is demo biz: hello world.
it is demo biz: hello world.

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 开发板
    +关注

    关注

    25

    文章

    4601

    浏览量

    95108
  • SDK
    SDK
    +关注

    关注

    3

    文章

    981

    浏览量

    45074
  • 鸿蒙
    +关注

    关注

    55

    文章

    2097

    浏览量

    42270
  • OpenHarmony
    +关注

    关注

    24

    文章

    3485

    浏览量

    15410
收藏 人收藏

    评论

    相关推荐

    鸿蒙OpenHarmony【轻量系统运行】 (基于Hi3861开发板

    由于Hi3861为WLAN模组,您可以在版本编译及烧录后,通过如下操作,使开发板实现联网功能。
    的头像 发表于 04-23 09:50 470次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OpenHarmony</b>【轻量系统运行】 (基于<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>)

    鸿蒙OpenHarmony【轻量系统 环境搭建】 (基于Hi3861开发板

    除上述[安装库和工具集]和[安装编译工具]外,针对Hi3861开发板还需要安装特定的编译工具。
    的头像 发表于 04-26 17:47 1056次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OpenHarmony</b>【轻量系统 环境搭建】 (基于<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>)

    鸿蒙OpenHarmony【轻量系统 烧录】 (基于Hi3861开发板

    针对Hi3861开发板,除了DevEco Device Tool
    的头像 发表于 05-10 16:59 653次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OpenHarmony</b>【轻量系统 烧录】 (基于<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>)

    鸿蒙OpenHarmony【轻量系统 运行】 (基于Hi3861开发板

    由于Hi3861为WLAN模组,您可以在版本编译及烧录后,通过如下操作,使开发板实现联网功能。
    的头像 发表于 05-10 16:38 464次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OpenHarmony</b>【轻量系统 运行】 (基于<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>)

    盘点那些硬件+项目学习套件:Hi3861鸿蒙开发板及入门常见问题解答

    ,一个是鸿蒙应用开发,一个是鸿蒙设备开发。我们的Hi3861鸿蒙
    发表于 02-01 16:55

    Hi3861开发板介绍

    介绍Hi3861 WLAN模组的开发环境搭建、版本编译构建、烧录、源码修改、调试验证等方法。通过学习,开发者会对Hi3861 WLAN模组开发
    发表于 09-21 15:15

    鸿蒙开发板Hi3861烧录报错?

    各位高手:鸿蒙开发板烧录时出现如下错误,请问怎么解决?> Executing task: c:\users\xiexg\.deveco-device-tool\core\deveco-venv
    发表于 05-18 15:18

    【视频】设备开发第5期:SDK集成指南

    本课程以Hi3861开发板为例介绍了设备开发时如何集成三方SDK,并结合官网文档和开源代码展示了
    发表于 12-23 12:34

    基于鸿蒙系统+Hi3861的WiFi小车开发

    本文简单介绍鸿蒙系统 + Hi3861 的WiFi小车开发,适用于开发润和Hi3861开发板的小
    的头像 发表于 03-03 09:31 5045次阅读
    基于<b class='flag-5'>鸿蒙</b>系统+<b class='flag-5'>Hi3861</b>的WiFi小车<b class='flag-5'>开发</b>

    自制Hi3861开发板(附原理图和电路图)

    OpenHarmony的发展已经进入了新的阶段,逐步把重点向富设备开发方向。OpenHarmony 3.x的各大特性也是针对富设备来的,但是仍然支持轻量设备,如Hi3861芯片设备。于
    的头像 发表于 04-14 10:23 8708次阅读
    自制<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>(附原理图和电路图)

    Hi3861编译烧录更快捷

    更快捷 Hi3861作为OpenHarmony社区Top级开发板,相信很多鸿蒙智联设备开发者都在Linux上编译烧录过
    的头像 发表于 02-11 13:25 703次阅读

    纯Windows环境开发Hi3861,编译烧录更快捷

    更快捷 Hi3861作为OpenHarmony社区Top级开发板,相信很多鸿蒙智联设备开发者都在Linux上编译烧录过
    的头像 发表于 02-11 14:45 1461次阅读

    润开鸿Hi3861开发板介绍

    Hi3861开发板是一片大约2cm*5cm大小的开发板,是一款高度集成的2.4GHz WLAN SoC芯片,集成IEEE 802.11b/g
    的头像 发表于 04-27 10:59 2938次阅读
    润开鸿<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>介绍

    鸿蒙OpenHarmony【LED外设控制】 (基于Hi3861开发板

    OpenHarmony WLAN模组基于Hi3861平台提供了丰富的外设操作能力,包含I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等
    的头像 发表于 04-23 21:57 332次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OpenHarmony</b>【LED外设控制】 (基于<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>)

    鸿蒙OpenHarmony南向:【Hi3861开发板介绍】

    Hi3861开发板是一片大约2cm*5cm大小的开发板,是一款高度集成的2.4GHz WLAN SoC芯片,集成IEEE 802.11b/g
    的头像 发表于 05-06 17:19 455次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>OpenHarmony</b>南向:【<b class='flag-5'>Hi3861</b><b class='flag-5'>开发板</b>介绍】