1 /* Copyright 2022 Unionman Technology Co., Ltd.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 */
16 #include "napi/native_api.h"
17 #include "napi/native_node_api.h"
18
19 static const int INIT_DUTY = 500000;
20 static const int MAX_DUTY = 2500000;
21
22 #ifdef __cplusplus
23 #include "um_pwm.h"
24 extern "C" {
25 #endif
26
27 struct PwmOnData {
28 napi_async_work asyncWork = nullptr; // 异步工作项
29 napi_deferred deferred = nullptr; // 用于Promise的resolve、reject处理
30 napi_ref callback = nullptr; // 回调函数
31 int args[2] = {0}; // 2个输入参数
32 int result = 0; // 业务逻辑处理结果(返回值)
33 };
34
35 // 业务逻辑处理函数,由worker线程池调度执行。
executeCB(napi_env env,void * data)36 static void executeCB(napi_env env, void *data)
37 {
38 PwmOnData *pwmData = (PwmOnData *)data;
39
40 int pwmPex = pwmData->args[0];
41 int pwmAngle = pwmData->args[1];
42
43 set_pwm_period(pwmPex, MAX_DUTY);
44 double pwmDuty = 1.0 * INIT_DUTY * pwmAngle / 45L + INIT_DUTY;
45 set_pwm_dutyCycle(pwmPex, static_cast<int>(pwmDuty));
46 set_pwm_enable(pwmPex, 1);
47
48 pwmData->result = is_pwm_enabled(pwmPex);
49 }
50
51 // 业务逻辑处理完成回调函数,在业务逻辑处理函数执行完成或取消后触发,由EventLoop线程中执行。
completeCBForPromise(napi_env env,napi_status status,void * data)52 static void completeCBForPromise(napi_env env, napi_status status, void *data)
53 {
54 PwmOnData *pwmData = (PwmOnData *)data;
55 napi_value result = nullptr;
56 napi_create_int32(env, pwmData->result, &result);
57 napi_resolve_deferred(env, pwmData->deferred, result);
58
59 // 删除napi_ref对象
60 if (pwmData->callback != nullptr) {
61 napi_delete_reference(env, pwmData->callback);
62 }
63
64 // 删除异步工作项
65 napi_delete_async_work(env, pwmData->asyncWork);
66 delete pwmData;
67 }
68
setPwmStatus(napi_env env,napi_callback_info info)69 static napi_value setPwmStatus(napi_env env, napi_callback_info info)
70 {
71 // 获取2个参数,值的类型是js类型(napi_value)
72 size_t argc = 2L;
73 napi_value args[2];
74 napi_value thisArg = nullptr;
75 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr));
76
77 // 创建promise
78 napi_value promise = nullptr;
79 napi_deferred deferred = nullptr;
80 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
81
82 // 异步工作项上下文用户数据,传递到异步工作项的execute、complete之间传递数据
83 auto pwmData = new PwmOnData {
84 .asyncWork = nullptr,
85 .deferred = deferred,
86 };
87
88 // 将被收到的参数传入
89 NAPI_CALL(env, napi_get_value_int32(env, args[0], &pwmData->args[0]));
90 NAPI_CALL(env, napi_get_value_int32(env, args[1], &pwmData->args[1]));
91
92 // 创建async work,创建成功后通过最后一个参数(addonData->asyncWork)返回asyncwork的handle
93 napi_value resourceName = nullptr;
94 napi_create_string_utf8(env, "setPwmStatus", NAPI_AUTO_LENGTH, &resourceName);
95 napi_create_async_work(env, nullptr, resourceName, executeCB, completeCBForPromise, (void *)pwmData,
96 &pwmData->asyncWork);
97
98 // 将刚创建的async work加到队列,由底层去调度执行
99 napi_queue_async_work(env, pwmData->asyncWork);
100
101 // 返回promise
102 return promise;
103 }
104
105 /*
106 * 注册接口
107 */
registerpwmnapiApis(napi_env env,napi_value exports)108 static napi_value registerpwmnapiApis(napi_env env, napi_value exports)
109 {
110 napi_property_descriptor desc[] = {
111 DECLARE_NAPI_FUNCTION("setPwmStatus", setPwmStatus),
112 };
113 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
114 return exports;
115 }
116
117 /*
118 * 模块定义
119 */
120 static napi_module pwmnapiModule = {
121 .nm_version = 1,
122 .nm_flags = 0,
123 .nm_filename = nullptr,
124 .nm_register_func = registerpwmnapiApis,
125 .nm_modname = "pwmtest", // 模块名
126 .nm_priv = ((void *)0),
127 .reserved = {0},
128 };
129
130 #ifdef __cplusplus
131 }
132 #endif
133 /*
134 * 注册模块
135 */
RegisterpwmnapiModule(void)136 extern "C" __attribute__((constructor)) void RegisterpwmnapiModule(void)
137 {
138 napi_module_register(&pwmnapiModule); // 接口注册函数
139 }
140