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

news/2024/7/17 9:00:49 标签: harmonyos, c++

        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亮

四、工程代码

见附件


http://www.niftyadmin.cn/n/5534595.html

相关文章

复习2-20240624

vscode 使用 Javabean &#xff08;封装性&#xff09; public class Demo01 {/*1.原则 &#xff1a; 字母 数字 $ _ 中文 除了 这五个 其它都不可以2. 细则 &#xff1a; 数字 不能 开头%hbviunh &hfiureh )nhjrn 7487j -ni hbiu tgf hi…

[经验] candy是什么意思英语翻译 #笔记#其他#职场发展

candy是什么意思英语翻译 1、candy的意思 Candy是英语中的一个词汇&#xff0c;意思是糖果、糖果制品。Candy意为果脯的意思也不是很常见。 糖果是一种富含糖分的食品&#xff0c;主要由砂糖、粘合剂和食用色素等组成。糖果的种类可以很多&#xff0c;有硬糖、软糖、巧克力、…

LabVIEW与3D相机开发高精度表面检测系统

使用LabVIEW与3D相机开发一个高精度表面检测系统。该系统能够实时获取三维图像&#xff0c;进行精细的表面分析&#xff0c;广泛应用于工业质量控制、自动化检测和科学研究等领域。通过真实案例&#xff0c;展示开发过程中的关键步骤、挑战及解决方案&#xff0c;确保系统的高性…

ArcGIS查找相同图斑、删除重复图斑

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 这次是上次 今天分享一下&#xff0c;很重要却被大家忽略的两个工具 这两个工具不仅可以找出属性…

初学51单片机之PWM实例呼吸灯以及遇到的问题(已解答)

PWM全名Pulse Width Modulation中文称呼脉冲宽度调制 如图 这是一个周期10ms、频率是100HZ的波形&#xff0c;但是每个周期内&#xff0c;高低电平宽度各不相同&#xff0c;这就是PWM的本质。 占空比是指高电平占整个周期的比列,上图第一个波形的占空比是40%&#xff0c;第二个…

Windows Server 2022 中文版、英文版下载 (updated Jun 2024)

Windows Server 2022 中文版、英文版下载 (updated Jun 2024) Windows Server 2022 x64, Version 21H2 请访问原文链接&#xff1a;https://sysin.org/blog/windows-server-2022/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.o…

【全资料】信息化建设全套资料获取(原件+实际项目参考)

软件开发从需求调研到项目验收需要一系列文档的支持&#xff0c;这些文档在项目的各个阶段发挥着重要的作用。本文将详细介绍这些文档及其作用。 一、需求调研 在软件开发的前期&#xff0c;进行需求调研是非常重要的。需求调研的主要目的是了解用户需求&#xff0c;包括功能需…

中国机器人产业崛起,德国市场面临30%的份额挑战

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 随着科技的不断进步&#xff0c;机器人行业正迎来前所未有的发展机遇。令人震惊的是&#xff0c;根据最新统计数据&#xff0c;中国机器人产业在…