用鸿蒙开发AI应用(八)JS框架访问内核层 原创 精华
前言
上回说到,用C++来写UI界面的开发效率不如JS+HTML来的高,但设备开发又免不了要通过内核态来操作硬件,这里我们就要先打通从JS框架到设备驱动之间的联系。本章基于HDF驱动和JS+CSS+HTML的技术上进行,相关内容可以回顾用鸿蒙开发AI应用(五)HDF 驱动补光灯和用鸿蒙开发AI应用(六)UI篇这两篇。
JS应用开发框架原理
在第六篇里,我们已经体验了一下使用JS开发界面的流程,这里简单分析ace的实现原理。
先看框架图,类小程序的Web应用先编译成js bundle包,通过JS Data binding来获取对象映射。其中Observer实现了一个极简的MVVC模型,用于将DOM上的对象分为4种类型(render、data、styleSheet、function),采用数据劫持机制分别挂载到观察者的原型函数上,并转化到C++函数执行。
查看源码就会发现,JS的部分是极简的,JS 引擎采用了JerryScript,每一个标签对应了一个C++的Component类。绝大部分功能实际都由C++实现,包括事件注册和触发,页面路由,控件的更新,超时,文件操作,命令行输出等等... 所有API的100%对接不禁让我想起了一个动画片。
进入C++领域后就方便很多了,此时的ACE仍处于用户态,用HDF上的消息机制就能触达内核,无非是再包装一层API的套娃操作。
内置模块
这里有一系列@system.xxx的模块提供了访问APP、Router、Audio、Sensor等等的设备能力。ohos_module_config.h定义了JS框架中模块的别名到模块初始化函数的对应关系。其中app,dfx,router模块是必有的。
实现ace模块
背景知识介绍完了,就可以根据业务的复杂度来依葫芦画瓢的自定义ace模块封装功能,这里为了简化操作,我们直接在内置的app模块上挂载操作。
1. 定义头文件
修改foundation/ace/frameworks/lite/src/core/modules/app_module.h,加入ToggleLed函数并初始化。
2. 调用HDF驱动
在foundation/ace/frameworks/lite/src/core/modules/app_module.cpp中加入,
3. 配置HDF头文件路径
修改 foundation/ace/frameworks/lite/src/core/modules/BUILD.gn
修改foundation/ace/frameworks/lite/BUILD.gn
4. 编译烧录
涉及到HDF驱动和ACE框架,就要重新完整烧录镜像文件。
开发界面程序
1. 配置模块接口
前面我们在内置app模块上增加了函数taggleLed,对于DevEco Studio来说是无法直接获取的,所以要先增加api接口。
修改\Huawei\Sdk\js\2.0.1.93\api\smartVision\@system.app.d.ts文件
2. 页面触发
这里我们在之前的UI篇的程序中,借用一个滑动事件来触发这个翻转Led的操作。
修改entry/src/main/js/default/pages/index/index.js
其中toggleLed这个函数名要与之前ace模块初始化注册时,JSI::SetModuleAPI中定义的字符串名称相匹配。
3. 打包成Hap
将应用打包成Hap改名为MyUILed.hap
4. 安装到设备
具体nfs映射目录,参考前篇所述。
5. 运行程序
滑动主界面,看到Led灯切换就说明程序运行成功了。
简单总结一下整个流程,
- 主页面index,引入import app from '@system.app'模块;
- 事件中调用app.toggleLed();来发起操作;
- 通过JS框架打包成MyUILed.hap(本质是一个zip包);
- 安装到设备上后,就被解压还原成JS代码;
- 设备上的ace框架通过JSI::SetModuleAPI,将JS代码通过关键字"toggleLed"映射成对应的C++函数AppModule::ToggleLed;
- AppModule::ToggleLed函数中找到LED_SERVICE,发送HDF消息
- 内核中HDF驱动收到消息后,真正执行了LED翻转操作。
至此,鱼和熊掌是可以兼得了,我们既能高效的以类小程序方式来构建漂亮的UI部分,又能高效的用C++来访问设备底层功能,可以为后续大量的AI密集计算铺平了道路。
资料下载
本期相关文件资料,可在公众号“深度觉醒”,后台回复:“ohos08”,获取下载链接。
下一篇预告
最近更新 DevEco Device Tools 2.0,
整合了很多 hpm 和 hos 命令,
下一篇,我们先来尝鲜一下新版的烧录工具,
敬请期待...
C和JS的结合打通了开发板,楼主代码功力深厚
这篇可以的,非常有用。
我写了led的驱动,用控制台程序可以调用成功,但用js调用就出现错误:
[HDF:E/hdf_syscall_adapter]Open file node failed: /dev/led_service
01-01 00:01:51.528 13 61 E 03900/ACE: failed to get serivce led_service
我理解是打开设备失败了,查看/dev/led_service是存在的。是哪里的问题,有大神给指导一下吗?
👍👍👍
VFS里面没有/dev/led_service,原因可能是你编写的驱动没有被HDF加载,或者你写的几个HDF驱动的入口函数有问题。
这里重新烧录镜像文件会把系统重置吗