OpenHarmony致力于打造一套更加開(kāi)放完善的IoT生態(tài)系統(tǒng),為此OpenHarmony規(guī)劃了一組目錄,用于將各廠商的SDK集成到OpenHarmony中。本文檔基于Hi3861開(kāi)發(fā)板,向平臺(tái)開(kāi)發(fā)者介紹將SDK集成到OpenHarmony的方法。
規(guī)劃目錄結(jié)構(gòu)
三方SDK通常由靜態(tài)庫(kù)和適配代碼構(gòu)成。SDK的業(yè)務(wù)邏輯通過(guò)硬件模組工具鏈編譯得到靜態(tài)庫(kù)libs,每款模組都有其對(duì)應(yīng)的libs。SDK的南向API與OpenHarmony 的API存在使用差異,該差異可通過(guò)adapter適配代碼屏蔽,不同模組可共用一套adapter。
基于以上特征,在OpenHarmony目錄結(jié)構(gòu)中,可以對(duì)三方SDK目錄做如下劃分。
- 適配代碼adapter,放置到domains/iot/link/ 目錄下,與模組解耦。
- 業(yè)務(wù)庫(kù)libs,放置到device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/ 目錄下,與模組綁定。
平臺(tái)開(kāi)發(fā)者在適配前,務(wù)必先依次完成以下步驟,下面以demolink SDK舉例,進(jìn)行介紹。
- 創(chuàng)建廠商目錄,domains/iot/link/demolink/、device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/ ,用于廠商隔離。
- 創(chuàng)建domains/iot/link/demolink/BUILD.gn ,用于構(gòu)建適配代碼。
- 創(chuàng)建device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/libs/ 目錄,用于存放業(yè)務(wù)庫(kù)libs。
鴻蒙開(kāi)發(fā)指導(dǎo)文檔:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
.
├── 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直接拿
構(gòu)建業(yè)務(wù)libs
平臺(tái)SDK業(yè)務(wù)一般以靜態(tài)庫(kù)的形式提供,平臺(tái)廠商在獲取到OpenHarmony代碼后,需要根據(jù)對(duì)應(yīng)的硬件模組vendor,編譯業(yè)務(wù)libs,并將編譯結(jié)果放置在device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/libs/ 目錄下。下面介紹業(yè)務(wù)libs的構(gòu)建方法。
OpenHarmony已規(guī)劃用于編譯業(yè)務(wù)libs的目錄domains/iot/link/libbuild/ ,該目錄中包含domains/iot/link/libbuild/BUILD.gn和domains/iot/link/BUILD.gn文件,目錄結(jié)構(gòu)如下。
.
└── domains
└── iot
└── link
├── demolink
│ └── BUILD.gn
├── libbuild
│ └── BUILD.gn
└── BUILD.gn
平臺(tái)開(kāi)發(fā)者在構(gòu)建libs前,務(wù)必先完成如下步驟。
- 在domains/iot/link/libbuild/ 目錄下放置業(yè)務(wù)源碼文件,包括.c和.h文件。
. └── domains └── iot └── link ├── demolink │ ├── demosdk_adapter.c │ ├── demosdk_adapter.h │ └── BUILD.gn ├── libbuild │ ├── demosdk.c │ ├── demosdk.h │ └── BUILD.gn └── BUILD.gn
- 適配domains/iot/link/libbuild/BUILD.gn,在編譯完成后還原該文件。
在BUILD.gn中,sources為需要參與構(gòu)建的源文件,include_dirs為依賴的頭文件路徑,構(gòu)建的目標(biāo)結(jié)果是生成靜態(tài)庫(kù)libdemosdk.a。static_library("demosdk") { sources = [ "demosdk.c" ] include_dirs = [ "http://domains/iot/link/libbuild", "http://domains/iot/link/demolink" ] }
- 適配domains/iot/link/BUILD.gn,在編譯完成后還原該文件。
此BUILD.gn文件用于指定構(gòu)建條目,需要在features中填入所有需參與編譯的靜態(tài)庫(kù)條目,使domains/iot/link/libbuild/BUILD.gn參與到構(gòu)建中來(lái)。import("http://build/lite/config/subsystem/lite_subsystem.gni") import("http://build/lite/config/component/lite_component.gni") lite_subsystem("iot") { subsystem_components = [ ":link" ] } lite_component("link") { features = [ "libbuild:demosdk" ] }
完成以上3點(diǎn)后,需在代碼根目錄下執(zhí)行命令“hb build -T //domains/iot/link:iot”,等待執(zhí)行完成,檢查out/hispark_pegasus/wifiiot_hispark_pegasus/libs/目錄下是否生成了目標(biāo)庫(kù)文件。
將庫(kù)文件拷貝到device/hisilicon/hispark_pegasus/sdk_liteos/3rd_sdk/demolink/libs/ 目錄下,并將domains/iot/link/libbuild/ 目錄中的.c和.h文件清除。
編寫(xiě)適配代碼
代碼編寫(xiě)
平臺(tái)SDK中使用的API通常與OpenHarmony API存在差異,無(wú)法直接使用,需要一層適配代碼adapter進(jìn)行中間轉(zhuǎn)換。本節(jié)以domains/iot/link/demolink/demosdk_adapter.c中的任務(wù)創(chuàng)建接口DemoSdkCreateTask舉例,向開(kāi)發(fā)者演示如何在OpenHarmony上編寫(xiě)適配代碼。
- 查看待適配接口DemoSdkCreateTask的描述、參數(shù)、返回值。
struct TaskPara { char *name; void *(*func)(char* arg); void *arg; unsigned char prio; unsigned int size; }; /* * IoT OS 創(chuàng)建線程接口 * 返回值: 返回0 成功, 其他 失敗 */ int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para);
- 查看OpenHarmony API接口文檔,選取一個(gè)功能類似的接口,并比對(duì)參數(shù)及用法上的差異。例如本文選取osThreadNew ,通過(guò)和DemoSdkCreateTask接口比對(duì),可以發(fā)現(xiàn)兩接口依賴的參數(shù)基本一致,只是參數(shù)所歸屬的結(jié)構(gòu)體不同。
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);
- 完成代碼差異轉(zhuǎn)換。
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; }
腳本編寫(xiě)
開(kāi)發(fā)者在完成代碼適配后,還需要在adapter同級(jí)目錄下新建BUILD.gn文件。該文件可在整包構(gòu)建時(shí),將適配代碼編譯成靜態(tài)庫(kù),并鏈接到bin包中去。在domains/iot/link/demolink/BUILD.gn中,sources中為需要參與構(gòu)建的源文件,include_dirs中為依賴的頭文件路徑,構(gòu)建目標(biāo)結(jié)果是生產(chǎn)靜態(tài)庫(kù)libdemolinkadapter.a。
import("http://build/lite/config/component/lite_component.gni")
static_library("demolinkadapter") {
sources = [
"demosdk_adapter.c"
]
include_dirs = [
"http://kernel/liteos-m/kal/cmsis",
"http://domains/iot/link/demolink"
]
}
修改domains/iot/link/BUILD.gn文件,使domain/iot/hilink/BUILD.gn參與到構(gòu)建系統(tǒng)中。
import("http://build/lite/config/subsystem/lite_subsystem.gni")
import("http://build/lite/config/component/lite_component.gni")
lite_subsystem("iot") {
subsystem_components = [
":link"
]
}
lite_component("link") {
features = [
"demolink:demolinkadapter"
]
}
編寫(xiě)業(yè)務(wù)代碼
業(yè)務(wù)libs庫(kù)和適配代碼準(zhǔn)備就緒后,還需要編寫(xiě)業(yè)務(wù)入口函數(shù),調(diào)起三方SDK的業(yè)務(wù)入口。
下面以demolink舉例,介紹如何在applications/sample/wifi-iot/app/路徑下編寫(xiě)代碼,調(diào)起demosdk的入口函數(shù)。
目錄創(chuàng)建
開(kāi)發(fā)者編寫(xiě)業(yè)務(wù)時(shí),務(wù)必先在applications/sample/wifi-iot/app/ 路徑下新建一個(gè)目錄(或一套目錄結(jié)構(gòu)),用于存放業(yè)務(wù)源碼文件。
例如:在app下新增業(yè)務(wù)目錄demolink,并在其中創(chuàng)建業(yè)務(wù)入口代碼helloworld.c和編譯構(gòu)建文件BUILD.gn,如下。. └── applications └── sample └── wifi-iot └── app │── demolink │ │── helloworld.c │ └── BUILD.gn └── BUILD.gn
編寫(xiě)業(yè)務(wù)代碼。
在helloworld.c文件中編寫(xiě)業(yè)務(wù)入口函數(shù)DemoSdkMain,并調(diào)起demolink的業(yè)務(wù)DemoSdkEntry,最后通過(guò)SYS_RUN()調(diào)用入口函數(shù)完成業(yè)務(wù)啟動(dòng)。#include "hos_init.h" #include "demosdk.h" void DemoSdkMain(void) { DemoSdkEntry(); } SYS_RUN(DemoSdkMain);
編寫(xiě)構(gòu)建腳本
新增applications/sample/wifi-iot/app/demolink/BUILD.gn文件,指定源碼和頭文件路徑,編譯輸出靜態(tài)庫(kù)文件libexample_demolink.a。static_library("example_demolink") { sources = [ "helloworld.c" ] include_dirs = [ "http://utils/native/lite/include", "http://domains/iot/link/libbuild" ] }
修改applications/sample/wifi-iot/app/BUILD.gn,使demolink參與編譯。
import("http://build/lite/config/component/lite_component.gni") lite_component("app") { features = [ "demolink:example_demolink" ] }
運(yùn)行
在代碼根目錄下,執(zhí)行命令“hb build”編譯輸出版本包。最后啟動(dòng)運(yùn)行,運(yùn)行結(jié)果如圖所示,與demolink預(yù)期相符。
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.
審核編輯 黃宇
-
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
5032瀏覽量
97371 -
SDK
+關(guān)注
關(guān)注
3文章
1035瀏覽量
45899 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2339瀏覽量
42804 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3713瀏覽量
16252
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論