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_END

static 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>;//节点写1

export const bq_GPIO_Off: (ledPath: string) =>  Promise<string>;//节点写0

export 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 = LedName
    this.ledAddress = LedAddress
    this.ledState = LedState
    this.isLedExit = isLedExit
    this.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 = -1
  async 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: ledModel
  tip(str: string) {
    let show: string
    switch (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亮

四、工程代码

见附件

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QGIS在VS2019开发

QGIS二次开发&#xff08;1&#xff09;—加载矢量、栅格图层&#xff08;QGIS 2.14.16 && Qt-4.8.6 && VS2010 &#xff09;_qgis开发教程-CSDN博客 VS2019QT5.15.2QGIS二次开发环境搭建&#xff08;非源码方式&#xff09;_qt qgis-CSDN博客 也许面向对象课…

diffusion model(十八):diffusion model中negative prompt的工作机制

info个人博客主页http://myhz0606.com/article/ncsn 前置阅读&#xff1a; DDPM&#xff1a; http://myhz0606.com/article/ddpm classifier-guided&#xff1a;http://myhz0606.com/article/guided classifier-free guided&#xff1a;http://myhz0606.com/article/classi…

技术干货 | AI驱动工程仿真和设计创新

在当今快速发展的技术领域&#xff0c;人工智能&#xff08;AI&#xff09;、机器学习和深度学习等技术已经成为推动工程仿真和设计创新的关键力量。Altair技术经理张晨在Altair “AI FOR ENGINEERS”线下研讨会上发表了相关精彩演讲&#xff0c;本文摘自演讲内容&#xff0c;与…

倒F天线参数

倒F天线是依据天线形状命名的。 天线的谐振点及输入阻抗余S、H和L的关系如下&#xff1a; 倒F天线一般用于单频点设计&#xff0c;使用1/4波长原理&#xff08;利用镜像原理&#xff0c;实际相当于半波长的偶极子天线&#xff09;。也就是说L的长度是谐振点对应波长的1/4&#…

mybatis动态传参pgsql日期Interval

在navicat16中&#xff0c;标准写法 SELECT * FROM business_status_info WHERE create_time > (NOW() - INTERVAL 5 minutes) 在mybatis中&#xff0c;错误写法 SELECT * FROM business_status_info WHERE create_time > (NOW() - INTERVAL #{monitorTimeInterval,jdbc…

ViT:3 Compact Architecture

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则…

浏览器提升编译速度小技巧(一)- 防病毒排除

1.引言 在Chrome开发过程中&#xff0c;编译速度是影响开发效率的关键因素之一。编译一个大型项目如Chrome&#xff0c;往往需要处理大量的代码文件和依赖库&#xff0c;这个过程既复杂又耗时。因此&#xff0c;任何能够提升编译速度的技巧&#xff0c;都能显著提高开发效率&a…

AI风险管理新利器:SAIF CHECK利用Meta Llama 3保障合规与安全

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

react-native在IOS上集成百度地图详解

export default class BaiDuMapTest extends Component { render() { return ( ); } } const styles StyleSheet.create({ container: { flex: 1, justifyContent: ‘center’, alignItems: ‘center’, backgroundColor: ‘#F5FCFF’, }, welcome: { fontSize:…

电子设备抗震等级与电子设备震动实验

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/139923445 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

RK3588上手踩坑之启动卡死2

同事开发了一块RK3588Q&#xff0c;记录下上手的踩坑过程。 RK3588上手踩坑实录_-CSDN博客https://blog.csdn.net/huntenganwei/article/details/135213035?spm1001.2014.3001.5501 按照之前的搞法&#xff0c;一通操作。 上电 莫名其妙的duang了 各种检查&#xff0c;核对…

2024年国内顶尖的在线文档协作工具大对比

近几年国内主流使用的9款在线文档协作工具对比&#xff1a;PingCode 知识库、WPS Office 云协作、腾讯文档、语雀、Filez 企业网盘、360亿方云、石墨文档、Confluence、Notion。 在线文档协作工具因其能够提供实时编辑、共享和管理文档的能力&#xff0c;成为了很多团队提升工作…

制造业工厂急需一套erp系统帮他降本增效

随着全球制造业竞争的日益激烈&#xff0c;制造业工厂面临着越来越多的挑战&#xff0c;包括成本控制、生产效率、市场响应速度等方面。在这样的背景下&#xff0c;一套高效的ERP&#xff08;企业资源规划&#xff09;系统成为了制造业工厂降本增效的必备工具。本文将探讨ERP系…

一文读懂交换机MAC地址表:五大关键点,图解21步

HCIA 新班开课了华为HCIA课程介绍苏州面授班 | 全国直播班循环开班&#xff0c;免费重学前言 什么是MAC地址表?MAC地址表有什么作用&#xff1f;MAC地址表里面包含了哪些要素&#xff1f;今天带你好好唠唠。 我们以一个案例为例&#xff1a; 如上图&#xff1a;PC1和PC2通…

基于机理状态模型的约束预测控制

1、约束优化问题描述 考虑如下线性离散时间系统的状态空间增量模型&#xff1a; Δ x ( k 1 ) A Δ x ( k ) B u Δ u ( k ) B d Δ d ( k ) y c ( k ) C c Δ x ( k ) y c ( k − 1 ) y b ( k ) C b Δ x ( k ) y b ( k − 1 ) (1) \begin{aligned} \Delta x(k1)&am…

反激开关电源UC3842芯片介绍

1、VCC端有个36V的稳压管&#xff0c;说明供电电压最高为36V&#xff0c;当然也不能过低&#xff0c;过低就有个欠压锁定电路&#xff08;UVLO&#xff09;&#xff1b; 2、输出经过一个稳压器得到高精度的5V电压&#xff0c;其中一路输出给RC充放电&#xff0c;产生一定频率的…

如何进行外贸SEO优化?

你需要了解目标市场的搜索习惯。不同国家的人使用的搜索引擎和关键词可能不同&#xff0c;所以要先做市场调研&#xff0c;找出你要推广的产品在目标市场最常用的关键词。可以使用像Ahrefs、SEMrush等工具来帮助你分析和选择合适的关键词。 网站的结构也很重要。一个清晰、易导…

08较成功的降低干扰获得较好的波形

08较成功的降低干扰获得较好的波形 波形数据当前数据调整后的数据后续 结语其他以下是废话 试验&#xff0c;本身就是一个摸索的过程&#xff0c;在上一阶段的试验中&#xff0c;我们优化了采集装置&#xff0c;更换了导电性较好的电极。 目前数据美观程度较之前提升了不少&…

持续增强国产适配 | 宁盾身份域管与南大通用、飞腾完成产品兼容性认证

随着党政、央国企、金融信创国产化改造日益深入&#xff0c;企业对国产 IT 基础设施生态兼容适配的需求日益迫切。为践行给企业提供“开箱即用”的交付体验承诺&#xff0c;宁盾身份域管持续增强多元异构产品的兼容适配。近日&#xff0c;宁盾身份域管与天津南大通用数据技术股…

QT事件处理系统之二:窗口部件的事件拦截,以及事件的传递顺序

1、案例说明 在父窗口中为selfLineEdit窗口安装事件过滤器,这样我们可以在父窗口中首先拦截来自于selfLineEdit本身产生的事件,并且决定该事件最终是否继续传递到selfLineEdit窗口本身。 2、关键代码 selfLineEdit.cpp #include "selfLineEdit.h" #include &l…