当前位置: 首页 > 科技观察

OpenHarmony3.0采用ets开发HAP控制LED灯

时间:2023-03-20 10:11:51 科技观察

更多信息请访问:Harmonyos.51cto.com1.开发环境硬件:Hi3516DV300开发板软件:OpenHarmony3.0系统工具:DevEcoStudio3.02。功能介绍OpenHarmony3.0采用方舟开发框架arkUI,支持基于TS扩展的声明式开发范式eTS。HAP控制底部LED灯的开和关。3.实现原理如果在Android上实现,需要通过java调用jni来访问底层。但是在OpenHarmony上,HAP是使用ets语言开发的,并没有发现HAP中嵌入类JNI的语言,但是系统也提供了访问底层的机制,叫做NAPI,但是这部分是在系统实现的层,不与HAP一起发布。.我们要实现控制LED灯的功能,在NAPI部分用C语言实现,然后编译成xxx.z.so动态库,向上层提供控制接口。绿色的LED灯对应GPIO2_3,计算出来的个数:2*8+3=19,所以直接控制gpio19下的值就可以控制LED灯的亮灭。4.具体实现整个功能的实现分为上层HAP应用开发和下层.z.so库开发两部分。4.1应用开发1.在HUAWEIDevEcoStudio中创建一个[Standard]EmptyAbility。开发语言选择“eTS”,可以看到APIVersion只支持7,说明是OpenHarmony3新支持的,OpenHarmony3才支持。这些功能其实都是测试版,待稳定后会在HarmonyOS中使用。,但尚未发布。项目创建好后,我在pages目录结构下右键新建一个ets页面,命名为led。我们页面的样式、布局、控件都在led.ets文件中,不再像js那样分成css、hml、js文件。Led.ets文件内容从'@ohos.led'@Entry@ComponentstructLed{@Stateprivateimgpath:string='app.media.ledoff'@StateprivateisShow:boolean=falsebuild(){Flex({direction:FlexDirection.Column,alignItems:ItemAlign.Center,justifyContent:FlexAlign.Center}){Text('LED灯控制').fontSize(25).fontWeight(FontWeight.Bold).margin({bottom:30})Image($r('app.media.ledoff')).objectFit(ImageFit.Contain).width(150).height(150).visibility(this.isShow?Visibility.None:Visibility.Visible)Image($r('app.media.ledon')).objectFit(ImageFit.Contain).width(150).height(150).visibility(this.isShow?Visibility.Visible:Visibility.None)Flex({alignItems:ItemAlign.Center,justifyContent:FlexAlign.SpaceEvenly}){Button('关闭',{type:ButtonType.Capsule,stateEffect:true}).backgroundColor(0x317aff).width(150).height(50).backgroundColor("#aaaaaa").onClick((event:ClickEvent)=>{this.isShow=falseled.switchLed(19,0);})Button('打开',{type:ButtonType.Capsule,stateEffect:true}).backgroundColor(0x317aff).width(150).height(50).onClick((event:ClickEvent)=>{this.isShow=trueled.switchLed(19,1);})}.width("100%").margin({top:50})}.width('100%').height('100%').padding(10)}}放两张代表LED灯状态的图片,放在入口\代码的src\main\resources\phone\media目录下导入的ohos.led库是自己添加的NAPI层的动态库,后面会介绍。在config.json文件中,记得将led.ets放在js部分pages数组的第一个位置,因为它是第一个显示的页面。代码中使用了两个Button组件,一个是打开的,一个是关闭的,因为ets中没有类似js中switch的组件。页面中有两个图片组件,分别显示打开图片和关闭图片。通过设置visibility属性来切换状态,本来想通过动态设置图片来源来改变图片内容,但是没有找到有效的方法。应该是支持的,就是不知道怎么用。编译前记得设置签名,否则编译后的程序无法安装。最后,可以编译程序。最终生成的HAP在build\outputs\hap\debug\phone\entry-debug-standard-ark-signed.hap4.2动态库开发动态库需要在OpenHarmony源码中添加编译。本文使用的是OpenHarmony3.0的源码。在foundation/ace/napi/sample目录下,复制一份native_module_demo,重命名为native_module_led,修改里面的文件名。请注意,文件中的调用也被修改为正确的名称,否则编译会报错。主要修改的文件是,foundation/ace/napi/sample/native_module_led/BUILD.gnfoundation/ace/napi/sample/native_module_led/native_module_led.cppfoundation/ace/napi/BUILD.gn目录native_module_ledBUILD.gn文件:import("//build/ohos.gni")ohos_shared_library("led"){include_dirs=["//third_party/node/src","//foundation/ace/napi/interfaces/kits",]sources=["led_javascript_class.cpp","native_module_led.cpp",]deps=["//foundation/ace/napi:ace_napi"]relative_install_dir="module"external_deps=["hiviewdfx_hilog_native:libhilog"]subsystem_name="ace"part_name="napi"}Native_module_lednative_module_led目录下的.cpp文件修改部分摘要:包含头文件和宏定义,#include//standardlibrary标准库函数头文件#include//standardinputoutput标准输入输出函数#include//定义扩展整数类型和宏#include//POSIX系统API访问函数头文件#include//unix标准中的通用头文件defineO_WRONLYandO_RDONLY//#includede#defineGPIO_DIR_IN(char*)"in"#defineGPIO_DIR_OUT(char*)"out"#defineGPIO_VAL_LOW0#defineGPIO_VAL_HIGH1添加函数SwitchLed的具体实现,staticnapi_valueSwitchLed(napi_envenv,napi_callback_infoinfo){HILOG_Sw("heLOG_Sw");size_trequireArgc=2;size_targc=2;napi_valueargs[2]={null};NAPI_CALL(env,napi_get_cb_info(env,info,&argc,args,nullptr,nullptr));NAPI_ASSERT(env,argc>=requireArgc,"Wrongnumberofarguments");napi_valuetypevaluetype0;NAPI_CALL(env,napi_typeof(env,args[0],&valuetype0));napi_valuetypevaluetype1;NAPI_CALL(env,napi_typeof(env,args[1],&valuetype1));NAPI_ASSERT(env,valuetype0==napi_number1&;.&value;==napi_number,"错误的参数类型。Numbersexpected.");uint32_tgpio;NAPI_CALL(env,napi_get_value_uint32(env,args[0],&gpio));uint32_tval;NAPI_CALL(env,napi_get_value_uint32(env,args[1)],&val));chardirection[100]={0};sprintf(方向,"echoout>/sys/class/gpio/gpio%d/direction",gpio);system(direction);charvalue[100]={0};sprintf(value,"echo%d>/sys/class/gpio/gpio%d/value",val,gpio);system(value);napi_valuesum;NAPI_CALL(env,napi_create_double(env,1.0f,&sum));returnsum;}初化部分,EXTERN_C_START/**functionformoduleexports*/staticnapi_valueInit(napi_envenv,napi_valueexports){/**Propertiesdefine*/napi_property_descriptordesc[]={DECLARE_NAPI_FUNCTION(“添加”,添加),DECLARE_NAPI_FUNCTION(“减号”,减号),DECLARE_NAPI_FUNCTION(“switchLed”,SwitchLed),DECLARE_NAPI_FUNCTION(“TestPromise”,TestPromise),DECLARE_NAPI_FUNCTION(“TestPromiseOrAsyncCallback”,TestPromiseOrAsyncCallback),};NAPI_CALL(env,napi_define_properties(env,exports,sizeof(desc)/sizeof(desc[0]),desc));DemoJavascriptClassInit(env,exports);returnexports;}EXTERN_C_END模块定义及注册,/**Moduledefine*/staticnapi_moduleledModule={.nm_version=1,.nm_flags=0,.nm_filename=nullptr,.nm_register_func=Init,.nm_modname="led",.nm_priv=((void*)0),.reserved={0},};/**Moduleregisterfunction*/extern"C"__attribute__((constructor))voidRegisterModule(void){napi_module_register(&ledModule);}napi目录下的BUILD.gn文件,group("napi_packages_test"){testonly=truedeps=["sample/native_module_demo:demo","sample/native_module_netserver:netserver","sample/native_module_storage:storage","test/unittest:unittest","sample/native_module_led:led",]if(is_standard_system){deps+=["sample/native_module_ability:ability"]}}最后在源码根目录执行编译命令,$./构建。sh--product-nameHi3516DV300--build-targetmake_test生成的文件为:out/ohos-arm-release/ace/napi/libled.z.so5。系统设置需要授权应用访问gpio下的导出文件,device/hisilicon/hi3516dv300/build/rootfs/init.Hi3516DV300.cfg"name":"boot","cmds":["write/sys/class/gpio/export19","chmod777/sys/class/gpio/gpio19/direction","chmod777/sys/class/gpio/gpio19/value",6.系统部署6.1复制复制生成的动态库.z.so动态库已经复制到PCE:\libled.z.soPC串口控制台:#mount-oremount,rw/PC命令窗口cmd:E:>hdc_stdfilesendE:\libled.z.so/system/lib/module/PC串口控制台:#chmod666/system/lib/module/libled.z.so6.2安装应用PC命令窗口cmd:E:>hdc_stdinstallE:\Projects\HarmonyProject\MyLed\build\outputs\hap\debug\phone\entry-debug-standard-ark-signed.hap7.应用测试点击打开按钮,LED图标变为绿色,LED灯亮,点击关闭按钮,LED图标变为灰色,同时LED灯熄灭。