自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Bearpi-Micro深入解析通過(guò)JS應(yīng)用控制LED燈

系統(tǒng) OpenHarmony
請(qǐng)確保已經(jīng)完成編寫(xiě)一個(gè)點(diǎn)亮LED燈程序?qū)嶒?yàn),因?yàn)楸緦?shí)驗(yàn)將依賴編寫(xiě)一個(gè)點(diǎn)亮LED燈程序?qū)嶒?yàn)中開(kāi)發(fā)的驅(qū)動(dòng)。

??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??

??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??

一、前言

最近跑了一遍Bearpi-Micro編寫(xiě)點(diǎn)亮LED燈程序的Demo,深入了解了如何在開(kāi)發(fā)板上運(yùn)行一個(gè)控制LED燈的程序,達(dá)到能關(guān)閉燈、開(kāi)啟燈以及翻轉(zhuǎn)燈的狀態(tài),南向如何編寫(xiě)JS API接口提供驅(qū)動(dòng)服務(wù)給北向應(yīng)用使用。突發(fā)奇想,發(fā)現(xiàn)了官方給出的點(diǎn)燈應(yīng)用中的一個(gè)不足,并進(jìn)行優(yōu)化。
參考文章:??編寫(xiě)通過(guò)JS應(yīng)用控制LED燈??

二、(南向)深入解析通過(guò)JS應(yīng)用控制LED燈

1.前提

請(qǐng)確保已經(jīng)完成編寫(xiě)一個(gè)點(diǎn)亮LED燈程序?qū)嶒?yàn),因?yàn)楸緦?shí)驗(yàn)將依賴編寫(xiě)一個(gè)點(diǎn)亮LED燈程序?qū)嶒?yàn)中開(kāi)發(fā)的驅(qū)動(dòng),以下教程篇幅較長(zhǎng),請(qǐng)耐心仔細(xì)閱讀。

2.JS API接口開(kāi)發(fā)

注:以下代碼為主要代碼的剖析,詳細(xì)完整的代碼可查看參考文章??編寫(xiě)通過(guò)JS應(yīng)用控制LED燈??。

(1)添加控制LED燈的JS API接口

修改foundation\ace\ace_engine_lite\frameworks\src\core\modules\app_module.h,加入toggleLed JS API。

static JSIValue ToggleLed(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);

("##start##“和”##end##"僅用來(lái)標(biāo)識(shí)位置,添加完配置后刪除這兩行)。

void InitAppModule(JSIValue exports)
{
JSI::SetModuleAPI(exports, "getInfo", AppModule::GetInfo);
JSI::SetModuleAPI(exports, "terminate", AppModule::Terminate);
##start##
JSI::SetModuleAPI(exports, "ledcontrol", AppModule::ToggleLed);
##end##
#ifdef FEATURE_SCREEN_ON_VISIBLE
JSI::SetModuleAPI(exports, "screenOnVisible", AppModule::ScreenOnVisible);
#endif
}

解析:在頭文件中封裝好JS API接口函數(shù)。
提供給北向的接口名為:ledcontrol ,南向業(yè)務(wù)代碼函數(shù)為T(mén)oggleLed 。

(2)編寫(xiě)控制LED燈c++ 業(yè)務(wù)代碼

在foundation\ace\ace_engine_lite\frameworks\src\core\modules\app_module.cpp中加入控制LED燈c++ 業(yè)務(wù)代碼
注:以下代碼僅為部分重要代碼。

                 主函數(shù)ToggleLed將會(huì)調(diào)用的GpioWriteRead函數(shù)??
static int GpioWriteRead(struct HdfIoService *serv, int32_t eventData, int32_t *val)    
//傳入驅(qū)動(dòng)服務(wù)(已在前面的宏定義),命令eventData,待返回的數(shù)據(jù)指針val
{
int ret = HDF_FAILURE;
struct HdfSBuf *data = HdfSBufObtainDefaultSize(); //獲取256字節(jié)的容量
struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); //獲取256字節(jié)的容量

if (data == NULL || reply == NULL) {
HILOG_ERROR(HILOG_MODULE_ACE, "fail to obtain sbuf data\n");
return ret;
}

