這一篇我們繼續(xù)深入一點點,嘗試打通從用戶態(tài)UI到內(nèi)核態(tài)HDF之間的聯(lián)系。其中涉及到的調(diào)用關(guān)系比較復雜,建議在“用鴻蒙開發(fā)AI應用(五)HDF 驅(qū)動補光燈”的基礎上閱讀本文,HDF的相關(guān)細節(jié)這里就不在贅述了。
背景知識
用戶程序框架子系統(tǒng)包含兩個大的模塊:Ability子系統(tǒng)和包管理子系統(tǒng)。
1. Ability子系統(tǒng)

1.1 Ability
Ability是系統(tǒng)調(diào)度應用的最小單元,是能夠完成一個獨立功能的組件,一個應用可以包含一個或多個Ability。Ability分為兩種類型:Page類型的Ability和Service類型的Ability
Page類型的Ability:帶有界面,為用戶提供人機交互的能力。
Service類型的Ability:不帶界面,為用戶提供后臺任務機制。
1.2 AbilitySlice
AbilitySlice是單個頁面及其控制邏輯的總和,是Page類型Ability特有的組件,一個Page類型的Ability可以包含多個AbilitySlice,此時,這些頁面提供的業(yè)務能力應當是高度相關(guān)的。

1.3 生命周期
生命周期是Ability被調(diào)度到啟動、激活、隱藏和退出等各個狀態(tài)的的統(tǒng)稱。

Ability生命周期各狀態(tài)解析:
UNINITIALIZED:未初始狀態(tài),為臨時狀態(tài),Ability被創(chuàng)建后會由UNINITIALIZED狀態(tài)進入INITIAL狀態(tài);
INITIAL:初始化狀態(tài),也表示停止狀態(tài),表示當前Ability未運行,調(diào)用Start后進入INACTIVE,同時回調(diào)開發(fā)者的OnStart生命周期回調(diào);
INACTIVE:未激活狀態(tài),表示當前窗口已顯示但是無焦點狀態(tài),由于Window暫未支持焦點的概念,當前狀態(tài)與ACTIVE一致。
ACTIVE:前臺激活狀態(tài),表示當前窗口已顯示,并獲取焦點,Ability在退到后臺之前先由ACTIVE狀態(tài)進入INACTIVE狀態(tài);
BACKGROUND: 后臺狀態(tài),表示當前Ability退到后臺,Ability在被銷毀后由BACKGROUND狀態(tài)進入INITIAL狀態(tài),或者重新被激活后由BACKGROUND狀態(tài)進入ACTIVE狀態(tài)。
1.4 AbilityLoader
AbilityLoader負責注冊和加載開發(fā)者Ability的模塊。開發(fā)者開發(fā)的Ability先要調(diào)用AbilityLoader的注冊接口注冊到框架中,接著Ability啟動時會被實例化。
1.5 AbilityManager
AbilityManager負責AbilityKit和Ability管理服務進行IPC的通信。
1.6 EventHandler
EventHandler是AbilityKit提供給開發(fā)者的用于在Ability中實現(xiàn)線程間通信的一個模塊。
1.7 Ability運行管理服務
Ability運行管理服務是用于協(xié)調(diào)各Ability運行關(guān)系、及生命周期進行調(diào)度的系統(tǒng)服務。
其中,服務啟動模塊負責Ability管理服務的啟動、注冊等。
服務接口管理模塊負責Ability管理服務對外能力的管理。
進程管理模塊負責Ability應用所在進程的啟動和銷毀、及其進程信息維護等功能。Ability棧管理模塊負責維護各個Ability之間跳轉(zhuǎn)的先后關(guān)系。
生命周期調(diào)度模塊是Ability管理服務根據(jù)系統(tǒng)當前的操作調(diào)度Ability進入相應的狀態(tài)的模塊。
連接管理模塊是Ability管理服務對Service類型Ability連接管理的模塊。
1.8 AppSpawn
AppSpawn是負責創(chuàng)建Ability應用所在進程的系統(tǒng)服務,該服務有較高的權(quán)限,為Ability應用設置相應的權(quán)限,并預加載一些通用的模塊,加速應用的啟動。
2. 包管理子系統(tǒng)
包管理子系統(tǒng),是OpenHarmony為開發(fā)者提供的安裝包管理框架。

