Use Hongmeng to develop AI applications (8) JS framework to access the kernel layer

Preface

As mentioned last time, the development efficiency of using `C++` to write the `UI` interface is not as high as that of `JS+HTML`, but device development inevitably requires operating the hardware through the kernel state. Here we must first get rid of the problem from `JS The connection between the framework and the device driver. This chapter is based on the technologies of `HDF driver` and `JS+CSS+HTML`. For related content, you can review ` Developing AI applications with Hongmeng (5) HDF driver fill light` and ` Developing AI applications with Hongmeng (6) UI' `These two articles.

JS application development framework principles

In the sixth article, we have experienced JSthe process of using the development interface. Here is a simple analysis aceof the implementation principle.

Let’s look at the framework diagram first. Web applications like small programs are first compiled into js bundlepackages, and JS Data bindingthe object mapping is obtained through them. ObserverA minimalist MVVC model is implemented, which is used to divide the DOMabove objects into 4 types (render, data, styleSheet, function). The data hijacking mechanism is used to mount them on the prototype function of the observer respectively, and convert them into functions C++. implement.

If you look at the source code, you will find that JSthe part is minimalist, the JS engine uses it JerryScript, and each tag corresponds to a C++class Component. Most functions are actually C++implemented, including event registration and triggering, page routing, control updates, timeouts, file operations, command line output, etc... The 100% docking of all APIs reminds me of a cartoon.

C++It is much more convenient after entering the domain. At this time ACE, you are still in user mode, and you can HDFuse the message mechanism to reach the kernel. It is nothing more than a matryoshka operation wrapped in another layer of API.

Built-in module

There are a series @system.xxxof modules that provide device capabilities to access APP, Router, Audio, Sensor, etc. ohos_module_config.hDefines JS框架the corresponding relationship between the alias of the module and the module initialization function. Among them app, dfx, routermodule is required.

// 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
};

Implement ace module

After introducing the background knowledge, you can encapsulate the functions of the custom ace module according to the complexity of the business. In order to simplify the operation, we directly appmount the operation on the built-in module.

1. Define header files

Modify foundation/ace/frameworks/lite/src/core/modules/app_module.h, add ToggleLedfunctions and initialize.

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. Call HDF driver

Join in 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\n");

    struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE, 0);
    if (serv == NULL)
    {
        printf("fail to get service %s\n", 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\n");
        return JSI::CreateUndefined();
    }

    const char *send_cmd = "toggle LED";

    if (SendEvent(serv, send_cmd))
    {
        printf("fail to send event\n");
        return JSI::CreateUndefined();
    }

    if (HdfDeviceUnregisterEventListener(serv, &listener))
    {
        printf("fail to  unregister listener\n");
        return JSI::CreateUndefined();
    }

    HdfIoServiceRecycle(serv);

    return JSI::CreateUndefined();
}

3. Configure HDF header file path

Revisefoundation/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",
]

Revisefoundation/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. Compile and burn

python build.py my_hi3516dv300 -b debug

When it comes to HDFdrivers and ACEframeworks, the image file must be burned completely again.

Develop interface program

1. Configure module interface

Earlier, we appadded functions to the built-in module taggleLed, which DevEco Studiocannot be obtained directly for Python, so we need to add apian interface first.

Modify \Huawei\Sdk\js\2.0.1.93\api\smartVision\@system.app.d.tsfiles

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;
}

2. Page trigger

Here we UI篇use a sliding event in the previous program to trigger the operation of flipping the Led.

Reviseentry/src/main/js/default/pages/index/index.js

swiperChange (e) {
    this.swiperPage = e.index;
    if(e.index == 0){
        this.iconcheckedColor = '#ffffff';
        this.iconUncheckedColor = '#262626';
    }else{
        this.iconcheckedColor = '#262626';
        this.iconUncheckedColor = '#ffffff';
    }
    // 调用翻转Led函数
    app.toggleLed();
}

The toggleLedfunction name must match the string name defined acein the previous module initialization registration .JSI::SetModuleAPI

3. Package into Hap

Package the application as HaprenamedMyUILed.hap

4. Install to device

For the specific nfsmapping directory, refer to the previous chapter.

mkdir nfs
mount 192.168.1.52:/nfs /nfs nfs
cd nfs
./dev_tools/bin/bm set -s disable
./dev_tools/bin/bm install -p MyUILed.hap

5. Run the program

Slide the main interface and see Led灯the switch, which means the program is running successfully.

To briefly summarize the entire process,

  • Main page index, import import app from '@system.app'module;

  • Called in an event app.toggleLed();to initiate an operation;

  • By JS框架packaging MyUILed.hap(essentially a zip package);

  • After it is installed on the device, it is decompressed and restored to JS代码;

  • The framework on the device acepasses JSI::SetModuleAPIand JS代码the keywords are "toggleLed"mapped to the corresponding C++functions AppModule::ToggleLed;

  • AppModule::ToggleLedFound in function LED_SERVICE, send HDFmessage

  • After the driver in the kernel HDFreceives the message, it actually executes it LED翻转操作.

At this point, we can have the best of both worlds. We can not only efficiently build beautiful UIparts in a small program-like manner, but also C++efficiently access the underlying functions of the device, which AIpaves the way for a large number of subsequent intensive calculations.

Download

Relevant documents and information for this issue can be found on the public account "Deep Awakening" and reply: "ohos08" in the background to obtain the download link.

Next article preview

Recently updated DevEco Device Tools 2.0,

Integrates many hpm and hos commands,

In the next article, let’s try out the new version of the burning tool first.

Stay tuned...

Recommended in the past

Guess you like

Origin blog.csdn.net/weixin_47479625/article/details/113733673