• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 编写通过JS应用控制LED灯
2在本示例将演示如何在系统中添加自定义JS API,达到能通过JS应用关闭灯、开启灯以及翻转灯的状态。希望通过本教程的学习,开发者能掌握如何在OpenHarmony中自定义JS API。
3
4**注:** 在学习本教程之前,请确保已经完成[编写一个点亮LED灯程序](./编写一个点亮LED灯程序.md)实验,因为本实验将依赖[编写一个点亮LED灯程序](./编写一个点亮LED灯程序.md)实验中开发的驱动,以下教程篇幅较长,请耐心仔细阅读。
5
6## 一、JS API接口开发
7
81. 添加控制LED灯的JS API接口
9
10    修改`foundation\ace\ace_engine_lite\frameworks\src\core\modules\app_module.h`,加入toggleLed JS API,("##start##"和"##end##"仅用来标识位置,添加完配置后删除这两行)
11
12    ```
13    public:
14    ACE_DISALLOW_COPY_AND_MOVE(AppModule);
15    AppModule() = default;
16    ~AppModule() = default;
17    static JSIValue GetInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
18    static JSIValue Terminate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
19    ##start##
20    static JSIValue ToggleLed(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
21    ##end##
22    #ifdef FEATURE_SCREEN_ON_VISIBLE
23        static JSIValue ScreenOnVisible(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
24    #endif
25    ```
26
27    ```
28    void InitAppModule(JSIValue exports)
29    {
30        JSI::SetModuleAPI(exports, "getInfo", AppModule::GetInfo);
31        JSI::SetModuleAPI(exports, "terminate", AppModule::Terminate);
32    ##start##
33        JSI::SetModuleAPI(exports, "ledcontrol", AppModule::ToggleLed);
34    ##end##
35    #ifdef FEATURE_SCREEN_ON_VISIBLE
36        JSI::SetModuleAPI(exports, "screenOnVisible", AppModule::ScreenOnVisible);
37    #endif
38    }
39    ```
40
412. 编写控制LED灯c++ 业务代码
42
43    在`foundation\ace\ace_engine_lite\frameworks\src\core\modules\app_module.cpp`中加入控制LED灯c++ 业务代码("##start##"和"##end##"仅用来标识位置,添加完配置后删除这两行)。
44
45    ```
46    #include "app_module.h"
47    #include "ace_log.h"
48    #include "js_app_context.h"
49    #ifdef FEATURE_SCREEN_ON_VISIBLE
50    #include "js_async_work.h"
51    #include "product_adapter.h"
52    #endif
53
54    ##start##
55    #include "hdf_sbuf.h"
56    #include "hdf_io_service_if.h"
57
58    #define LED_WRITE_READ 1
59    #define LED_SERVICE "hdf_led"
60    ##end##
61
62    namespace OHOS {
63    namespace ACELite {
64    const char * const AppModule::FILE_MANIFEST = "manifest.json";
65    const char * const AppModule::KEY_APP_NAME = "appName";
66    const char * const AppModule::KEY_VERSION_NAME = "versionName";
67    const char * const AppModule::KEY_VERSION_CODE = "versionCode";
68
69    ```
70
71    ```
72    struct AsyncParams : public MemoryHeap {
73        ACE_DISALLOW_COPY_AND_MOVE(AsyncParams);
74        AsyncParams() : result(nullptr), callback(nullptr), context(nullptr) {}
75
76        JSIValue result;
77        JSIValue callback;
78        JSIValue context;
79    };
80    #endif
81
82    ##start##
83
84    static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
85    {
86        uint32_t value;
87        HdfSbufReadUint32(data, &value);
88        HILOG_ERROR(HILOG_MODULE_ACE,"%s: dev event received: %u %u\n", (char *)priv, id, value);
89
90        return HDF_SUCCESS;
91    }
92
93    static int GpioWriteRead(struct HdfIoService *serv, int32_t eventData, int32_t *val)
94    {
95        int ret = HDF_FAILURE;
96        struct HdfSBuf *data = HdfSbufObtainDefaultSize();
97        struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
98
99        if (data == NULL || reply == NULL) {
100            HILOG_ERROR(HILOG_MODULE_ACE,"fail to obtain sbuf data\n");
101            return ret;
102        }
103
104        if (!HdfSbufWriteUint8(data, (uint8_t)eventData))
105        {
106            HILOG_ERROR(HILOG_MODULE_ACE,"fail to write sbuf\n");
107            HdfSbufRecycle(data);
108            HdfSbufRecycle(reply);
109            return ret;
110        }
111
112        ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data, reply);
113        if (ret != HDF_SUCCESS)
114        {
115            HILOG_ERROR(HILOG_MODULE_ACE,"fail to send service call\n");
116            HdfSbufRecycle(data);
117            HdfSbufRecycle(reply);
118            return ret;
119        }
120        if (!HdfSbufReadInt32(reply, val))
121        {
122            HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service call reply\n");
123            ret = HDF_ERR_INVALID_OBJECT;
124            HdfSbufRecycle(data);
125            HdfSbufRecycle(reply);
126            return ret;
127        }
128        HILOG_ERROR(HILOG_MODULE_ACE,"Get reply is: %d\n", val);
129
130        HdfSbufRecycle(data);
131        HdfSbufRecycle(reply);
132        return ret;
133    }
134
135    JSIValue AppModule::ToggleLed(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
136    {
137        HILOG_ERROR(HILOG_MODULE_ACE, "led button pressed.");
138
139        struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE);
140        if (serv == NULL)
141        {
142            HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service2 %s\n", LED_SERVICE);
143            return JSI::CreateUndefined();
144        }
145
146        if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {
147            return JSI::CreateUndefined();
148        }
149
150        JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS);
151        JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
152        JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);
153
154        int32_t num = (int32_t)JSI::GetNumberProperty(args[0], "code");
155
156        int32_t replyData = 0;
157
158        if (GpioWriteRead(serv, num, &replyData))
159        {
160            HILOG_ERROR(HILOG_MODULE_ACE,"fail to send event\n");
161            JSI::CallFunction(fail, thisVal, nullptr, 0);
162            JSI::CallFunction(complete, thisVal, nullptr, 0);
163            JSI::ReleaseValueList(success, fail, complete);
164            return JSI::CreateUndefined();
165        }
166
167        JSIValue result = JSI::CreateObject();
168        JSI::SetNumberProperty(result, "led_status", replyData);
169
170        JSIValue argv[ARGC_ONE] = {result};
171        JSI::CallFunction(success, thisVal, argv, ARGC_ONE);
172        JSI::CallFunction(complete, thisVal, nullptr, 0);
173        JSI::ReleaseValueList(success, fail, complete, result);
174
175        HdfIoServiceRecycle(serv);
176
177        return JSI::CreateUndefined();
178    }
179
180    ##end##
181
182    JSIValue AppModule::GetInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
183    {
184        JSIValue result = JSI::CreateUndefined();
185
186        cJSON *manifest = ReadManifest();
187        if (manifest == nullptr) {
188            HILOG_ERROR(HILOG_MODULE_ACE, "Fail to get the content of manifest.");
189            return result;
190        }
191
192        cJSON *appName = cJSON_GetObjectItem(manifest, KEY_APP_NAME);
193        cJSON *versionName = cJSON_GetObjectItem(manifest, KEY_VERSION_NAME);
194        cJSON *versionCode = cJSON_GetObjectItem(manifest, KEY_VERSION_CODE);
195
196        result = JSI::CreateObject();
197        if (appName != nullptr && appName->type == cJSON_String) {
198            JSI::SetStringProperty(result, KEY_APP_NAME, appName->valuestring);
199        }
200        if (versionName != nullptr && versionName->type == cJSON_String) {
201            JSI::SetStringProperty(result, KEY_VERSION_NAME, versionName->valuestring);
202        }
203        if (versionCode != nullptr && versionCode->type == cJSON_Number) {
204            JSI::SetNumberProperty(result, KEY_VERSION_CODE, versionCode->valuedouble);
205        }
206        cJSON_Delete(manifest);
207        manifest = nullptr;
208        return result;
209    }
210    ```
2113. 配置HDF头文件路径
212
213    在`foundation\ace\ace_engine_lite\ace_lite.gni`中添加HDF头文件路径。
214
215    ```
216    ace_lite_include_dirs += [
217        "//drivers/hdf_core/framework/ability/sbuf/include",
218        "//drivers/hdf_core/framework/include/core",
219        "//drivers/hdf_core/framework/include/utils",
220        "//drivers/hdf_core/adapter/uhdf/posix/include",
221    ]
222    ```
2234. 添加编译依赖
224
225    修改`foundation\ace\ace_engine_lite\frameworks\BUILD.gn`,在`public_deps`中添加以下代码
226    ```
227    "//drivers/hdf_core/adapter/uhdf/manager:hdf_core",
228    ```
229
230    修改`foundation\ace\ace_engine_lite\test\ace_test_config.gni`,在`extra_deps`中添加以下代码
231    ```
232    "//drivers/hdf_core/adapter/uhdf/manager:hdf_core",
233    ```
234
235## 二、运行结果
236
237示例代码[编译、烧录](BearPi-HM_Micro开发板编译调试.md)后,参考[如何在开发板上安装HAP应用](如何在开发板上安装HAP应用.md)教程安装device/board/bearpi/bearpi_hm_micro/tools/hap_tools/hap_example目录下的LED.hap应用进行测试
238
239
240
241
242