BundleKit:是包管理服務對外提供的接口,有安裝/卸載接口、包信息查詢接口、包狀態(tài)變化監(jiān)聽接口。
包掃描器:用來解析本地預制或者安裝的安裝包,提取里面的各種信息,供管理子模塊進行管理,持久化。
包安裝子模塊:安裝,卸載,升級一個包;包安裝服務一個單獨進程的用于創(chuàng)建刪除安裝目錄,具有較高的權(quán)限。
包管理子模塊:管理安裝包相關(guān)的信息,存儲持久化包信息。
包安全管理子模塊:簽名檢查、權(quán)限授予、權(quán)限管理。
HDF驅(qū)動LED(可選)
之前在內(nèi)核中已經(jīng)注冊過一個led_driver驅(qū)動,并以led_service服務發(fā)布,這一節(jié)稍微重構(gòu)一下代碼,功能上沒有變化,我們快速過一遍,熟悉HDF的可以自行跳過。
1. 業(yè)務代碼
先新建頭文件vendorhuaweihdfledincludeled_ctrl.h。
#ifndef _LED_CTRL_H #define _LED_CTRL_H #include "hdf_device_desc.h" #include "hdf_log.h" #include "device_resource_if.h" #include "osal_io.h" #include "osal_mem.h" #include "gpio_if.h" #include "osal_irq.h" #include "osal_time.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int32_t CtlLED(int mode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _LED_CTRL_H */
再新建源文件 vendorhuaweihdfledled_ctrl.c
#include "led_ctrl.h" #define HDF_LOG_TAG led_driver // 打印日志所包含的標簽,如果不定義則用默認定義的HDF_TAG標簽 int32_t CtlLED(int mode) { int32_t ret; uint16_t valRead; /* LED的GPIO管腳號 */ // uint16_t gpio = 5 * 8 + 1; // 紅外補光燈 uint16_t gpio = 2 * 8 + 3; // 綠色指示燈 // uint16_t gpio = 3 * 8 + 4; // 紅色指示燈 /* 將GPIO管腳配置為輸出 */ ret = GpioSetDir(gpio, GPIO_DIR_OUT); if (ret != 0) { HDF_LOGE("GpioSerDir: failed, ret %d ", ret); return ret; } if (mode == -1) { // 翻轉(zhuǎn)輸出口 (void)GpioRead(gpio, &valRead); ret = GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); } else { ret = GpioWrite(gpio, mode); } if (ret != 0) { HDF_LOGE("GpioWrite: failed, ret %d ", ret); return ret; } return ret; }
先完成對綠色指示燈的控制邏輯。
2. 驅(qū)動實現(xiàn) 在 huawei/hdf 目錄下新建一個文件夾 led, 然后在其中新建一個源文件 led.c。
#include "hdf_device_desc.h" // HDF框架對驅(qū)動開放相關(guān)能力接口的頭文件 #include "hdf_log.h" // HDF 框架提供的日志接口頭文件 #include "led_ctrl.h" // #define HDF_LOG_TAG led_driver // 打印日志所包含的標簽,如果不定義則用默認定義的HDF_TAG標簽 #define LED_WRITE_READ 1 // 讀寫操作碼1 // Dispatch是用來處理用戶態(tài)發(fā)下來的消息 int32_t LedDriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t result = HDF_FAILURE; HDF_LOGE("Led driver dispatch"); if (client == NULL || client->device == NULL) { HDF_LOGE("Led driver device is NULL"); return HDF_ERR_INVALID_OBJECT; } switch (cmdCode) { case LED_WRITE_READ: const char *recv = HdfSbufReadString(data); if (recv != NULL) { HDF_LOGI("recv: %s", recv); result = CtlLED(-1); // result = CtlLED(GPIO_VAL_HIGH); if (!HdfSbufWriteInt32(reply, result)) { HDF_LOGE("replay is fail"); } return HdfDeviceSendEvent(client->device, cmdCode, data); } break; default: break; } return result; } //驅(qū)動對外提供的服務能力,將相關(guān)的服務接口綁定到HDF框架 int32_t HdfLedDriverBind(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { HDF_LOGE("Led driver bind failed!"); return HDF_ERR_INVALID_OBJECT; } static struct IDeviceIoService ledDriver = { .Dispatch = LedDriverDispatch, }; deviceObject->service = (struct IDeviceIoService *)(&ledDriver); HDF_LOGD("Led driver bind success"); return HDF_SUCCESS; } // 驅(qū)動自身業(yè)務初始的接口 int32_t HdfLedDriverInit(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { HDF_LOGE("Led driver Init failed!"); return HDF_ERR_INVALID_OBJECT; } HDF_LOGD("Led driver Init success"); return HDF_SUCCESS; } // 驅(qū)動資源釋放的接口 void HdfLedDriverRelease(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { HDF_LOGE("Led driver release failed!"); return; } HDF_LOGD("Led driver release success"); return; } // 定義驅(qū)動入口的對象,必須為HdfDriverEntry(在hdf_device_desc.h中定義)類型的全局變量 struct HdfDriverEntry g_ledDriverEntry = { .moduleVersion = 1, .moduleName = "led_driver", .Bind = HdfLedDriverBind, .Init = HdfLedDriverInit, .Release = HdfLedDriverRelease, }; // 調(diào)用HDF_INIT將驅(qū)動入口注冊到HDF框架中,在加載驅(qū)動時HDF框架會先調(diào)用Bind函數(shù),再調(diào)用Init函數(shù)加載該驅(qū)動,當Init調(diào)用異常時,HDF框架會調(diào)用Release釋放驅(qū)動資源并退出。 HDF_INIT(g_ledDriverEntry);
3. 驅(qū)動編譯 在 huawei/hdf/led 目錄下新建編譯文件 Makefile。
include $(LITEOSTOPDIR)/../../drivers/hdf/lite/lite.mk MODULE_NAME := hdf_led_driver LOCAL_SRCS += led_ctrl.c led.c LOCAL_INCLUDE := ./include LOCAL_CFLAGS += -fstack-protector-strong -Wextra -Wall -Werror include $(HDF_DRIVER)
4. 編譯結(jié)果鏈接到內(nèi)核鏡像 修改 huawei/hdf/hdf_vendor.mk 文件,添加以下代碼
LITEOS_BASELIB += -lhdf_led_driver #鏈接生成的靜態(tài)庫 LIB_SUBDIRS += $(VENDOR_HDF_DRIVERS_ROOT)/led #驅(qū)動代碼Makefile的目錄
5. 驅(qū)動配置 修改 vendor/hisi/hi35xx/hi3516dv300/config/device_info/device_info.hcs配置文件,添加驅(qū)動的設備描述。
platform :: host {
hostName = "platform_host"; // host名稱,host節(jié)點是用來存放某一類驅(qū)動的容器
priority = 50; // host啟動優(yōu)先級(0-200),值越大優(yōu)先級越低,建議默認配100,優(yōu)先級相同則不保證host的加載順序
device_led :: device { // led設備節(jié)點
device0 :: deviceNode { // led驅(qū)動的DeviceNode節(jié)點
policy = 2; // policy字段是驅(qū)動服務發(fā)布的策略,在驅(qū)動服務管理章節(jié)有詳細介紹
priority = 100; // 驅(qū)動啟動優(yōu)先級(0-200),值越大優(yōu)先級越低,建議默認配100,優(yōu)先級相同則不保證device的加載順序
preload = 0; // 驅(qū)動按需加載字段
permission = 0666; // 驅(qū)動創(chuàng)建設備節(jié)點權(quán)限
moduleName = "led_driver"; // 驅(qū)動名稱,該字段的值必須和驅(qū)動入口結(jié)構(gòu)的moduleName值一致
serviceName = "led_service"; // 驅(qū)動對外發(fā)布服務的名稱,必須唯一
deviceMatchAttr = "led_config"; // 驅(qū)動私有數(shù)據(jù)匹配的關(guān)鍵字,必須和驅(qū)動私有數(shù)據(jù)配置表中的match_attr值相等
}
}
編譯用戶程序框架子系統(tǒng) 1. 添加配置文件 在 build/lite/platform/hi3516dv300_liteos_a/platform.json中的subsystems字段下面添加appexecfwk和aafwk。
{
"subsystem": "aafwk",
"components": [
{
"component": "ability",
"optional": "true",
"dirs": [
"foundation/aafwk"
],
"targets": [
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilitykit_lite",
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilityMain_lite",
"http://foundation/aafwk/frameworks/abilitymgr_lite:aafwk_abilityManager_lite",
"http://foundation/aafwk/services/abilitymgr_lite:aafwk_services_lite"
],
"features": [
{"enable_ohos_appexecfwk_feature_ability": "true"}
],
"deps": {
"components": [
"hilog_a",
"bundle_mgr",
"system_ability_manager",
"distributed_schedule",
"graphic",
"utils",
"ipc"
],
"third_party": [
"cjson",
"bounds_checking_function"
]
}
}
]
},
{
"subsystem": "appexecfwk",
"components": [
{
"component": "bundle_mgr",
"optional": "true",
"dirs": [
"foundation/appexecfwk"
],
"targets": [
"http://foundation/appexecfwk/services/bundlemgr_lite:appexecfwk_services_lite",
"http://foundation/appexecfwk/frameworks/bundle_lite:appexecfwk_kits_lite"
],
"features": [],
"deps": {
"components": [
"iam",
"app_verify",
"hilog_a",
"system_ability_manager",
"global_resource_manager",
"graphic",
"utils"
],
"third_party": [
"cjson",
"zlib"
]
}
}
]
},
2. 添加編譯文件 新建buildliteconfigsubsystemaafwkBUILD.gn文件,
import("http://build/lite/config/subsystem/lite_subsystem.gni")
lite_subsystem("aafwk") {
subsystem_components = [
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilitykit_lite",
"http://foundation/aafwk/frameworks/abilitymgr_lite:aafwk_abilityManager_lite",
"http://foundation/aafwk/services/abilitymgr_lite:aafwk_services_lite",
]
}
新建/build/lite/config/subsystem/appexecfwk/BUILD.gn文件,
import("http://build/lite/config/subsystem/lite_subsystem.gni")
lite_subsystem("appexecfwk") {
subsystem_components = [
"http://foundation/appexecfwk/kits/appkit_lite:appexecfwk_kit_lite",
"http://foundation/appexecfwk/services/bundlemgr_lite:appexecfwk_services_lite",
]
}
3. 運行管理服務 用戶程序框架有兩個系統(tǒng)服務ability管理服務(abilityms)和(bundlems),兩系統(tǒng)服務運行于foundation進程中。
abilityms和bundlems注冊到sa_manager中,sa_manager運行于foundation進程中,sa_manager為abilityms和bundlems創(chuàng)建線程運行環(huán)境。
在foundation/distributedschedule/services/safwk_lite/BUILD.gn中添加對abilityms和bundlems
deps = [
"...",
]
if (ohos_kernel_type == "liteos_a") {
deps += [
"...",
"http://foundation/aafwk/services/abilitymgr_lite:abilityms",
"http://foundation/appexecfwk/services/bundlemgr_lite:bundlems",
"...",
]
}
基于AbilityKit開發(fā)的Ability 1. 主頁面實現(xiàn) 新建源文件applicationssamplecameramyLedAppsrcmain_ability.cpp
#include "main_ability.h"
namespace OHOS {
REGISTER_AA(MainAbility)
void MainAbility::OnStart(const Want &want)
{
printf("MainAbility::OnStart
");
SetMainRoute("MainAbilitySlice");
Ability::OnStart(want);
}
2. 分片頁面 2.1 定義控件常量 新建源文件main_ability_slice.cpp, 屏幕大小為960x480
#include "main_ability_slice.h"
#include "ability_manager.h"
#include "components/ui_label.h"
#include "components/ui_label_button.h"
namespace OHOS
{
REGISTER_AS(MainAbilitySlice)
constexpr static int BUTTON1_POSITION_X = 380;
constexpr static int BUTTON1_POSITION_Y = 200;
constexpr static int BUTTON_WIDTH = 200;
constexpr static int BUTTON_HEIGHT = 80;
constexpr static int ROOT_VIEW_POSITION_X = 0;
constexpr static int ROOT_VIEW_POSITION_Y = 0;
constexpr static int ROOT_VIEW_WIDTH = 960;
constexpr static int ROOT_VIEW_HEIGHT = 480;
constexpr static uint8_t ROOT_VIEW_OPACITY = 255;
constexpr static uint8_t FONT_ID = 10;
constexpr static int BUTTON1_POSITION_X = 380;
constexpr static int BUTTON1_POSITION_Y = 200;
constexpr static int BUTTON_WIDTH = 200;
constexpr static int BUTTON_HEIGHT = 80;
constexpr static int ROOT_VIEW_POSITION_X = 0;
constexpr static int ROOT_VIEW_POSITION_Y = 0;
constexpr static int ROOT_VIEW_WIDTH = 960;
constexpr static int ROOT_VIEW_HEIGHT = 480;
constexpr static uint8_t ROOT_VIEW_OPACITY = 255;
constexpr static uint8_t FONT_ID = 10;
} // namespace OHOS
2.2 創(chuàng)建按鈕和布局 在生命周期函數(shù)OnStart中,全屏放置一個rootView_,居中位置放置一個按鈕button1。
void MainAbilitySlice::OnStart(const Want &want)
{
printf("MainAbilitySlice::OnStart
");
AbilitySlice::OnStart(want);
auto button1 = new UILabelButton();
button1->SetPosition(BUTTON1_POSITION_X, BUTTON1_POSITION_Y);
button1->SetText("翻轉(zhuǎn) LED");
button1->Resize(BUTTON_WIDTH, BUTTON_HEIGHT);
button1->SetFontId(FONT_ID);
button1->SetStyle(STYLE_TEXT_COLOR, Color::Black().full);
button1->SetStyle(STYLE_TEXT_OPA, ROOT_VIEW_OPACITY);
button1->SetStyle(STYLE_BACKGROUND_OPA, ROOT_VIEW_OPACITY);
rootView_ = RootView::GetWindowRootView();
rootView_->SetPosition(ROOT_VIEW_POSITION_X, ROOT_VIEW_POSITION_Y);
rootView_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT);
rootView_->Add(button1);
SetUIContent(rootView_);
}
2.3 實現(xiàn)驅(qū)動消息機制 這里順便提一下,文檔中DevSvcManagerClntGetService接口僅在內(nèi)核態(tài)有效,可以方便的獲取服務并直接調(diào)用。鴻蒙作為微內(nèi)核的OS,想從用戶態(tài)調(diào)用內(nèi)核態(tài)函數(shù),要么用框架的消息機制,要么自己用中斷服務實現(xiàn)。
#define LED_WRITE_READ 1
#define LED_SERVICE "led_service"
static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
{
const char *string = HdfSbufReadString(data);
if (string == NULL)
{
printf("fail to read string in event data
");
return HDF_FAILURE;
}
printf("%s: dev event received: %u %s
", (char *)priv, id, string);
return HDF_SUCCESS;
}
static int SendEvent(struct HdfIoService *serv, const char *eventData)
{
int ret = 0;
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
if (data == NULL)
{
printf("fail to obtain sbuf data
");
return 1;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
if (reply == NULL)
{
printf("fail to obtain sbuf reply
");
ret = HDF_DEV_ERR_NO_MEMORY;
HdfSBufRecycle(data);
return ret;
}
if (!HdfSbufWriteString(data, eventData))
{
printf("fail to write sbuf
");
ret = HDF_FAILURE;
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data, reply);
if (ret != HDF_SUCCESS)
{
printf("fail to send service call
");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
int replyData = 0;
if (!HdfSbufReadInt32(reply, &replyData))
{
printf("fail to get service call reply
");
ret = HDF_ERR_INVALID_OBJECT;
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
printf("Get reply is: %d
", replyData);
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
2.4 加入點擊事件 每次點擊按鈕,向內(nèi)核態(tài)發(fā)送一次消息。
auto onClick = [this](UIView &view, const Event &event) -> bool {
printf("led button pressed
");
struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE, 0);
if (serv == NULL)
{
printf("fail to get service %s
", LED_SERVICE);
return false;
}
static struct HdfDevEventlistener listener = {
.callBack = OnDevEventReceived,
.priv = (void *)"Service0"};
if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS)
{
printf("fail to register event listener
");
return false;
}
const char *send_cmd = "toggle LED";
if (SendEvent(serv, send_cmd))
{
printf("fail to send event
");
return false;
}
if (HdfDeviceUnregisterEventListener(serv, &listener))
{
printf("fail to unregister listener
");
return false;
}
HdfIoServiceRecycle(serv);
return true;
};
2.5 注銷頁面 在生命周期函數(shù)OnStop中,刪除所有節(jié)點,回收系統(tǒng)資源。
void DeleteViewChildren(UIView *view)
{
if (view == nullptr) {
return;
}
while (view != nullptr) {
UIView *tempView = view;
view = view->GetNextSibling();
if (tempView->IsViewGroup()) {
DeleteViewChildren(dynamic_cast(tempView)->GetChildrenHead());
}
if (tempView->GetParent()) {
dynamic_cast(tempView->GetParent())->Remove(tempView);
}
delete tempView;
}
}
void MainAbilitySlice::OnStop()
{
printf("MainAbilitySlice::OnStop
");
AbilitySlice::OnStop();
DeleteViewChildren(rootView_);
}
3. 編譯配置 新增 applicationssamplecameramyLedAppBUILD.gn文件
import("http://build/lite/config/component/lite_component.gni")
import("http://build/lite/config/subsystem/aafwk/config.gni")
HDF_FRAMEWORKS = "http://drivers/hdf/frameworks"
src_path = "http://applications/sample/camera/myLedApp/src"
lite_library("ledability") {
target_type = "shared_library"
ldflags = [
"-shared",
]
sources = [
"${src_path}/main_ability.cpp",
"${src_path}/main_ability_slice.cpp",
]
include_dirs = [
".",
"http://foundation/aafwk/frameworks/ability_lite/example/entry/src/main/cpp",
"http://foundation/aafwk/interfaces/innerkits/abilitymgr_lite",
"http://foundation/aafwk/interfaces/kits/ability_lite",
"http://foundation/aafwk/interfaces/kits/want_lite",
"http://foundation/appexecfwk/interfaces/kits/bundle_lite",
"http://foundation/appexecfwk/utils/bundle_lite",
"http://foundation/communication/interfaces/kits/ipc_lite",
"http://foundation/graphic/lite/interfaces/kits/config",
"http://foundation/graphic/lite/interfaces/kits/ui",
"http://foundation/graphic/lite/interfaces/kits/utils",
"http://kernel/liteos_a/kernel/common",
"http://kernel/liteos_a/kernel/include",
"http://drivers/hdf/lite/include/host",
"$HDF_FRAMEWORKS/ability/sbuf/include",
"$HDF_FRAMEWORKS/core/shared/include",
"$HDF_FRAMEWORKS/core/host/include",
"$HDF_FRAMEWORKS/core/master/include",
"$HDF_FRAMEWORKS/include/core",
"$HDF_FRAMEWORKS/include/utils",
"$HDF_FRAMEWORKS/utils/include",
"$HDF_FRAMEWORKS/include/osal",
"http://kernel/liteos_a/platform/include",
"$HDF_FRAMEWORKS/adapter/syscall/include",
"$HDF_FRAMEWORKS/adapter/vnode/include",
]
deps = [
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilitykit_lite",
"http://drivers/hdf/lite/manager:hdf_core",
"http://drivers/hdf/lite/adapter/osal/posix:hdf_posix_osal",
]
defines = [
"OHOS_APPEXECFWK_BMS_BUNDLEMANAGER",
]
if (enable_ohos_appexecfwk_feature_ability == true) {
deps += [
"http://foundation/graphic/lite/frameworks/ui:ui",
]
defines += [
"ENABLE_WINDOW=1",
"ABILITY_WINDOW_SUPPORT"
]
}
output_dir = "$root_out_dir/dev_tools/led"
}
4. 應用配置文件 新建 applicationssamplecameramyLedAppconfig.json
{
"app": {
"bundleName": "com.bluishfish.ledability",
"vendor": "huawei",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 3,
"target": 3
}
},
"deviceConfig": {
"default": {
"keepAlive": false
}
},
"module": {
"deviceType": [
"smartVision"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "ledability",
"moduleType": "entry"
},
"abilities": [{
"name": "MainAbility",
"icon": "assets/entry/resources/base/media/icon.png",
"label": "Led Ability",
"launchType": "standard",
"type": "page",
"visible": true
}
]
}
}

5. 板級編譯配置 復制 build/lite/product/ipcamera_hi3516dv300.json,改名為my_hi3516dv300在子系統(tǒng)里加入
{
"ohos_version": "OpenHarmony 1.0",
"board": "hi3516dv300",
"kernel": "liteos_a",
"compiler": "clang",
"subsystem": [
{
"name": "aafwk",
"component": [
"......",
{ "name": "ability_led", "dir": "http://applications/sample/camera/myLedApp:ledability", "features": []}
]
"......"
6. 編譯應用
python build.py my_hi3516dv300 -b debug

將系統(tǒng)燒錄到開發(fā)板上。
7. 打包應用 在 assetsentry esourcesasemedia目錄下放置一個icon.png作為啟動圖標。
將applicationssamplecameramyLedAppconfig.json和 Z:openharmonyoutmy_hi3516dv300dev_toolsledlibledability.so打包壓縮成zip包

改名為ledability.hap ,復制到NFS共享目錄
8. 安裝Hap
mkdir nfs mount 192.168.1.57:/nfs /nfs nfs ./nfs/dev_tools/bin/bm set -s disable ./nfs/dev_tools/bin/bm install -p ./nfs/ledability.hap

9. 運行程序
./nfs/dev_tools/bin/aa start -p com.bluishfish.ledability -n MainAbility
完美!
-
AI
+關(guān)注
關(guān)注
90文章
38373瀏覽量
297536 -
鴻蒙系統(tǒng)
+關(guān)注
關(guān)注
183文章
2642瀏覽量
69410
發(fā)布評論請先 登錄
觸摸屏的工作原理
觸摸屏的應用與工作原理
電阻式觸摸屏,什么是電阻式觸摸屏
基于單片機的液晶顯示觸摸屏控制設計
觸摸屏技術(shù)是誰發(fā)明的_觸摸屏技術(shù)的發(fā)展歷程
基于觸摸屏控制的LED彩色臺燈控制系統(tǒng)的設計
組態(tài)王和觸摸屏哪個好_組態(tài)王和觸摸屏區(qū)別
基于觸摸屏的LED驅(qū)動電路設計
PLC觸摸屏的作用_觸摸屏是怎樣控制PLC的
觸摸屏電容屏原理_觸摸屏有哪些應用領(lǐng)域
觸摸屏電容屏的原理,觸摸屏有哪些應用領(lǐng)域
modbus觸摸屏

基于鴻蒙開發(fā)的觸摸屏控制LED
評論