device-wifi-sdk.md 11.7 KB
Newer Older
M
mamingshuai 已提交
1
# 集成三方SDK<a name="ZH-CN_TOPIC_0000001051612018"></a>
W
wenjun 已提交
2

M
mamingshuai 已提交
3 4 5 6 7 8 9 10
-   [规划目录结构](#section1736472718351)
-   [构建业务libs](#section442815485351)
-   [编写适配代码](#section3984721113613)
-   [代码编写](#section830417531286)
-   [脚本编写](#section13500201173710)
-   [编写业务代码](#section8754114803918)
-   [运行](#section7737749184012)
-   [结束](#section153301392411)
[
[yang] 已提交
11

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

M
mamingshuai 已提交
14
## 规划目录结构<a name="section1736472718351"></a>
W
wenjun 已提交
15

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

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

N
NEEN 已提交
20 21
-   适配代码adapter,放置到domains/iot/link/ 目录下,与模组解耦。
-   业务库libs,放置到device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/ 目录下,与模组绑定。
W
wenjun 已提交
22 23 24

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

N
NEEN 已提交
25 26 27
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。
W
wenjun 已提交
28 29 30 31 32 33 34 35 36 37 38

```
.
├── domains
│   └── iot
│       └── link
│           ├── demolink
│           │   └── BUILD.gn
│           ├── libbuild
│           │   └── BUILD.gn
│           └── BUILD.gn
N
NEEN 已提交
39 40 41 42
└── device
     └── hisilicon
         └── hispark_pegasus
             └── sdk_liteos
W
wenjun 已提交
43 44 45 46 47
                 └── 3rd_sdk
                     └── demolink
                         └── libs
```

M
mamingshuai 已提交
48
## 构建业务libs<a name="section442815485351"></a>
W
wenjun 已提交
49

N
NEEN 已提交
50
平台SDK业务一般以静态库的形式提供,平台厂商在获取到OpenHarmony代码后,需要根据对应的硬件模组vendor,编译业务libs,并将编译结果放置在device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录下。下面介绍业务libs的构建方法。
W
wenjun 已提交
51

N
NEEN 已提交
52
OpenHarmony已规划用于编译业务libs的目录domains/iot/link/libbuild/ ,该目录中包含domains/iot/link/libbuild/BUILD.gn和domains/iot/link/BUILD.gn文件,目录结构如下。
W
wenjun 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

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

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

M
mamingshuai 已提交
68
1.  在domains/iot/link/libbuild/ 目录下放置业务源码文件,包括.c和.h文件。
W
wenjun 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

    ```
    .
    └── domains
        └── iot
            └── link
                ├── demolink
                │   ├── demosdk_adapter.c
                │   ├── demosdk_adapter.h
                │   └── BUILD.gn
                ├── libbuild
                │   ├── demosdk.c
                │   ├── demosdk.h
                │   └── BUILD.gn
                └── BUILD.gn
    ```

N
NEEN 已提交
86
2.  适配domains/iot/link/libbuild/BUILD.gn,在编译完成后还原该文件。
W
wenjun 已提交
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

    在BUILD.gn中,sources为需要参与构建的源文件,include\_dirs为依赖的头文件路径,构建的目标结果是生成静态库libdemosdk.a。

    ```
    static_library("demosdk") {
        sources = [
            "demosdk.c"
        ]
        include_dirs = [
            "//domains/iot/link/libbuild",
            "//domains/iot/link/demolink"
        ]
    }
    ```

N
NEEN 已提交
102
3.  适配domains/iot/link/BUILD.gn,在编译完成后还原该文件。
W
wenjun 已提交
103

N
NEEN 已提交
104
    此BUILD.gn文件用于指定构建条目,需要在features中填入所有需参与编译的静态库条目,使domains/iot/link/libbuild/BUILD.gn参与到构建中来。
W
wenjun 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

    ```
    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"
        ]
    }
    ```


N
NEEN 已提交
122
完成以上3点后,需在代码根目录下执行命令“hb build -T //domains/iot/link:iot”,等待执行完成,检查out/hispark\_pegasus/wifiiot\_hispark\_pegasus/libs/目录下是否生成了目标库文件。
W
wenjun 已提交
123

D
duangavin123 已提交
124
![](figure/zh-cn_image_0000001078563230.png)
W
wenjun 已提交
125

N
NEEN 已提交
126
将库文件拷贝到device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/ 目录下,并将domains/iot/link/libbuild/ 目录中的.c和.h文件清除。
W
wenjun 已提交
127

M
mamingshuai 已提交
128
## 编写适配代码<a name="section3984721113613"></a>
W
wenjun 已提交
129

M
mamingshuai 已提交
130
## 代码编写<a name="section830417531286"></a>
W
wenjun 已提交
131

N
NEEN 已提交
132
平台SDK中使用的API通常与OpenHarmony API存在差异,无法直接使用,需要一层适配代码adapter进行中间转换。本节以domains/iot/link/demolink/demosdk\_adapter.c中的任务创建接口DemoSdkCreateTask举例,向开发者演示如何在OpenHarmony上编写适配代码。
W
wenjun 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204

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 fail\n");
            return DEMOSDK_ERR;
        }
        *(unsigned int *)handle = (unsigned int)threadId;
        return DEMOSDK_OK;
    }
    ```


M
mamingshuai 已提交
205
## 脚本编写<a name="section13500201173710"></a>
W
wenjun 已提交
206

N
NEEN 已提交
207
开发者在完成代码适配后,还需要在adapter同级目录下新建BUILD.gn文件。该文件可在整包构建时,将适配代码编译成静态库,并链接到bin包中去。在domains/iot/link/demolink/BUILD.gn中,sources中为需要参与构建的源文件,include\_dirs中为依赖的头文件路径,构建目标结果是生产静态库libdemolinkadapter.a。
W
wenjun 已提交
208 209 210 211 212 213 214 215

```
import("//build/lite/config/component/lite_component.gni")
static_library("demolinkadapter") {
    sources = [
        "demosdk_adapter.c"
    ]
    include_dirs = [
N
NEEN 已提交
216
        "//kernel/liteos-m/kal/cmsis",
W
wenjun 已提交
217 218 219 220 221
        "//domains/iot/link/demolink"
    ]
}
```

N
NEEN 已提交
222
修改domains/iot/link/BUILD.gn文件,使domain/iot/hilink/BUILD.gn参与到构建系统中。
W
wenjun 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

```
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"
    ]
}
```

M
mamingshuai 已提交
239
## 编写业务代码<a name="section8754114803918"></a>
W
wenjun 已提交
240 241 242

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

N
NEEN 已提交
243
下面以demolink举例,介绍如何在applications/sample/wifi-iot/app/路径下编写代码,调起demosdk的入口函数。
W
wenjun 已提交
244 245 246

1.  目录创建

N
NEEN 已提交
247
    开发者编写业务时,务必先在applications/sample/wifi-iot/app/ 路径下新建一个目录(或一套目录结构),用于存放业务源码文件。
W
wenjun 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280

    例如:在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.  编写构建脚本

N
NEEN 已提交
281
    新增applications/sample/wifi-iot/app/demolink/BUILD.gn文件,指定源码和头文件路径,编译输出静态库文件libexample\_demolink.a。
W
wenjun 已提交
282 283 284 285 286 287 288

    ```
    static_library("example_demolink") {
        sources = [
            "helloworld.c"
        ]
        include_dirs = [
289
            "//utils/native/lite/include",
N
NEEN 已提交
290
            "//domains/iot/link/libbuild"
W
wenjun 已提交
291 292 293 294
        ]
    }
    ```

N
NEEN 已提交
295
    修改applications/sample/wifi-iot/app/BUILD.gn,使demolink参与编译。
W
wenjun 已提交
296 297 298 299 300 301 302 303 304 305 306

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


M
mamingshuai 已提交
307
## 运行<a name="section7737749184012"></a>
W
wenjun 已提交
308

N
NEEN 已提交
309
在代码根目录下,执行命令“hb build”编译输出版本包。最后启动运行,运行结果如图所示,与demolink预期相符。
W
wenjun 已提交
310 311 312 313 314 315 316 317 318 319 320 321

```
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.
```

M
mamingshuai 已提交
322
## 结束<a name="section153301392411"></a>
W
wenjun 已提交
323 324 325

至此,三方SDK集成已介绍完毕。