if (!HdfSbufWriteUint8(data, (uint8_t)eventData)) { //將8位無(wú)符號(hào)整數(shù)eventData寫(xiě)入data
HILOG_ERROR(HILOG_MODULE_ACE, "fail to write sbuf\n");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}

ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data,reply); //調(diào)度驅(qū)動(dòng)服務(wù)函數(shù),傳入命令LED_WRITE_READ,傳入到驅(qū)動(dòng)的數(shù)據(jù)指針data,驅(qū)動(dòng)待返回的數(shù)據(jù)指針reply
if (ret != HDF_SUCCESS) {
HILOG_ERROR(HILOG_MODULE_ACE, "fail to send service call\n");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
if (!HdfSbufReadInt32(reply, val)) { //讀取32位整型數(shù)reply的值賦給val;如果reply的值為NULL則獲取驅(qū)動(dòng)服務(wù)的回復(fù)失敗
HILOG_ERROR(HILOG_MODULE_ACE, "fail to get service call reply\n");
ret = HDF_ERR_INVALID_OBJECT;
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
HILOG_ERROR(HILOG_MODULE_ACE, "Get reply is: %d\n", val); //終端打印消息

HdfSBufRecycle(data); //釋放內(nèi)存data
HdfSBufRecycle(reply); //釋放內(nèi)存reply
return ret;
}

解析:已在代碼中注釋。
重要的:Dispatch函數(shù),調(diào)度驅(qū)動(dòng)服務(wù)呼叫,需要傳入4個(gè)參數(shù):*service-驅(qū)動(dòng)服務(wù)對(duì)象的指針,cmdId-函數(shù)的命令字,*data-想要傳入驅(qū)動(dòng)的數(shù)據(jù)指針,*reply-驅(qū)動(dòng)待回復(fù)的數(shù)據(jù)指針。

接口ToggleLed主函數(shù):

JSIValue AppModule::ToggleLed(const JSIValue thisVal,const JSIValue *args,uint8_t argsNum) //南向接口具體內(nèi)容,控制LED燈c++ 業(yè)務(wù)代碼
{
HILOG_ERROR(HILOG_MODULE_ACE, "led button pressed.");
struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE); //綁定HDF驅(qū)動(dòng)中的LED服務(wù)
if (serv == NULL) {
HILOG_ERROR(HILOG_MODULE_ACE, "fail to get service2 %s\n", LED_SERVICE);
return JSI::CreateUndefined();
}
if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {
return JSI::CreateUndefined();
}
JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS); //獲取北向接口中的屬性
JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);
int32_t num = (int32_t)JSI::GetNumberProperty(args[0], "code"); //獲取北向下發(fā)的命令code
int32_t replyData = 0;
if (GpioWriteRead(serv, num,&replyData)) { //使用上文定義的GpioWriteRead函數(shù),傳入驅(qū)動(dòng)服務(wù)名,命令num,待返回的數(shù)據(jù)指針
HILOG_ERROR(HILOG_MODULE_ACE, "fail to send event\n");
JSI::CallFunction(fail, thisVal, nullptr, 0);
JSI::CallFunction(complete, thisVal, nullptr, 0);
JSI::ReleaseValueList(success, fail, complete);
return JSI::CreateUndefined();
}
JSIValue result = JSI::CreateObject();
JSI::SetNumberProperty(result, "led_status", replyData); //將replyData的值賦給result
JSIValue argv[ARGC_ONE] = {result};
JSI::CallFunction(success, thisVal, argv, ARGC_ONE);
JSI::CallFunction(complete, thisVal, nullptr, 0);
JSI::ReleaseValueList(success, fail, complete, result);
HdfIoServiceRecycle(serv); //銷毀led的驅(qū)動(dòng)程序服務(wù)對(duì)象以釋放不再需要的資源。
return JSI::CreateUndefined();
}

解析:獲取北向接口中的屬性success、fail、complete、code。

JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS); //獲取北向接口中的屬性
JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);
int32_t num = (int32_t)JSI::GetNumberProperty(args[0], "code"); //獲取北向下發(fā)的命令code

#沖刺創(chuàng)作新星#【FFH】Bearpi-Micro深入解析通過(guò)JS應(yīng)用控制LED燈-開(kāi)源基礎(chǔ)軟件社區(qū)

幾個(gè)功能相似的賦值函數(shù)。

JSI::SetNumberProperty(result, "led_status", replyData); //將replyData的值賦給result
HdfSbufWriteUint8(data, (uint8_t)eventData) //將8位無(wú)符號(hào)整數(shù)eventData寫(xiě)入data
HdfSbufReadInt32(reply, val)//讀取32位整型數(shù)reply的值賦給val

主要流程:北向應(yīng)用調(diào)用ledcontrol接口,南向ToggleLed獲取ledcontrol接口中的屬性,并將屬性值通過(guò)驅(qū)動(dòng)服務(wù)中的Dispatch函數(shù)傳遞進(jìn)驅(qū)動(dòng)任務(wù)中,驅(qū)動(dòng)給出返回值。

三、樣例效果

點(diǎn)擊應(yīng)用的開(kāi)關(guān)燈,嗯!挺流暢的。但是,如果我只打開(kāi)北向應(yīng)用,通過(guò)南向命令行終端打開(kāi)LED燈,北向應(yīng)用中燈的狀態(tài)并不會(huì)發(fā)生改變。

南北向沒(méi)有達(dá)到完美的聯(lián)動(dòng)效果。。。

#沖刺創(chuàng)作新星#【FFH】Bearpi-Micro深入解析通過(guò)JS應(yīng)用控制LED燈-開(kāi)源基礎(chǔ)軟件社區(qū)

四、優(yōu)化官方的應(yīng)用樣例

