NAPI篇【4】——NAPI应用点亮一个LED

        OpenHarmony的NAPI功能为开发者提供了JS与C/C++不同语言模块之间的相互访问,交互的能力,使得开发者使用C或者C++语言实现应用的关键功能。如操作开发板中某个GPIO节点的状态(OpenHarmony并没有提供直接操作GPIO口状态的API),点亮一个LED灯。

        本篇基于前3篇NAPI的讲解总结,做一个控制开发板上LED灯状态的应用作为完结篇。

一、环境准备

        设备:rk3568开发板

        开发环境:DevEco Studio4.0.0.600

二、NAPI函数编写

        1、基于NAPI的GPIO节点控制函数

        OpenHarmony并没有提供直接操作GPIO口状态的API。若需要控制开发板上LED灯的亮灭, 需要通过NAPI的方式,写一个可以查询GPIO口状态、一个可以对节点写1和一个可以对节点写0的函数。

(1)main目录如下:

(2)bq_function.cpp

#include "napi/native_api.h"
#include "napi/native_api.h"
#include <cstring>
#include <js_native_api.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>using namespace std;
//对指定节点写1
static napi_value Bq_GPIO_On(napi_env env, napi_callback_info info) {size_t argc = 1;napi_value args[1] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);napi_valuetype valuetype0;napi_typeof(env, args[0], &valuetype0);char *ledPath = new char[150]{};size_t buffSize = 100;size_t realSize = 0;napi_get_value_string_utf8(env, args[0], ledPath, buffSize, &realSize);int fd;char *ret = new char[50]{};fd = open(ledPath, O_RDWR | O_TRUNC | O_NOCTTY);if (fd < 0) {strcpy(ret, "fail to open file");} else {strcpy(ret, "1");write(fd, "1", 1);close(fd);}napi_value returnValue = nullptr;napi_create_string_utf8(env, ret, strlen(ret), &returnValue);return returnValue;
}//对指定节点写0
static napi_value Bq_GPIO_Off(napi_env env, napi_callback_info info) {size_t argc = 1;napi_value args[1] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);napi_valuetype valuetype0;napi_typeof(env, args[0], &valuetype0);char *ledPath = new char[150]{};size_t buffSize = 100;size_t realSize = 0;napi_get_value_string_utf8(env, args[0], ledPath, buffSize, &realSize);int fd;char *ret = new char[50]{};fd = open(ledPath, O_RDWR | O_TRUNC | O_NOCTTY);if (fd < 0) {strcpy(ret, "fail to open file");} else {strcpy(ret, "0");write(fd, "0", 1);close(fd);}napi_value returnValue = nullptr;napi_create_string_utf8(env, ret, strlen(ret), &returnValue);return returnValue;
}//查询指定节点状态
static napi_value bq_GPIO_State(napi_env env, napi_callback_info info) {size_t argc = 1;napi_value args[1] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);napi_valuetype valuetype0;napi_typeof(env, args[0], &valuetype0);char *ledPath = new char[150]{};size_t buffSize = 100;size_t realSize = 0;napi_get_value_string_utf8(env, args[0], ledPath, buffSize, &realSize);char *ret = new char[50]{};FILE *fp;char gpioValuePath[200];char gpioValue[2];// 构建GPIO口值文件路径snprintf(gpioValuePath, sizeof(gpioValuePath), "%s", ledPath);if (access(gpioValuePath, F_OK) == -1) {strcpy(ret, "Error: the GPIO is not exist");napi_value returnValue = nullptr;napi_create_string_utf8(env, ret, strlen(ret), &returnValue);return returnValue;}// 打开GPIO口值文件fp = fopen(gpioValuePath, "r");if (fp == NULL) {perror("Error opening GPIO value file");strcpy(ret, "Error opening GPIO value file");} else {// 读取GPIO口值if (fgets(gpioValue, sizeof(gpioValue), fp) == NULL) {perror("Error reading GPIO value");fclose(fp);strcpy(ret, "Error reading GPIO value");} else {strcpy(ret, gpioValue);}}fclose(fp);napi_value returnValue = nullptr;napi_create_string_utf8(env, ret, strlen(ret), &returnValue);return returnValue;
}EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) {napi_property_descriptor desc[] = {{"bq_GPIO_On", nullptr, Bq_GPIO_On, nullptr, nullptr, nullptr, napi_default, nullptr},{"bq_GPIO_Off", nullptr, Bq_GPIO_Off, nullptr, nullptr, nullptr, napi_default, nullptr},{"bq_GPIO_State", nullptr, bq_GPIO_State, nullptr, nullptr, nullptr, napi_default, nullptr}};napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);return exports;
}
EXTERN_C_ENDstatic napi_module demoModule = {.nm_version = 1,.nm_flags = 0,.nm_filename = nullptr,.nm_register_func = Init,.nm_modname = "entry",.nm_priv = ((void *)0),.reserved = {0},
};extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }

         2、NAPI函数与导出与配置

        (1)index.d.ts

