• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Third-Party SDK Integration<a name="EN-US_TOPIC_0000001051612018"></a>
2
3To build a more open and complete Internet of Things \(IoT\) ecosystem, OpenHarmony has opened up a group of directories to integrate SDKs provided by different vendors. This guide describes how to integrate SDKs into OpenHarmony based on the Hi3861 board.
4
5## Planning a Directory Structure<a name="section1736472718351"></a>
6
7A third-party SDK consists of a static library and the adaption code. The SDK service logic is compiled to obtain the static library  **libs**  through the hardware module tool chain. Each module has its corresponding  **libs**. The southbound APIs of the SDK are different from the APIs of OpenHarmony. The difference can be shielded by using the adaptation code  **adapter**. Different modules can share the same  **adapter**.
8
9Based on the preceding features, third-party SDK directories can be divided as follows in the OpenHarmony directory structure:
10
11-   domains/iot/link/: The  **adapter**  is stored in this directory and is decoupled from the module.
12-   device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/: The service library  **libs**  is stored in this directory and is bound to the module.
13
14You must perform the following steps before adaptation. The following uses the demolink SDK as an example.
15
161.  Create vendor directories,  **domains/iot/link/demolink/**  and  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/**, to isolate different vendors.
172.  Create the  **domains/iot/link/demolink/BUILD.gn**  file to build the adaptation code.
183.  Create the  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/**  directory to store the service library  **libs**.
19
20```
21.
22├── domains
23│   └── iot
24│       └── link
25│           ├── demolink
26│           │   └── BUILD.gn
27│           ├── libbuild
28│           │   └── BUILD.gn
29│           └── BUILD.gn
30└── device
31     └── hisilicon
32         └── hispark_pegasus
33             └── sdk_liteos
34                 └── 3rd_sdk
35                     └── demolink
36                         └── libs
37```
38
39## Building the Service  **libs**<a name="section442815485351"></a>
40
41Generally, the platform SDK service is provided as a static library. After obtaining the OpenHarmony code, the platform vendor needs to compile the service library  **libs**  based on the corresponding hardware module vendor and save the compilation result to the  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/**  directory. The following describes how to build the service library  **libs**.
42
43OpenHarmony has planned the  **domains/iot/link/libbuild/**  directory for compiling the service library  **libs**. This directory contains the  **domains/iot/link/libbuild/BUILD.gn**  and  **domains/iot/link/BUILD.gn**  files. The directory structure is as follows:
44
45```
46.
47└── domains
48    └── iot
49        └── link
50            ├── demolink
51            │   └── BUILD.gn
52            ├── libbuild
53            │   └── BUILD.gn
54            └── BUILD.gn
55```
56
57Before building  **libs**, you must perform the following steps:
58
591.  Place the service source code files \(including  **.c**  and  **.h**  files\) in the  **domains/iot/link/libbuild/**  directory.
60
61    ```
62    .
63    └── domains
64        └── iot
65            └── link
66                ├── demolink
67                │   ├── demosdk_adapter.c
68                │   ├── demosdk_adapter.h
69                │   └── BUILD.gn
70                ├── libbuild
71                │   ├── demosdk.c
72                │   ├── demosdk.h
73                │   └── BUILD.gn
74                └── BUILD.gn
75    ```
76
772.  Adapt to the  **domains/iot/link/libbuild/BUILD.gn**  file and restore the file after the compilation is complete.
78
79    In the  **BUILD.gn**  file,  **sources**  specifies the source file to build and  **include\_dirs**  specifies the path of the dependent header file so that the target build result is the static library  **libdemosdk.a**.
80
81    ```
82    static_library("demosdk") {
83        sources = [
84            "demosdk.c"
85        ]
86        include_dirs = [
87            "//domains/iot/link/libbuild",
88            "//domains/iot/link/demolink"
89        ]
90    }
91    ```
92
933.  Adapt to the  **domains/iot/link/BUILD.gn**  file and restore the file after the compilation is complete.
94
95    The  **BUILD.gn**  file is used to specify build entries. You need to enter all static library entries to be compiled in  **features**  so that the  **domains/iot/link/libbuild/BUILD.gn**  file is used in the build.
96
97    ```
98    import("//build/lite/config/subsystem/lite_subsystem.gni")
99    import("//build/lite/config/component/lite_component.gni")
100    lite_subsystem("iot") {
101        subsystem_components = [
102            ":link"
103        ]
104    }
105    lite_component("link") {
106        features = [
107            "libbuild:demosdk"
108        ]
109    }
110    ```
111
112
113After the preceding operations are complete, run the  **hb build -T //domains/iot/link:iot**  command in the root directory of the code and then check whether the target library file is generated in the  **out/hispark\_pegasus/wifiiot\_hispark\_pegasus/libs/**  directory.
114
115![](figures/device-wlan-sdk-files.png)
116
117Copy the library file to the  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/**  directory and delete the  **.c**  and  **.h**  files from the  **domains/iot/link/libbuild/**  directory.
118
119## Compiling Adaptation Code<a name="section3984721113613"></a>
120
121## Compiling Code<a name="section830417531286"></a>
122
123The APIs used in the platform SDK are different from the OpenHarmony APIs and cannot be directly used. Therefore, the adaptation code  **adapter**  is required for intermediate conversion. This section uses  **DemoSdkCreateTask**  in  **domains/iot/link/demolink/demosdk\_adapter.c**  as an example to describe how to compile adaptation code on OpenHarmony.
124
1251.  Check the description, parameters, and return values of the  **DemoSdkCreateTask**  API to adapt.
126
127    ```
128    struct TaskPara {
129        char *name;
130        void *(*func)(char* arg);
131        void *arg;
132        unsigned char prio;
133        unsigned int size;
134    };
135
136    /*
137     * Create a thread for the IoT OS.
138     * Returns 0 if the operation is successful; returns a non-zero value otherwise.
139     */
140    int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para);
141    ```
142
1432.  Check the OpenHarmony API document, select an API with similar features, and compare the parameters and usage. This guide uses  **osThreadNew**  as an example. By comparing this API with  **DemoSdkCreateTask**, you can find that the parameters on which the two APIs depend are basically the same, but the structures to which the parameters belong are different.
144
145    ```
146    typedef struct {
147        const char                   *name;   ///< name of the thread
148        uint32_t                 attr_bits;   ///< attribute bits
149        void                      *cb_mem;    ///< memory for control block
150        uint32_t                   cb_size;   ///< size of provided memory for control block
151        void                   *stack_mem;    ///< memory for stack
152        uint32_t                stack_size;   ///< size of stack
153        osPriority_t              priority;   ///< initial thread priority (default: osPriorityNormal)
154        TZ_ModuleId_t            tz_module;   ///< TrustZone module identifier
155        uint32_t                  reserved;   ///< reserved (must be 0)
156    } osThreadAttr_t;
157
158    /// Create a thread and add it to Active Threads.
159    /// \param[in]     func          thread function.
160    /// \param[in]     argument      pointer that is passed to the thread function as start argument.
161    /// \param[in]     attr          thread attributes; NULL: default values.
162    /// \return thread ID for reference by other functions or NULL in case of error.
163    osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
164    ```
165
1663.  Perform code adaptation to shield the difference.
167
168    ```
169    int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para)
170    {
171        osThreadAttr_t attr = {0};
172        osThreadId_t threadId;
173        if (handle == 0 || para == 0) {
174            return DEMOSDK_ERR;
175        }
176        if (para->func == 0) {
177            return DEMOSDK_ERR;
178        }
179        if (para->name == 0) {
180            return DEMOSDK_ERR;
181        }
182        attr.name = para->name;
183        attr.priority = para->prio;
184        attr.stack_size = para->size;
185        threadId = osThreadNew((osThreadFunc_t)para->func, para->arg, &attr);
186        if (threadId == 0) {
187            printf("osThreadNew fail\n");
188            return DEMOSDK_ERR;
189        }
190        *(unsigned int *)handle = (unsigned int)threadId;
191        return DEMOSDK_OK;
192    }
193    ```
194
195
196## Compiling a Script<a name="section13500201173710"></a>
197
198After completing code adaptation, create the  **BUILD.gn**  file in the directory where the  **adapter**  is located. This file can be used to compile the adaptation code into a static library and link the static library to the  **bin**  package during the entire package build. In the  **domains/iot/link/demolink/BUILD.gn**  file,  **sources**  specifies the source files to be used in the build and  **include\_dirs**  specifies the path of the dependent header file so that the target build result is the static library  **libdemolinkadapter.a**.
199
200```
201import("//build/lite/config/component/lite_component.gni")
202static_library("demolinkadapter") {
203    sources = [
204        "demosdk_adapter.c"
205    ]
206    include_dirs = [
207        "//kernel/liteos-m/kal/cmsis",
208        "//domains/iot/link/demolink"
209    ]
210}
211```
212
213Modify the  **domains/iot/link/BUILD.gn**  file so that the  **domain/iot/hilink/BUILD.gn**  file is used in the build.
214
215```
216import("//build/lite/config/subsystem/lite_subsystem.gni")
217import("//build/lite/config/component/lite_component.gni")
218lite_subsystem("iot") {
219    subsystem_components = [
220        ":link"
221    ]
222}
223lite_component("link") {
224    features = [
225        "demolink:demolinkadapter"
226    ]
227}
228```
229
230## Compiling Service Code<a name="section8754114803918"></a>
231
232After the service library  **libs**  and adaptation code are ready, compile the service entry function to call the service entry of the third-party SDK.
233
234The following uses  **demolink**  as an example to describe how to compile code in  **applications/sample/wifi-iot/app/**  to call the  **demosdk**  entry function.
235
2361.  Create a directory.
237
238    Before compiling a service, you must create a directory \(or a directory structure\) in  **applications/sample/wifi-iot/app/**  to store service source code files.
239
240    For example, add the service directory  **demolink**  to the app, and create the service entry code  **helloworld.c**  and compile the  **BUILD.gn**  file.
241
242    ```
243    .
244    └── applications
245        └── sample
246            └── wifi-iot
247                └── app
248                    │── demolink
249                    │    │── helloworld.c
250                    │    └── BUILD.gn
251                    └── BUILD.gn
252    ```
253
2542.  Compile service code.
255
256    Compile the service entry function  **DemoSdkMain**  in the  **helloworld.c**  file, call the service entry  **DemoSdkEntry**  of  **demolink**, and call the entry function through  **SYS\_RUN\(\)**  to start the service.
257
258    ```
259    #include "hos_init.h"
260    #include "demosdk.h"
261
262    void DemoSdkMain(void)
263    {
264        DemoSdkEntry();
265    }
266
267    SYS_RUN(DemoSdkMain);
268    ```
269
2703.  Compile build scripts.
271
272    Add the  **applications/sample/wifi-iot/app/demolink/BUILD.gn**  file, specify the paths of the source code and header file, and compile the static library file  **libexample\_demolink.a**.
273
274    ```
275    static_library("example_demolink") {
276        sources = [
277            "helloworld.c"
278        ]
279        include_dirs = [
280            "//utils/native/lite/include",
281            "//domains/iot/link/libbuild"
282        ]
283    }
284    ```
285
286    Modify the  **applications/sample/wifi-iot/app/BUILD.gn**  file so that  **demolink**  is used in compilation.
287
288    ```
289    import("//build/lite/config/component/lite_component.gni")
290    lite_component("app") {
291        features = [
292            "demolink:example_demolink"
293        ]
294    }
295    ```
296
297
298## Runtime<a name="section7737749184012"></a>
299
300Run the  **hb build**  command in the root directory of the code to compile and output the version package. Start  **demolink**. The following shows the running result, which is consistent with the expected result of  **demolink**.
301
302```
303ready to OS start
304sdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00
305formatting spiffs...
306FileSystem mount ok.
307wifi init success!
308it is demosdk entry.
309it is demo biz: hello world.
310it is demo biz: hello world.
311```
312
313## End<a name="section153301392411"></a>
314
315The third-party SDK integration is complete.
316
317