分析:
從上文的剖析中可以看出南北向的接口似乎沒(méi)有優(yōu)化的地方,北向調(diào)用接口,南向就返回?zé)舻臓顟B(tài)值給北向。但是我們通過(guò)南向命令行終端執(zhí)行應(yīng)用程序的時(shí)候雖然也使用到了LED的驅(qū)動(dòng)服務(wù),但是并沒(méi)有將燈的狀態(tài)值反饋給北向(因?yàn)楸毕驔](méi)有調(diào)用接口,自然就不會(huì)有返回值)。
思路:
既然知道了問(wèn)題可能出在北向的應(yīng)用方面,那么就著手嘗試修改/增加一下,讓北向應(yīng)用中燈的圖片一直調(diào)用接口就能一直得到返回的狀態(tài)值。既然需要用到接口就得傳參數(shù)。經(jīng)過(guò)實(shí)驗(yàn)發(fā)現(xiàn),不管傳入命令code=0(關(guān)燈)、1(開(kāi)燈)、2(轉(zhuǎn)換燈狀態(tài)),效果都極不理想。于是乎深入底層了解LED的驅(qū)動(dòng)服務(wù)。

以下為主要代碼段

// Dispatch是用來(lái)處理用戶態(tài)發(fā)下來(lái)的消息
int32_t LedDriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{//在這里cmdCode一直都是1,data表示傳入的開(kāi)關(guān)燈命令,reply表示將要返回?zé)舻臓顟B(tài)值
uint8_t contrl;
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)
{
/* 接收到用戶態(tài)發(fā)來(lái)的LED_WRITE_READ命令 */
case LED_WRITE_READ:
/* 讀取data里的數(shù)據(jù),賦值給contrl */
HdfSbufReadUint8(data,&contrl);
switch (contrl) //在這里判斷傳遞進(jìn)來(lái)的命令
{
/* 開(kāi)燈 */
case LED_ON: //*data=1,開(kāi)燈
GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_LOW);
status = 1;
break;
/* 關(guān)燈 */
case LED_OFF: //*data=0,關(guān)燈
GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_HIGH);
status = 0;
break;
/* 狀態(tài)翻轉(zhuǎn) */
case LED_TOGGLE: //*data=2,轉(zhuǎn)換燈
if(status == 0)
{
GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_LOW);
status = 1;
}
else
{
GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_HIGH);
status = 0;
}
break;
default: //*data=其他值時(shí)不做操作
break;
}
/* 把LED的狀態(tài)值寫(xiě)入reply, 可被帶至用戶程序 */
if (!HdfSbufWriteInt32(reply, status))
{
HDF_LOGE("replay is fail");
return HDF_FAILURE;
}
break;
default:
break;
}
return HDF_SUCCESS;
}

解決方案

既然如此如果我們?cè)诒毕騻魅肫渌钪?,比?,它同樣會(huì)調(diào)用LED的驅(qū)動(dòng)服務(wù),同樣會(huì)返回?zé)舻臓顟B(tài)值,只是沒(méi)有進(jìn)行其他操作。所以在北向可以多寫(xiě)一個(gè)函數(shù)為getstatus()??,發(fā)送命令3,單純只為獲得燈的狀態(tài)值。

getstatus(){
//if(this.statu=='0')this.statu='1'
//else this.statu='0'

try{
let that=this
app.ledcontrol({
code:3,
success(res){
that.statu = res.led_status
},
fail(res,code){

},
complete(){

}
})
}catch{
this.openstatus="調(diào)用錯(cuò)誤"
}
},

效果展示

南向點(diǎn)燈的同時(shí),北向的應(yīng)用也會(huì)實(shí)時(shí)更新燈的狀態(tài)。完美!

#沖刺創(chuàng)作新星#【FFH】Bearpi-Micro深入解析通過(guò)JS應(yīng)用控制LED燈-開(kāi)源基礎(chǔ)軟件社區(qū)

??想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):??

??51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)??

??https://ost.51cto.com??。

責(zé)任編輯:jianghua 來(lái)源: 51CTO開(kāi)源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2023-09-06 15:35:14

2022-11-14 16:56:43

項(xiàng)目開(kāi)發(fā)WiFi程序

2022-01-07 09:56:16

鴻蒙HarmonyOS應(yīng)用

2022-08-05 19:37:59

鴻蒙Api框架

2022-10-20 16:40:16

JS應(yīng)用控制LED鴻蒙

2022-08-10 15:58:54

LED燈鴻蒙

2024-04-02 15:43:47

電顯示技術(shù)發(fā)展

2017-06-14 13:28:25

2018-12-25 13:45:54

Fedora IoT樹(shù)莓派Linux

2011-02-15 11:46:41

2014-07-31 13:15:45

WiFi LED

2022-03-01 15:54:38

智能開(kāi)發(fā)鴻蒙創(chuàng)造性TV

2021-02-06 10:40:45

鴻蒙HarmonyOS應(yīng)用開(kāi)發(fā)

2023-08-07 08:13:41

2022-02-14 14:28:57

驅(qū)動(dòng)開(kāi)發(fā)鴻蒙系統(tǒng)

2024-12-13 08:37:32

2021-09-28 20:22:44

AI

2016-05-18 17:15:17

互動(dòng)出版網(wǎng)

2022-02-16 15:55:21

驅(qū)動(dòng)調(diào)用操作系統(tǒng)鴻蒙

2023-05-18 08:54:22

OkHttp源碼解析
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)