export const bq_GPIO_On: (ledPath: string) =>  Promise<string>;//节点写1export const bq_GPIO_Off: (ledPath: string) =>  Promise<string>;//节点写0export const bq_GPIO_State: (ledPath: string) => Promise<string>;//节点状态查询

        (2)CMakeLists.txt

# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(Demo_Led)set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})include_directories(${NATIVERENDER_ROOT_PATH}${NATIVERENDER_ROOT_PATH}/include)add_library(entry SHARED bq_func.cpp)
target_link_libraries(entry PUBLIC libace_napi.z.so)

        (3)build-profile.json5

        (4)oh-package.json5

三、Openharmony UI交互界面编写

        1、UI界面编写,NAPI函数引用

        (1)index.ets

        开发板控制LED灯节点地址为:/sys/class/leds/pilot_lamp/brightness

import NAPI from 'libentry.so';//引出NAPI接口
import promptAction from '@ohos.promptAction';
@Observed
class ledModel {public ledName: string //LED灯名称public ledAddress: string //LED灯的节点地址public ledState: boolean //LED灯状态public isLedExit: boolean //LED灯节点是否存在public ledStateCheck: string //检测返回值constructor(LedName: string, LedAddress: string, LedState: boolean = false, isLedExit: boolean = true, LedStateCheck: string = '') {this.ledName = LedNamethis.ledAddress = LedAddressthis.ledState = LedStatethis.isLedExit = isLedExitthis.ledStateCheck = LedStateCheck}
}
@Entry
@Component
struct Index {@State message: number = 0;@State led: ledModel = new ledModel('LED_Green','/sys/class/leds/pilot_lamp/brightness')//开发板控制LED灯节点地址'/sys/class/leds/pilot_lamp/brightness'private setIntervalID: number = -1async ledCheck() {this.led.ledStateCheck = await NAPI.bq_GPIO_State(this.led.ledAddress)if (this.led.ledStateCheck === '1') {this.led.ledState = true} else if (this.led.ledStateCheck === 'Error: the GPIO is not exist') {this.led.isLedExit = false} else {this.led.ledState = false}}async aboutToAppear() {await this.ledCheck()//状态扫描this.setIntervalID = setInterval(async () => {await this.ledCheck()}, 500)}aboutToDisappear() {clearInterval(this.setIntervalID)}build() {Column() {Text("点亮一个LED灯").size({ width: '100%', height: 35 }).margin({ top: 10, bottom: 10 }).textAlign(TextAlign.Center).fontSize(30).fontWeight(800)Column({ space: 10 }) {ledList({ item: this.led})}.margin({ top: 20, bottom: 10 }).size({ width: '50%', height: 50 }).justifyContent(FlexAlign.Start).alignSelf(ItemAlign.Center)}.justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).size({ width: '100%', height: '100%' })}
}
@Component
struct ledList {@ObjectLink item: ledModeltip(str: string) {let show: stringswitch (str) {case "1":show = '已打开';break;case "0":show = '已关闭';break;default:show = `error: ${str}`}promptAction.showToast({message: show,duration: 800})}build() {Row() {Text(`${this.item.ledName}`).size({ width: '70%', height: 35 }).fontSize(30).fontWeight(700).fontColor(this.item.isLedExit === true ? Color.Black : '#c9c9cd')Blank()Toggle({ type: ToggleType.Switch, isOn: this.item.ledState }).size({ width: 80, height: 35 }).enabled(this.item.isLedExit).onChange(async (isOn) => {if (isOn) {let res: string = await NAPI.bq_GPIO_On(this.item.ledAddress)this.tip(res)} else {let res: string = await NAPI.bq_GPIO_Off(this.item.ledAddress)this.tip(res)}})}.width('100%')}
}

        2、效果展示

        (1)LED灭

        (2)LED亮

