#物联网征文# 基于OpenHarmony Native Api框架实现控制LED灯亮灭 原创 精华
基于OpenHarmony Native Api框架实现控制LED灯亮灭
一、样例介绍
基于OpenHarmony NAPI框架实现北向应用端控制南向设备端扩展板指定GPIO口对应LED灯的亮灭
二、开发环境
- 搭载OpenHarmony-3.1-release版本的Unionpi Tiger开发板
- DevEco Studio 3.0.0.991
- 40PIN测试小板
- Ubuntu20.04虚拟机
- USB_Burning_Tool烧录工具
环境搭建就不详细介绍了,社区也可以搜得到,这里给出笔者参考的几篇资料
[1]OpenHarmony在Amlogic A311D芯片平台的快速开发上手指南-开源基础软件社区-51CTO.COM
[2]docs/UnionpiTiger_helloworld · OpenHarmony-SIG/knowledge_demo_temp - 码云 - 开源中国 (gitee.com)
[3]unionpi_tiger/README_zh.md · OpenHarmony/device_board_unionman - Gitee.com
三、OpenHarmony系统技术架构
OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或组件。子系统是一个逻辑概念,它具体由对应的组件构成。
四、NAPI框架简介
NAPI(Native API)是 OpenHarmony 标准系统的一种JS API实现机制,适合封装IO、CPU密集型、OS底层等能力并对外暴露JS接口,实现JS与C/C++代码互相访问。
五、实现步骤
1、创建NAPI扩展库
新增子系统gpioled_subsys
在OpenHarmony源码目录下任意位置创建一个目录gpioled_subsys
作为子系统的目录(子系统可创建在OpenHarmony源码目录任意位置)。子系统目录下创建ohos.build
文件,构建时会先读取此文件。把新增的子系统配置到build/subsystem_config.json
。
新增gpioled_part组件
在子系统目录下创建一个子组件目录gpioled_part
。
修改子系统根目录下的ohos.build文件,添加组件配置
新增扩展动态库
在组件目录下创建一个子目录gpioled_demo
,作为 NAPI扩展库的代码目录。
在gpioled_demo
目录下创建代码文件gpioled.cpp
。
在gpioled_demo
目录下创建BUILD.gn
文件,编写构建配置。
将组件添加到产品定义中
产品定义文件存放在productdefine/common/products 目录,文件名就是产品名称。 如:a311d开发板的产品定义文件为productdefine/common/products/a311d.json
按格式:“subsystemA:partA“:{}在产品定义中添加组件。
2、NAPI接口开发
模块注册
1)添加NAPI框架头文件,引入框架提供的方法。
2)定义模块。
3)注册模块,加载动态库时自动调用注册。
使用DECLARE_NAPI_FUNCTION(“js函数名”, c++实现函数名)定义接口函数、DECLARE_NAPI_PROPERTY、 DECLARE_NAPI_STATIC_PROPERTY等定义属性,再通过napi_define_properties赋给exports对象,最后返回exports对象。
实现原理
NAPI支持Callback、 Promise 二种异步模型
• Callback:任务结果以参数的形式提供给用户注册的回调函数;代码逻辑复杂,可读性差,回调地狱。
• Promise:ES6提供的一种异步编程解决方案,比传统的解决方案——回调函数更加优雅。可使得异步执行可以 按照同步的流表示出来,避免了层层嵌套的回调函数,代码更易读。
NAPI框架中,异步接口实现基于napi_create_async_work() 函数创建的异步工作项
napi_status napi_create_async_work(napi_env env,
napi_value async_resource,
napi_value async_resource_name,
napi_async_execute_callback execute,
napi_async_complete_callback complete,
void* data, napi_async_work* result);
参数说明:
[in] env: 传入接口调用者的环境,包含js引擎等,由框架提供。
[in] async_resource: 可选项,关联async_hooks。
[in] async_resource_name: 异步资源标识符,主要用于async_hooks API暴露断言诊断信息。
[in] execute: 异步工作项的处理函数,当工作项被调度到后在worker线程中执行,用于处理业务逻辑,并得到结果。
[in] complete: execute参数指定的函数执行完成或取消后,触发执行该函数,将结果返回给JS。此函数在EventLoop中执行。
[in] data: 异步工作项上下文数据(Addon),用于在主线程接口实现方法、execute、complete之间传递数据。
[out] result: napi_async_work*指针,返回创建的异步工作项对象。
返回值:返回napi_ok表示转换成功,其他值失败。
异步工作项工作时序图
定义异步工作项上下文数据
根据实际场景需要定义异步工作项上下文数据结构,用于在主线程方法、execute、complete之间传递数据,一般包含异步工作项对象、napi_deferred对象、回调函数、参数数组、返回结果等。
异步接口–Callback实现
主线程方法接收参数,初始化异步工作项上下文数据,创建异步工作项,并将其加到调度队列。最后方法返回空值。
worker线程执行业务逻辑计算,将结果存入上下文数据
执行Complete函数,从上下文数据中获取结果,将结果转换为JS类型,调用回调函数返回结果给调用方。
异步接口-- Promise实现
NAPI框架提供napi_create_promise()函数用于创建Promise,返回promise、deferred 二个对象, promise用于主线程方法返回, deferred对象用于resolve、reject处理。
napi_status napi_create_promise(napi_env env,
napi_deferred* deferred,
napi_value* promise);
参数说明:
[in] env: 传入接口调用者的环境,包含js引擎等,由框架提供,默认情况下直接传入即可。
[out] deferred: 返回接收刚创建的deferred对象,关联Promise对象,后面用于napi_resolve_deferred() 或 napi_reject_deferred() 更新状态,返回数据。
[out] promise: 关联上面deferred对象的JS Promise对象,用于主线程方法返回。
返回值:返回napi_ok表示转换成功,其他值失败。
主线程方法接收参数,创建Promise,初始化异步工作项上下文数据,创建异步工作项,并将其加到调度队列。最后返回Promise对象。
worker线程执行业务逻辑计算,将结果存入上下文数据。
执行Complete函数,从上下文数据中获取结果,将结果转换为JS类型,调用 napi_resolve_deferred、 napi_reject_deferred更新状态、返回结果给调用方。
修改device/unionman/a311d/system/cfg/init.A311D.cfg 文件,在boot的cmds中添加相关命令
3.NAPI接口应用
编写定义.d.ts文件
编写接口定义@ohos.nameX.d.ts文件,放到OpenHarmony SDK目录ets\${ets_version}\api目录下。使用SDK 8则${ets_version}为3.1.6.6,SDK 7则为3.0.0.0。
注意@ohos.nameX必须和NAPI模块的BUILD.gn文件中ohos_shared_library(“nameX”)指定的动态库名一致。
使用DevEco Studio创建标准应用App,并引入模块:
页面初始化,同步按钮开关状态与选择的GPIO口对应的值保持一致
使用select组件实现选择指定GPIO口的功能
当下拉选择新值时,触发change事件并调用changeGpio函数
使用switch组件,当开关状态切换时触发事件调用switchChange方法
新增两个方法,封装开启、关闭指定的LED灯
点击File->Project Structure
选择自动签名
使用Micro USB数据线连接PC与开发板OTG口并接通电源后点击Run即可
六、构建与烧录
进入源码根目录,执行如下命令进行版本编译
编译完成后,效果如图所示:
编译完成后需要,进行对镜像进行打包,然后进行烧写。
执行以下命令固件打包
固件打包完成,生成路径为编译根目录下的out/a311d/packages/phone/images/OpenHarmony.img。
打开烧录工具,使用Micro USB数据线连接PC与开发板OTG口并接通电源,导入烧录包后开始烧录即可(可关闭校验IMG)
系统烧录后,如系统版本未变,可直接使用hdc_std工具将新构建的out/a311d/packages/phone/system/lib/module/libgpioled.z.so文件复制替换开发板系统中的/system/lib/module/libgpioled.z.so文件,提升验证效率。参考命令如下:
使用hdc工具还有另一个好处就是调试过程中不需要将Micro USB数据线在开发板OTG口和DEBUG口来回切换,不管是烧录,串口调试还是应用安装都是连接OTG口就行
hdc_std工具获取方式:
通过OpenHarmony sdk获取,hdc_std在sdk的toolchains目录下,例如笔者的hdc工具存放路径为:C:\Users\haoyuan.chen\AppData\Local\OpenHarmony\Sdk\toolchains\3.1.6.6
将其添加到环境变量,显示以下结果即可
更多资料请参考:OpenAtom OpenHarmony
七、演示效果
八、参考资料
标准设备应用开发—Native Api-开源基础软件社区-51CTO.COM
九、项目地址
Haoc_小源同学/HarmonyOS技术训练营 - 码云 - 开源中国 (gitee.com)
【本文正在参加物联网有奖征文活动】,活动链接:https://ost.51cto.com/posts/14758;
北向和南向在未来的联系一定会更加的紧密,感谢楼主对NAPI的指导。
写的很好👍
一起学习,一起加油!
多谢!第一次发,有写得不好的地方还请指点