1e41f4b71Sopenharmony_ci# Third-Party SDK Integration<a name="EN-US_TOPIC_0000001051612018"></a> 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciTo 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. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## Planning a Directory Structure<a name="section1736472718351"></a> 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ciA 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**. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciBased on the preceding features, third-party SDK directories can be divided as follows in the OpenHarmony directory structure: 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci- domains/iot/link/: The **adapter** is stored in this directory and is decoupled from the module. 12e41f4b71Sopenharmony_ci- device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/: The service library **libs** is stored in this directory and is bound to the module. 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ciYou must perform the following steps before adaptation. The following uses the demolink SDK as an example. 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci1. Create vendor directories, **domains/iot/link/demolink/** and **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/**, to isolate different vendors. 17e41f4b71Sopenharmony_ci2. Create the **domains/iot/link/demolink/BUILD.gn** file to build the adaptation code. 18e41f4b71Sopenharmony_ci3. Create the **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/** directory to store the service library **libs**. 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci``` 21e41f4b71Sopenharmony_ci. 22e41f4b71Sopenharmony_ci├── domains 23e41f4b71Sopenharmony_ci│ └── iot 24e41f4b71Sopenharmony_ci│ └── link 25e41f4b71Sopenharmony_ci│ ├── demolink 26e41f4b71Sopenharmony_ci│ │ └── BUILD.gn 27e41f4b71Sopenharmony_ci│ ├── libbuild 28e41f4b71Sopenharmony_ci│ │ └── BUILD.gn 29e41f4b71Sopenharmony_ci│ └── BUILD.gn 30e41f4b71Sopenharmony_ci└── device 31e41f4b71Sopenharmony_ci └── hisilicon 32e41f4b71Sopenharmony_ci └── hispark_pegasus 33e41f4b71Sopenharmony_ci └── sdk_liteos 34e41f4b71Sopenharmony_ci └── 3rd_sdk 35e41f4b71Sopenharmony_ci └── demolink 36e41f4b71Sopenharmony_ci └── libs 37e41f4b71Sopenharmony_ci``` 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ci## Building the Service **libs**<a name="section442815485351"></a> 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ciGenerally, 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**. 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ciOpenHarmony 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: 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci``` 46e41f4b71Sopenharmony_ci. 47e41f4b71Sopenharmony_ci└── domains 48e41f4b71Sopenharmony_ci └── iot 49e41f4b71Sopenharmony_ci └── link 50e41f4b71Sopenharmony_ci ├── demolink 51e41f4b71Sopenharmony_ci │ └── BUILD.gn 52e41f4b71Sopenharmony_ci ├── libbuild 53e41f4b71Sopenharmony_ci │ └── BUILD.gn 54e41f4b71Sopenharmony_ci └── BUILD.gn 55e41f4b71Sopenharmony_ci``` 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_ciBefore building **libs**, you must perform the following steps: 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci1. Place the service source code files \(including **.c** and **.h** files\) in the **domains/iot/link/libbuild/** directory. 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci ``` 62e41f4b71Sopenharmony_ci . 63e41f4b71Sopenharmony_ci └── domains 64e41f4b71Sopenharmony_ci └── iot 65e41f4b71Sopenharmony_ci └── link 66e41f4b71Sopenharmony_ci ├── demolink 67e41f4b71Sopenharmony_ci │ ├── demosdk_adapter.c 68e41f4b71Sopenharmony_ci │ ├── demosdk_adapter.h 69e41f4b71Sopenharmony_ci │ └── BUILD.gn 70e41f4b71Sopenharmony_ci ├── libbuild 71e41f4b71Sopenharmony_ci │ ├── demosdk.c 72e41f4b71Sopenharmony_ci │ ├── demosdk.h 73e41f4b71Sopenharmony_ci │ └── BUILD.gn 74e41f4b71Sopenharmony_ci └── BUILD.gn 75e41f4b71Sopenharmony_ci ``` 76e41f4b71Sopenharmony_ci 77e41f4b71Sopenharmony_ci2. Adapt to the **domains/iot/link/libbuild/BUILD.gn** file and restore the file after the compilation is complete. 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci 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**. 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci ``` 82e41f4b71Sopenharmony_ci static_library("demosdk") { 83e41f4b71Sopenharmony_ci sources = [ 84e41f4b71Sopenharmony_ci "demosdk.c" 85e41f4b71Sopenharmony_ci ] 86e41f4b71Sopenharmony_ci include_dirs = [ 87e41f4b71Sopenharmony_ci "//domains/iot/link/libbuild", 88e41f4b71Sopenharmony_ci "//domains/iot/link/demolink" 89e41f4b71Sopenharmony_ci ] 90e41f4b71Sopenharmony_ci } 91e41f4b71Sopenharmony_ci ``` 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci3. Adapt to the **domains/iot/link/BUILD.gn** file and restore the file after the compilation is complete. 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci 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. 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci ``` 98e41f4b71Sopenharmony_ci import("//build/lite/config/subsystem/lite_subsystem.gni") 99e41f4b71Sopenharmony_ci import("//build/lite/config/component/lite_component.gni") 100e41f4b71Sopenharmony_ci lite_subsystem("iot") { 101e41f4b71Sopenharmony_ci subsystem_components = [ 102e41f4b71Sopenharmony_ci ":link" 103e41f4b71Sopenharmony_ci ] 104e41f4b71Sopenharmony_ci } 105e41f4b71Sopenharmony_ci lite_component("link") { 106e41f4b71Sopenharmony_ci features = [ 107e41f4b71Sopenharmony_ci "libbuild:demosdk" 108e41f4b71Sopenharmony_ci ] 109e41f4b71Sopenharmony_ci } 110e41f4b71Sopenharmony_ci ``` 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci 113e41f4b71Sopenharmony_ciAfter 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. 114e41f4b71Sopenharmony_ci 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ci 117e41f4b71Sopenharmony_ciCopy 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. 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci## Compiling Adaptation Code<a name="section3984721113613"></a> 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci## Compiling Code<a name="section830417531286"></a> 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_ciThe 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. 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci1. Check the description, parameters, and return values of the **DemoSdkCreateTask** API to adapt. 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci ``` 128e41f4b71Sopenharmony_ci struct TaskPara { 129e41f4b71Sopenharmony_ci char *name; 130e41f4b71Sopenharmony_ci void *(*func)(char* arg); 131e41f4b71Sopenharmony_ci void *arg; 132e41f4b71Sopenharmony_ci unsigned char prio; 133e41f4b71Sopenharmony_ci unsigned int size; 134e41f4b71Sopenharmony_ci }; 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci /* 137e41f4b71Sopenharmony_ci * Create a thread for the IoT OS. 138e41f4b71Sopenharmony_ci * Returns 0 if the operation is successful; returns a non-zero value otherwise. 139e41f4b71Sopenharmony_ci */ 140e41f4b71Sopenharmony_ci int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para); 141e41f4b71Sopenharmony_ci ``` 142e41f4b71Sopenharmony_ci 143e41f4b71Sopenharmony_ci2. 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. 144e41f4b71Sopenharmony_ci 145e41f4b71Sopenharmony_ci ``` 146e41f4b71Sopenharmony_ci typedef struct { 147e41f4b71Sopenharmony_ci const char *name; ///< name of the thread 148e41f4b71Sopenharmony_ci uint32_t attr_bits; ///< attribute bits 149e41f4b71Sopenharmony_ci void *cb_mem; ///< memory for control block 150e41f4b71Sopenharmony_ci uint32_t cb_size; ///< size of provided memory for control block 151e41f4b71Sopenharmony_ci void *stack_mem; ///< memory for stack 152e41f4b71Sopenharmony_ci uint32_t stack_size; ///< size of stack 153e41f4b71Sopenharmony_ci osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) 154e41f4b71Sopenharmony_ci TZ_ModuleId_t tz_module; ///< TrustZone module identifier 155e41f4b71Sopenharmony_ci uint32_t reserved; ///< reserved (must be 0) 156e41f4b71Sopenharmony_ci } osThreadAttr_t; 157e41f4b71Sopenharmony_ci 158e41f4b71Sopenharmony_ci /// Create a thread and add it to Active Threads. 159e41f4b71Sopenharmony_ci /// \param[in] func thread function. 160e41f4b71Sopenharmony_ci /// \param[in] argument pointer that is passed to the thread function as start argument. 161e41f4b71Sopenharmony_ci /// \param[in] attr thread attributes; NULL: default values. 162e41f4b71Sopenharmony_ci /// \return thread ID for reference by other functions or NULL in case of error. 163e41f4b71Sopenharmony_ci osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); 164e41f4b71Sopenharmony_ci ``` 165e41f4b71Sopenharmony_ci 166e41f4b71Sopenharmony_ci3. Perform code adaptation to shield the difference. 167e41f4b71Sopenharmony_ci 168e41f4b71Sopenharmony_ci ``` 169e41f4b71Sopenharmony_ci int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para) 170e41f4b71Sopenharmony_ci { 171e41f4b71Sopenharmony_ci osThreadAttr_t attr = {0}; 172e41f4b71Sopenharmony_ci osThreadId_t threadId; 173e41f4b71Sopenharmony_ci if (handle == 0 || para == 0) { 174e41f4b71Sopenharmony_ci return DEMOSDK_ERR; 175e41f4b71Sopenharmony_ci } 176e41f4b71Sopenharmony_ci if (para->func == 0) { 177e41f4b71Sopenharmony_ci return DEMOSDK_ERR; 178e41f4b71Sopenharmony_ci } 179e41f4b71Sopenharmony_ci if (para->name == 0) { 180e41f4b71Sopenharmony_ci return DEMOSDK_ERR; 181e41f4b71Sopenharmony_ci } 182e41f4b71Sopenharmony_ci attr.name = para->name; 183e41f4b71Sopenharmony_ci attr.priority = para->prio; 184e41f4b71Sopenharmony_ci attr.stack_size = para->size; 185e41f4b71Sopenharmony_ci threadId = osThreadNew((osThreadFunc_t)para->func, para->arg, &attr); 186e41f4b71Sopenharmony_ci if (threadId == 0) { 187e41f4b71Sopenharmony_ci printf("osThreadNew fail\n"); 188e41f4b71Sopenharmony_ci return DEMOSDK_ERR; 189e41f4b71Sopenharmony_ci } 190e41f4b71Sopenharmony_ci *(unsigned int *)handle = (unsigned int)threadId; 191e41f4b71Sopenharmony_ci return DEMOSDK_OK; 192e41f4b71Sopenharmony_ci } 193e41f4b71Sopenharmony_ci ``` 194e41f4b71Sopenharmony_ci 195e41f4b71Sopenharmony_ci 196e41f4b71Sopenharmony_ci## Compiling a Script<a name="section13500201173710"></a> 197e41f4b71Sopenharmony_ci 198e41f4b71Sopenharmony_ciAfter 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**. 199e41f4b71Sopenharmony_ci 200e41f4b71Sopenharmony_ci``` 201e41f4b71Sopenharmony_ciimport("//build/lite/config/component/lite_component.gni") 202e41f4b71Sopenharmony_cistatic_library("demolinkadapter") { 203e41f4b71Sopenharmony_ci sources = [ 204e41f4b71Sopenharmony_ci "demosdk_adapter.c" 205e41f4b71Sopenharmony_ci ] 206e41f4b71Sopenharmony_ci include_dirs = [ 207e41f4b71Sopenharmony_ci "//kernel/liteos-m/kal/cmsis", 208e41f4b71Sopenharmony_ci "//domains/iot/link/demolink" 209e41f4b71Sopenharmony_ci ] 210e41f4b71Sopenharmony_ci} 211e41f4b71Sopenharmony_ci``` 212e41f4b71Sopenharmony_ci 213e41f4b71Sopenharmony_ciModify the **domains/iot/link/BUILD.gn** file so that the **domain/iot/hilink/BUILD.gn** file is used in the build. 214e41f4b71Sopenharmony_ci 215e41f4b71Sopenharmony_ci``` 216e41f4b71Sopenharmony_ciimport("//build/lite/config/subsystem/lite_subsystem.gni") 217e41f4b71Sopenharmony_ciimport("//build/lite/config/component/lite_component.gni") 218e41f4b71Sopenharmony_cilite_subsystem("iot") { 219e41f4b71Sopenharmony_ci subsystem_components = [ 220e41f4b71Sopenharmony_ci ":link" 221e41f4b71Sopenharmony_ci ] 222e41f4b71Sopenharmony_ci} 223e41f4b71Sopenharmony_cilite_component("link") { 224e41f4b71Sopenharmony_ci features = [ 225e41f4b71Sopenharmony_ci "demolink:demolinkadapter" 226e41f4b71Sopenharmony_ci ] 227e41f4b71Sopenharmony_ci} 228e41f4b71Sopenharmony_ci``` 229e41f4b71Sopenharmony_ci 230e41f4b71Sopenharmony_ci## Compiling Service Code<a name="section8754114803918"></a> 231e41f4b71Sopenharmony_ci 232e41f4b71Sopenharmony_ciAfter the service library **libs** and adaptation code are ready, compile the service entry function to call the service entry of the third-party SDK. 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ciThe following uses **demolink** as an example to describe how to compile code in **applications/sample/wifi-iot/app/** to call the **demosdk** entry function. 235e41f4b71Sopenharmony_ci 236e41f4b71Sopenharmony_ci1. Create a directory. 237e41f4b71Sopenharmony_ci 238e41f4b71Sopenharmony_ci 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. 239e41f4b71Sopenharmony_ci 240e41f4b71Sopenharmony_ci For example, add the service directory **demolink** to the app, and create the service entry code **helloworld.c** and compile the **BUILD.gn** file. 241e41f4b71Sopenharmony_ci 242e41f4b71Sopenharmony_ci ``` 243e41f4b71Sopenharmony_ci . 244e41f4b71Sopenharmony_ci └── applications 245e41f4b71Sopenharmony_ci └── sample 246e41f4b71Sopenharmony_ci └── wifi-iot 247e41f4b71Sopenharmony_ci └── app 248e41f4b71Sopenharmony_ci │── demolink 249e41f4b71Sopenharmony_ci │ │── helloworld.c 250e41f4b71Sopenharmony_ci │ └── BUILD.gn 251e41f4b71Sopenharmony_ci └── BUILD.gn 252e41f4b71Sopenharmony_ci ``` 253e41f4b71Sopenharmony_ci 254e41f4b71Sopenharmony_ci2. Compile service code. 255e41f4b71Sopenharmony_ci 256e41f4b71Sopenharmony_ci 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. 257e41f4b71Sopenharmony_ci 258e41f4b71Sopenharmony_ci ``` 259e41f4b71Sopenharmony_ci #include "hos_init.h" 260e41f4b71Sopenharmony_ci #include "demosdk.h" 261e41f4b71Sopenharmony_ci 262e41f4b71Sopenharmony_ci void DemoSdkMain(void) 263e41f4b71Sopenharmony_ci { 264e41f4b71Sopenharmony_ci DemoSdkEntry(); 265e41f4b71Sopenharmony_ci } 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_ci SYS_RUN(DemoSdkMain); 268e41f4b71Sopenharmony_ci ``` 269e41f4b71Sopenharmony_ci 270e41f4b71Sopenharmony_ci3. Compile build scripts. 271e41f4b71Sopenharmony_ci 272e41f4b71Sopenharmony_ci 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**. 273e41f4b71Sopenharmony_ci 274e41f4b71Sopenharmony_ci ``` 275e41f4b71Sopenharmony_ci static_library("example_demolink") { 276e41f4b71Sopenharmony_ci sources = [ 277e41f4b71Sopenharmony_ci "helloworld.c" 278e41f4b71Sopenharmony_ci ] 279e41f4b71Sopenharmony_ci include_dirs = [ 280e41f4b71Sopenharmony_ci "//utils/native/lite/include", 281e41f4b71Sopenharmony_ci "//domains/iot/link/libbuild" 282e41f4b71Sopenharmony_ci ] 283e41f4b71Sopenharmony_ci } 284e41f4b71Sopenharmony_ci ``` 285e41f4b71Sopenharmony_ci 286e41f4b71Sopenharmony_ci Modify the **applications/sample/wifi-iot/app/BUILD.gn** file so that **demolink** is used in compilation. 287e41f4b71Sopenharmony_ci 288e41f4b71Sopenharmony_ci ``` 289e41f4b71Sopenharmony_ci import("//build/lite/config/component/lite_component.gni") 290e41f4b71Sopenharmony_ci lite_component("app") { 291e41f4b71Sopenharmony_ci features = [ 292e41f4b71Sopenharmony_ci "demolink:example_demolink" 293e41f4b71Sopenharmony_ci ] 294e41f4b71Sopenharmony_ci } 295e41f4b71Sopenharmony_ci ``` 296e41f4b71Sopenharmony_ci 297e41f4b71Sopenharmony_ci 298e41f4b71Sopenharmony_ci## Runtime<a name="section7737749184012"></a> 299e41f4b71Sopenharmony_ci 300e41f4b71Sopenharmony_ciRun 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**. 301e41f4b71Sopenharmony_ci 302e41f4b71Sopenharmony_ci``` 303e41f4b71Sopenharmony_ciready to OS start 304e41f4b71Sopenharmony_cisdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00 305e41f4b71Sopenharmony_ciformatting spiffs... 306e41f4b71Sopenharmony_ciFileSystem mount ok. 307e41f4b71Sopenharmony_ciwifi init success! 308e41f4b71Sopenharmony_ciit is demosdk entry. 309e41f4b71Sopenharmony_ciit is demo biz: hello world. 310e41f4b71Sopenharmony_ciit is demo biz: hello world. 311e41f4b71Sopenharmony_ci``` 312e41f4b71Sopenharmony_ci 313e41f4b71Sopenharmony_ci## End<a name="section153301392411"></a> 314e41f4b71Sopenharmony_ci 315e41f4b71Sopenharmony_ciThe third-party SDK integration is complete. 316e41f4b71Sopenharmony_ci 317