四、工程代码

见附件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/859988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flink metric(3)】chunjun是如何实现脏数据管理的

文章目录 一. 基础逻辑二. DirtyManager1. 初始化2. 收集脏数据并check3. 关闭资源 三. DirtyDataCollector1. 初始化2. 收集脏数据并check3. run&#xff1a;消费脏数据4. 释放资源 四. LogDirtyDataCollector 一. 基础逻辑 脏数据管理模块的基本逻辑是&#xff1a; 当数据消…

猫咪也怕油腻?选对猫粮是关键!福派斯鲜肉猫粮守护猫咪健康

亲爱的猫友们&#xff0c;我们都知道&#xff0c;猫咪的饮食健康是每一个铲屎官都非常关心的问题。最近&#xff0c;有些猫友向我反映&#xff0c;他们给猫主子喂食的猫粮油脂比较大&#xff0c;不禁让人担心这对猫咪是否真的好。 1️⃣ 首先&#xff0c;让我们来聊聊油脂在猫粮…

Spring Boot + Vue 全栈开发,都需要哪些前端知识?

Node.js默认安装的npm包和工具的位置&#xff1a;Node.js目录\node_modules 在这个目录下你可以看见 npm目录&#xff0c;npm本身就是被NPM包管理器管理的一个工具&#xff0c;说明 Node.js已经集成了npm工具 #在命令提示符输入 npm -v 可查看当前npm版本 npm -v 二、使用n…

代理IP超时是什么原因?

很多用户在使用代理IP进行网络访问时&#xff0c;可能会遇到代理IP超时的情况&#xff0c;也就是代理IP的延迟过高。代理IP延迟过高会影响用户的网络体验和数据获取效率。因此&#xff0c;了解代理IP延迟过高的原因很重要。以下是导致代理IP延迟过高的一些常见原因&#xff1a;…

FL Studio 21.2.3官方中文版重磅发布,手把手教你图文安装

FL Studio 21.2.3官方中文版重磅发布纯正简体中文支持&#xff0c;更快捷的音频剪辑及素材管理器&#xff0c;多样主题随心换&#xff01; 在数字音乐制作领域&#xff0c;FL Studio一直以其强大的功能和用户友好的界面而备受赞誉。随着技术的不断进步和音乐制作需求的日益增长…

Python高压电容导电体和水文椭圆微分

&#x1f3af;要点 &#x1f3af;二维热传导二阶偏微分方程 | &#x1f3af;调和函数和几何图曲率 | &#x1f3af;解潮汐波动方程 | &#x1f3af;解静止基态旋转球体流体运动函数 | &#x1f3af;水文空间插值 | &#x1f3af;流体流动模拟求解器 | &#x1f3af;随机算法解…

泰迪智能科技与成都文理学院人工智能与大数据学院开展校企合作交流

近日&#xff0c;在推动高等教育与产业深度融合的背景下&#xff0c;成都文理学院人工智能与大数据学院携手广东泰迪智能科技股份有限公司开展“专业建设交流会”。人工智能与大数据学院院长胡念青、院长助理陈坚、骨干教师刘超超、孙沛、赵杰、文运、胡斌、邹杰出席本次交流会…

vue项目中dom拖动排序功能实现

vue项目中拖动元素改变其顺序的功能实现 实现此功能&#xff0c;我利用的是SortableJs,其官网上直接介绍其为功能强大的js拖拽库&#xff0c;只需要简单的代码即可实现dom拖拽 1.下载 npm i sortablejs 2.引入 使用时&#xff0c;我们在那个页面中使用&#xff0c;就在该vue文…

【progressBar-js】优雅的 前端进度条 构建!

progressBar-js JS 前端进度条小工具 您可以通过此工具来构建一个有效的工具条&#xff0c;接下来就是一个示例&#xff01; 使用示例 引入 progressBar-js 库 直接在这里将 css 和 js 文件引入进来就算是成功导入了哦&#xff01;&#xff01;&#xff01; <link href&…

文件怎么加密?电脑文件加密,分享5个实用方法

通常情况下&#xff0c;人们对手机数据的保护比对电脑数据更为重视。许多人使用指纹和密码来防止他人窥视聊天记录和照片。然而&#xff0c;电脑上的数据却常常被忽视。大多数用户仅设置了电脑登录密码&#xff0c;认为这样就足以保护电脑和其中的文件。然而如果你也是这样认为…

