• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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