• 用鸿蒙开发AI应用(八)JS框架访问内核层


    目录:
    前言
    JS应用开发框架原理
    内置模块
    实现ace模块
    开发界面程序

    前言
    上回说到,用C++来写UI界面的开发效率不如JS+HTML来的高,但设备开发又免不了要通过内核态来操作硬件,这里我们就要先打通从JS框架到设备驱动之间的联系。本章基于HDF驱动和JS+CSS+HTML的技术上进行,相关内容可以回顾用鸿蒙开发AI应用(五)HDF 驱动补光灯和用鸿蒙开发AI应用(六)UI篇这两篇。
     用鸿蒙开发AI应用(八)JS框架访问内核层

    JS应用开发框架原理
    在第六篇里,我们已经体验了一下使用JS开发界面的流程,这里简单分析ace的实现原理。

    用鸿蒙开发AI应用(八)JS框架访问内核层

    先看框架图,类小程序的Web应用先编译成js bundle包,通过JS Data binding来获取对象映射。其中Observer实现了一个极简的MVVC模型,用于将DOM上的对象分为4种类型(render、data、styleSheet、function),采用数据劫持机制分别挂载到观察者的原型函数上,并转化到C++函数执行。

    查看源码就会发现,JS的部分是极简的,JS 引擎采用了JerryScript,每一个标签对应了一个C++的Component类。绝大部分功能实际都由C++实现,包括事件注册和触发,页面路由,控件的更新,超时,文件操作,命令行输出等等... 所有API的100%对接不禁让我想起了一个动画片。

    用鸿蒙开发AI应用(八)JS框架访问内核层进入C++领域后就方便很多了,此时的ACE仍处于用户态,用HDF上的消息机制就能触达内核,无非是再包装一层API的套娃操作。

    内置模块
    这里有一系列@system.xxx的模块提供了访问APP、Router、Audio、Sensor等等的设备能力。ohos_module_config.h定义了JS框架中模块的别名到模块初始化函数的对应关系。其中app,dfx,router模块是必有的。

    // Config information for built-in JS modules of OHOS platform
    const Module OHOS_MODULES[] = {
    #ifdef ENABLE_MODULE_REQUIRE_TEST
        {"sample", InitSampleModule},
    #endif
        {"app", InitAppModule},
    #ifdef FEATURE_MODULE_AUDIO
        {"audio", InitAudioModule},
    #endif // FEATURE_MODULE_AUDIO
        {"dfx", InitDfxModule},
        {"router", InitRouterModule},
    #ifdef ENABLE_MODULE_CIPHER
        {"cipher", InitCipherModule},
    #endif
    };

    实现ace模块
    背景知识介绍完了,就可以根据业务的复杂度来依葫芦画瓢的自定义ace模块封装功能,这里为了简化操作,我们直接在内置的app模块上挂载操作。

    1. 定义头文件
    修改foundation/ace/frameworks/lite/src/core/modules/app_module.h,加入ToggleLed函数并初始化。

    namespace OHOS {
    namespace ACELite {
    class AppModule final : public MemoryHeap {
    public:
        static JSIValue ToggleLed(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
    
    void InitAppModule(JSIValue exports)
    {
        JSI::SetModuleAPI(exports, "getInfo", AppModule::GetInfo);
        JSI::SetModuleAPI(exports, "terminate", AppModule::Terminate);
        JSI::SetModuleAPI(exports, "toggleLed", AppModule::ToggleLed);
    }
    } // namespace ACELite
    } // namespace OHOS
    #endif // OHOS_ACELITE_APP_MODULE_H

    2. 调用HDF驱动
    在foundation/ace/frameworks/lite/src/core/modules/app_module.cpp中加入,

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>
    #include <unistd.h>
    #include "hdf_sbuf.h"
    #include "hdf_io_service_if.h"
    
    #define LED_WRITE_READ 1
    #define LED_SERVICE "led_service"
    
    JSIValue AppModule::ToggleLed(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
    {
        HILOG_ERROR(HILOG_MODULE_ACE, "led button pressed.");
        printf("led button pressed
    ");
    
        struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE, 0);
        if (serv == NULL)
        {
            printf("fail to get service %s
    ", LED_SERVICE);
            return JSI::CreateUndefined();
        }
    
        static struct HdfDevEventlistener listener = {
            .callBack = OnDevEventReceived,c
            .priv = (void *)"Service0"};
    
        if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS)
        {
            printf("fail to register event listener
    ");
            return JSI::CreateUndefined();
        }
    
        const char *send_cmd = "toggle LED";
    
        if (SendEvent(serv, send_cmd))
        {
            printf("fail to send event
    ");
            return JSI::CreateUndefined();
        }
    
        if (HdfDeviceUnregisterEventListener(serv, &listener))
        {
            printf("fail to  unregister listener
    ");
            return JSI::CreateUndefined();
        }
    
        HdfIoServiceRecycle(serv);
    
        return JSI::CreateUndefined();
    }

    3. 配置HDF头文件路径
    修改 foundation/ace/frameworks/lite/src/core/modules/BUILD.gn

    include_dirs = [
        "presets",
        "maplejs",
        "//test/lite/testservice/include",
        "//vendor/huawei/watchgt/devkit/hal/include",
    	"//foundation/distributedschedule/interfaces/innerkits/samgr_lite/communication/mpc/transport",
        "//foundation/distributedschedule/interfaces/innerkits/samgr_lite/communication/mpc",
        
        "//drivers/hdf/lite/include/host",
        "$HDF_FRAMEWORKS/ability/sbuf/include",        
        "$HDF_FRAMEWORKS/core/shared/include",
        "$HDF_FRAMEWORKS/core/host/include",
        "$HDF_FRAMEWORKS/core/master/include",
        "$HDF_FRAMEWORKS/include/core",
        "$HDF_FRAMEWORKS/include/utils",
        "$HDF_FRAMEWORKS/utils/include",
        "$HDF_FRAMEWORKS/include/osal",
        "$HDF_FRAMEWORKS/adapter/syscall/include",
        "$HDF_FRAMEWORKS/adapter/vnode/include",
    ]

    修改foundation/ace/frameworks/lite/BUILD.gn

    config("ace_lite_config") {
      include_dirs = [
      ...
      ]
      
      include_dirs += [
        "//drivers/hdf/lite/include/host",
        "$HDF_FRAMEWORKS/ability/sbuf/include",        
        "$HDF_FRAMEWORKS/core/shared/include",
        "$HDF_FRAMEWORKS/core/host/include",
        "$HDF_FRAMEWORKS/core/master/include",
        "$HDF_FRAMEWORKS/include/core",
        "$HDF_FRAMEWORKS/include/utils",
        "$HDF_FRAMEWORKS/utils/include",
        "$HDF_FRAMEWORKS/include/osal",
        "$HDF_FRAMEWORKS/adapter/syscall/include",
        "$HDF_FRAMEWORKS/adapter/vnode/include",
      ]
    }
    shared_library("ace_lite") {
          
      public_deps = [
        "//base/security/frameworks/crypto_lite/js/builtin:ace_kit_cipher",
        "//foundation/graphic/lite/frameworks/surface:surface",
        "//foundation/multimedia/frameworks/camera_lite:camera",
        "//foundation/multimedia/frameworks/player_lite:player",
        "//foundation/multimedia/interfaces/kits/player_lite/js/builtin:audio_api",
        "//third_party/bounds_checking_function:libsec_shared",
        "//third_party/cJSON:cjson_shared",
        "//third_party/jerryscript/jerry-core:jerry-core_shared",
        "//third_party/jerryscript/jerry-ext:jerry-ext_shared",
        "//third_party/jerryscript/jerry-libm:jerry-libm_shared",
        "//third_party/jerryscript/jerry-port/default:jerry-port-default_shared",
        "//utils/native/lite/js/builtin:ace_utils_kits",
        "//utils/native/lite/timer_task:ace_kit_timer",
    
        "//drivers/hdf/lite/manager:hdf_core",
        "//drivers/hdf/lite/adapter/osal/posix:hdf_posix_osal",
      ]
    }

    4. 编译烧录

    python build.py my_hi3516dv300 -b debug

    用鸿蒙开发AI应用(八)JS框架访问内核层涉及到HDF驱动和ACE框架,就要重新完整烧录镜像文件。

    用鸿蒙开发AI应用(八)JS框架访问内核层

    开发界面程序
    1. 配置模块接口
    前面我们在内置app模块上增加了函数taggleLed,对于DevEco Studio来说是无法直接获取的,所以要先增加api接口。

    修改HuaweiSdkjs2.0.1.93apismartVision@system.app.d.ts文件

    export default class App {
      /**
       * Obtains the declared information in the config.json file of an application.
       */
      static getInfo(): IAppInfo;
    
      /**
       * Destroys the current ability.
       */
      static terminate(): void;
      
      /**
       * 翻转Led
       */
      static toggleLed(): void;
    }


    查看更多章节>>>

    作者:bluishfish

    想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

  • 相关阅读:
    Orchard part8
    最有效地优化 Microsoft SQL Server 的性能
    MSSQL优化之索引优化
    Orchard使用中的坎坎坷坷
    GridView----CustomRowCellEdit 使用注意事项
    VS 编辑并继续(转载)
    Visual Studio 2010(.NET 4.0)中使用SQLite.NET
    .net环境下ckeditor与ckfinder中文文件链接乱码的问题
    jQuery常用方法集锦
    checkbox、select、radio的设置与获取
  • 原文地址:https://www.cnblogs.com/HarmonyOS/p/14384183.html
Copyright © 2020-2023  润新知