hex、bin、elf、s19等文件格式介绍以及格式转换

文章目录 前言一、bin文件二、hex文件数据记录格式扩展线性地址记录(HEX386)格式扩展段地址记录(HEX86)文件结束(EOF)记录三、elf文件四、S19文件五、不同格式之间转换将bin文件转换成hex文件将hex文件转换成bin文件将bin文件转换成s19文件前言 编译器或汇编器将程序的源代码(…

详解三种常用标准化 Batch Norm Layer Norm RMSNorm

参考&#xff1a; BN究竟起了什么作用&#xff1f;一个闭门造车的分析《动手学深度学习》7.5 节 深度学习中&#xff0c;归一化是常用的稳定训练的手段&#xff0c;CV 中常用 Batch Norm&#xff1b; Transformer 类模型中常用 layer norm&#xff0c;而 RMSNorm 是近期很流行…

Pyppeteer原理介绍和入门尝试

pyppeteer仓库地址&#xff1a;https://github.com/miyakogi/pyppeteer puppeteer仓库地址&#xff1a;https://github.com/search?qpuppeteer&typerepositories 因为有些网页是可以检测到是否是使用了selenium。并且selenium所谓的保护机制不允许跨域cookies保存以及登…

测试的基础知识大全【测试概念、分类、模型、流程、测试用例书写、用例设计、Bug、基础功能测试实战】

测试基础笔记 Day01阶段⽬标⼀、测试介绍⼆、测试常⽤分类2.1 阶段划分单元测试集成测试系统测试验收测试 2.2 代码可⻅度划分⿊盒测试&#xff1a;主要针对功能&#xff08;阶段划分->系统测试&#xff09;灰盒测试&#xff1a;针对接⼝测试&#xff08;阶段划分->集成测…

【UEFI实战】HttpBoot

环境配置 首先下载tftpd工具&#xff0c;可以在phjounin / tftpd64 / Downloads — Bitbucket下载到&#xff0c;建议不要安装到C盘&#xff0c;因为可能无法修改其配置。配置tftpd工具的DHCP服务&#xff1a; 注意这里的IP地址需要跟实际网卡IP匹配。 下载Apache&#xff0c…

【TensorRT】TensorRT C# API 项目更新 (2):优化安装方式和代码

1. 项目介绍 NVIDIA TensorRT™ 是一款用于高性能深度学习推理的 SDK&#xff0c;包括深度学习推理优化器和运行时&#xff0c;可为推理应用程序提供低延迟和高吞吐量。基于 NVIDIA TensorRT 的应用程序在推理过程中的执行速度比纯 CPU 平台快 36 倍&#xff0c;使您能够优化在…

扣子/coze智能体开发的经验与避坑指南

近期&#xff0c;我计划几场关于分享智能体应用开发的活动。因此&#xff0c;我顺便总结了我在创建智能体过程中遇到的问题和解决方案&#xff0c;帮助大家避免类似的陷阱&#xff0c;提高智能体的性能和用户体验。以下是我总结的几点关键经验。 1. 人设与回复逻辑的提示词 在…

《C++ Primer》导学系列:第 8 章 - IO库

8.1 IO类 C标准库提供了一套丰富的输入输出&#xff08;IO&#xff09;类&#xff0c;用于处理数据的输入输出操作。这些类位于<iostream>头文件中&#xff0c;包括处理标准输入输出的istream和ostream类&#xff0c;处理文件输入输出的ifstream和ofstream类&#xff0c…

索引的分类和回表查询——Java全栈知识(29)

索引的分类和回表查询 Mysql 的索引按照类型可以分为以下几类&#xff0c;但是我们使用的 InnoDB 只支持主键索引&#xff0c;唯一索引&#xff0c;普通索引&#xff0c;并不支持全文索引。 1、聚集索引和二级索引 InnoDB 可以将索引分为两类分别是聚集索引和二级索引&…

编译原理大题自解(活前缀DFA、LR(0)分析表)

目录 4. (简答题) &#xff08;1&#xff09;给出识别活前缀的DFA &#xff08;2&#xff09;设计此文法的 LR(0)分析表 第一种解法 第二种解放 首先声明这是作者的写法&#xff08;不保证正确&#xff01;&#xff09;仅供参考。本题因为可能存在冲突的原因&#xff0c;所…