玛卡巴卡的卡巴卡玛 发表于 2024-11-15 23:59:15

鸿蒙Harmony南向开发子系统适配

  OpenHarmony子系统适配一样平常包含两部分:



[*]在config.json中增加对应子系统和部件,这样编译系统会将该部件纳入编译目标中。
[*]针对该部件的HAL层接口进行硬件适配,大概可选的软件功能适配。
分布式软总线子系统适配

wifi_lite部件适配

起首,在config.json文件中,增加communication子系统的wifi_lite部件,如下:
{
      "subsystem": "communication",
      "components": [
      {
          "component": "wifi_lite",
          "optional": "true"
      }
      ]
    }, wifi_lite部件在//build/lite/components/communication.json文件中,形貌如下:
    {
      "component": "wifi_lite",
……
      "targets": [
      "//foundation/communication/wifi_lite:wifi"               --- wifi_lite的编译目标
      ],
……
    }, 在//foundation/communication/wifi_lite/BUILD.gn文件中,形貌须要适配的接口头文件路径,如下:
config("include") {
include_dirs = [ "interfaces/wifiservice" ]       --- 因为wifi_lite只提供头文件,不提供wifi的具体实现,所以wifi模块暴露出适配的目录路径提供给硬件厂商来适配,厂商提供wifi协议栈源码实现。
}

group("wifi") {
public_configs = [ ":include" ]
} 由于在本案例中,wifi属于SoC提供的功能,以是适配源码放在SoC的//device/soc/bestechnic/hals/communication/wifi_lite/wifiservice目次下,包含wifi_device.c和wifi_hotspot.c分别适配wifi_device.h和wifi_hotspot.h。如下:
……
WifiErrorCode Scan(void)       --- wifi_device.c中扫描wifi热点的函数,对wifi_device.h中Scan函数的适配实现
{
    WifiErrorCode ret = ERROR_WIFI_BUSY;


    if (IsWifiActive() != WIFI_STA_ACTIVE)
      return ERROR_WIFI_IFACE_INVALID;

    if (g_HalHmosWifiInfo.scan_state == SCAN_REQUEST ||
      g_HalHmosWifiInfo.scan_state == SCAN_TRIGGER)
      return ERROR_WIFI_BUSY;

    HalHmosWifiLock();
    ret = ((HalHmosSendEvent(HMOS_ON_WIFI_SCAN_STATE_CHANGED, NULL) == 0) ? WIFI_SUCCESS : ERROR_WIFI_BUSY);
    HalHmosWifiUnLock();

    return ret;
}
……
int GetSignalLevel(int rssi, int band)       --- wifi_hotspot.c中获取wifi信号热点函数,对wifi_hotspot.h中GetSignalLevel函数的适配实现。
{
    if (band == HOTSPOT_BAND_TYPE_2G) {
      if (rssi >= RSSI_LEVEL_4_2_G)
            return RSSI_LEVEL_4;
      if (rssi >= RSSI_LEVEL_3_2_G)
            return RSSI_LEVEL_3;
      if (rssi >= RSSI_LEVEL_2_2_G)
            return RSSI_LEVEL_2;
      if (rssi >= RSSI_LEVEL_1_2_G)
            return RSSI_LEVEL_1;
    }

    if (band == HOTSPOT_BAND_TYPE_5G) {
      if (rssi >= RSSI_LEVEL_4_5_G)
            return RSSI_LEVEL_4;
      if (rssi >= RSSI_LEVEL_3_5_G)
            return RSSI_LEVEL_3;
      if (rssi >= RSSI_LEVEL_2_5_G)
            return RSSI_LEVEL_2;
      if (rssi >= RSSI_LEVEL_1_5_G)
            return RSSI_LEVEL_1;
    }
    return ERROR_WIFI_INVALID_ARGS;
} LWIP部件适配

LiteOS-M kernel目次下默认配置了lwip,因而具有编译功能,可以在kernel组件中指定lwip编译的目次。如下:
   {
      "subsystem": "kernel",
      "components": [
      {
          "component": "liteos_m",
          "features": [
            "ohos_kernel_liteos_m_lwip_path = \"//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1\""               --- 指定在芯片厂商目录中进行适配
          ]
      }
      ]
    }, 在//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1/BUILD.gn文件中,形貌了lwip的编译,如下:
import("//kernel/liteos_m/liteos.gni")
import("$LITEOSTHIRDPARTY/lwip/lwip.gni")
import("$LITEOSTOPDIR/components/net/lwip-2.1/lwip_porting.gni")

module_switch = defined(LOSCFG_NET_LWIP_SACK)
module_name = "lwip"
kernel_module(module_name) {
sources = LWIP_PORTING_FILES + LWIPNOAPPSFILES -
            [ "$LWIPDIR/api/sockets.c" ] + [ "porting/src/ethernetif.c" ]               --- 增加ethernetif.c文件,用以适配ethernet网卡的初始化适配
defines = [ "LITEOS_LWIP=1" ]
defines += [ "CHECKSUM_BY_HARDWARE=1" ]
}

config("public") {
defines = [ "_BSD_SOURCE=1" ]
include_dirs =
      [ "porting/include" ] + LWIP_PORTING_INCLUDE_DIRS + LWIP_INCLUDE_DIRS
} 在//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1/porting/include/lwip/lwipopts.h文件中,说明原有lwip配置选项保持不变,软总线会依赖这些配置选项,并且新增硬件适配的配置项,如下:
#ifndef _PORTING_LWIPOPTS_H_
#define _PORTING_LWIPOPTS_H_

#include_next "lwip/lwipopts.h"                               --- 保持原来的配置项不变

#define LWIP_NETIF_STATUS_CALLBACK      1
#define LWIP_CHECKSUM_ON_COPY         0
#define CHECKSUM_GEN_UDP                0       --- 新增硬件适配选项

#endif /* _PORTING_LWIPOPTS_H_ */ 在//device/soc/bestechnic/bes2600/liteos_m/components/net/lwip-2.1/porting/src/ethernetif.c文件中,说明对ethernet网卡初始化的适配,如下:
err_t
ethernetif_init(struct netif *netif)
{
……
#ifdef CHECKSUM_BY_HARDWARE
    eth_hw_checksum_init();
#endif
……
    netif->linkoutput = low_level_output;

    netif->drv_send = liteos_low_level_output;
    netif->hwaddr_len = NETIF_MAX_HWADDR_LEN;
    low_level_init(netif);
    driverif_init(netif);
    return ERR_OK;
……
} dsoftbus部件适配

在config.json中增加dsoftbus部件配置如下:
{
"component": "dsoftbus",
"features": [
    "softbus_adapter_config = \"//vendor/bestechnic/mini_distributed_music_player/dsoftbus_lite_config\""
]
}, dsoftbus部件在//foundation/communication/dsoftbus/dsoftbus.gni文件中提供了softbus_adapter_config配置选项可供移植过程进行配置,该配置设定了软总线移植适配的路径。
在本案例中,softbus_adapter_config配置为//vendor/bestechnic/mini_distributed_music_player/dsoftbus_lite_config路径,该路径下的内容为:
.
├── feature_config                                        --- 软总线功能特性配置,例如是否开启自发现功能等
│   └── mini
│       └── config.gni
└── spec_config                                                --- 软总线规格特性配置,例如设置软总线日志级别设置
    ├── softbus_config_adapter.c
    ├── softbus_config_adapter.h
    └── softbus_config_type.h 在config.gni文件中规定了以下配置项:
配置项形貌dsoftbus_feature_disc_ble是否开启BLE发现功能dsoftbus_feature_disc_coap是否开启COAP发现功能dsoftbus_feature_conn_tcp是否开启TCP连接功能dsoftbus_feature_conn_br是否开启BR连接功能dsoftbus_feature_conn_ble是否开启BLE连接功能dsoftbus_feature_conn_p2p是否开启P2P连接功能dsoftbus_feature_trans_udp是否开启UDP传输功能dsoftbus_feature_trans_udp_stream是否开启UDP传输流功能dsoftbus_feature_trans_udp_file是否开启UDP传输文件功能dsoftbus_feature_ip_auth是否开启认证传输通道功能dsoftbus_feature_auth_account是否开启基于账号认证功能dsoftbus_feature_qos是否开启QoS功能 在softbus_config_adapter.c文件中规定了以下配置项:
配置项形貌SOFTBUS_INT_MAX_BYTES_LENGTHSendBytes发送最大Bytes长度SOFTBUS_INT_MAX_MESSAGE_LENGTHSendMessage发送最大消息的长度SOFTBUS_INT_CONN_BR_MAX_DATA_LENGTH蓝牙最大接收数据量SOFTBUS_INT_CONN_RFCOM_SEND_MAX_LEN蓝牙最大接收数据量SOFTBUS_INT_ADAPTER_LOG_LEVEL日志级别设置SOFTBUS_STR_STORAGE_DIRECTORY存储目次设置 由于软总线配置了后,不会默认启动,以是须要在通过启动框架调用InitSoftBusServer函数,如下:
static void DSoftBus(void)
{
    osThreadAttr_t attr;
    attr.name = "dsoftbus task";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 65536;
    attr.priority = 24;

    extern void InitSoftBusServer(void);
    if (osThreadNew((osThreadFunc_t) InitSoftBusServer, NULL, &attr) == NULL) {
      printf("Failed to create WifiSTATask!\n");
    }
}

APP_FEATURE_INIT(DSoftBus); RPC部件适配

在config.json中增加rpc部件配置如下:
{
"component": "rpc"
}, 同样地,rpc部件须要通过启动框架调用StartDBinderService函数,由于该函数正常运行依赖主机已经获取IP地址,因此在LWIP协议栈注册IP地址变化变乱的回调函数中调用该函数,如下:
static void RpcServerWifiDHCPSucCB(struct netif *netif, netif_nsc_reason_t reason,
                                 const netif_ext_callback_args_t *args)
{
    (void) args;
    if (netif == NULL) {
      printf("%s %d, error: input netif is NULL!\n", __FUNCTION__, __LINE__);
      return;
    }
    if (reason == LWIP_NSC_IPSTATUS_CHANGE) {
      if (netif_is_up(netif) && !ip_addr_isany(&netif->ip_addr)) {
            printf("%s %d, start rpc server!\n", __FUNCTION__, __LINE__);
            StartDBinderService();
      }
    }
}

static void WifiDHCPRpcServerCB(void)
{
    NETIF_DECLARE_EXT_CALLBACK(WifiReadyRpcServerCallback);
    netif_add_ext_callback(&WifiReadyRpcServerCallback, RpcServerWifiDHCPSucCB);
}

APP_FEATURE_INIT(WifiDHCPRpcServerCB); 启动恢复子系统适配

启动恢复子系统适配bootstrap_lite/syspara_lite两个部件。请在vendor/bestechnic_bak/display_demo/config.json中新增对应的配置选项。
{
"subsystem": "startup",
"components": [
        {
          "component": "bootstrap_lite"               --- bootstrap_lite 部件
        },
        {
          "component": "syspara_lite",               --- syspara_lite 部件
          "features": [
                "enable_ohos_startup_syspara_lite_use_posix_file_api = true"
          ]
        }
]
}, 适配bootstrap_lite部件时,须要在连接脚本文件//device/soc/bestechnic/bes2600/liteos_m/sdk/bsp/out/best2600w_liteos/_best2001.lds中手动新增如下段:
       __zinitcall_bsp_start = .;
      KEEP (*(.zinitcall.bsp0.init))
      KEEP (*(.zinitcall.bsp1.init))
      KEEP (*(.zinitcall.bsp2.init))
      KEEP (*(.zinitcall.bsp3.init))
      KEEP (*(.zinitcall.bsp4.init))
      __zinitcall_bsp_end = .;
      __zinitcall_device_start = .;
      KEEP (*(.zinitcall.device0.init))
      KEEP (*(.zinitcall.device1.init))
      KEEP (*(.zinitcall.device2.init))
      KEEP (*(.zinitcall.device3.init))
      KEEP (*(.zinitcall.device4.init))
      __zinitcall_device_end = .;
      __zinitcall_core_start = .;
      KEEP (*(.zinitcall.core0.init))
      KEEP (*(.zinitcall.core1.init))
      KEEP (*(.zinitcall.core2.init))
      KEEP (*(.zinitcall.core3.init))
      KEEP (*(.zinitcall.core4.init))
      __zinitcall_core_end = .;
      __zinitcall_sys_service_start = .;
      KEEP (*(.zinitcall.sys.service0.init))
      KEEP (*(.zinitcall.sys.service1.init))
      KEEP (*(.zinitcall.sys.service2.init))
      KEEP (*(.zinitcall.sys.service3.init))
      KEEP (*(.zinitcall.sys.service4.init))
      __zinitcall_sys_service_end = .;
      __zinitcall_sys_feature_start = .;
      KEEP (*(.zinitcall.sys.feature0.init))
      KEEP (*(.zinitcall.sys.feature1.init))
      KEEP (*(.zinitcall.sys.feature2.init))
      KEEP (*(.zinitcall.sys.feature3.init))
      KEEP (*(.zinitcall.sys.feature4.init))
      __zinitcall_sys_feature_end = .;
      __zinitcall_run_start = .;
      KEEP (*(.zinitcall.run0.init))
      KEEP (*(.zinitcall.run1.init))
      KEEP (*(.zinitcall.run2.init))
      KEEP (*(.zinitcall.run3.init))
      KEEP (*(.zinitcall.run4.init))
      __zinitcall_run_end = .;
      __zinitcall_app_service_start = .;
      KEEP (*(.zinitcall.app.service0.init))
      KEEP (*(.zinitcall.app.service1.init))
      KEEP (*(.zinitcall.app.service2.init))
      KEEP (*(.zinitcall.app.service3.init))
      KEEP (*(.zinitcall.app.service4.init))
      __zinitcall_app_service_end = .;
      __zinitcall_app_feature_start = .;
      KEEP (*(.zinitcall.app.feature0.init))
      KEEP (*(.zinitcall.app.feature1.init))
      KEEP (*(.zinitcall.app.feature2.init))
      KEEP (*(.zinitcall.app.feature3.init))
      KEEP (*(.zinitcall.app.feature4.init))
      __zinitcall_app_feature_end = .;
      __zinitcall_test_start = .;
      KEEP (*(.zinitcall.test0.init))
      KEEP (*(.zinitcall.test1.init))
      KEEP (*(.zinitcall.test2.init))
      KEEP (*(.zinitcall.test3.init))
      KEEP (*(.zinitcall.test4.init))
      __zinitcall_test_end = .;
      __zinitcall_exit_start = .;
      KEEP (*(.zinitcall.exit0.init))
      KEEP (*(.zinitcall.exit1.init))
      KEEP (*(.zinitcall.exit2.init))
      KEEP (*(.zinitcall.exit3.init))
      KEEP (*(.zinitcall.exit4.init))
      __zinitcall_exit_end = .; 须要新增上述段是由于bootstrap_init提供的对外接口,见//utils/native/lite/include/ohos_init.h文件,采用的是灌段的形式,最终会生存到上述链接段中。主要的服务自动初始化宏如下表格所示:
接口名形貌SYS_SERVICE_INIT(func)标识核心系统服务的初始化启动入口SYS_FEATURE_INIT(func)标识核心系统功能的初始化启动入口APP_SERVICE_INIT(func)标识应用层服务的初始化启动入口APP_FEATURE_INIT(func)标识应用层功能的初始化启动入口 https://i-blog.csdnimg.cn/blog_migrate/c3a5920f5c4794513f928b9f997a375e.gif
 说明: 通过上面加载的组件编译出来的lib文件须要手动加入强制链接。
​ 如在 vendor/bestechnic/display_demo/config.json 中配置了bootstrap_lite 部件
    {
      "subsystem": "startup",
      "components": [
      {
          "component": "bootstrap_lite"
      },
      ...
      ]
    }, ​ bootstrap_lite部件会编译//base/startup/bootstrap_lite/services/source/bootstrap_service.c,该文件中,通过SYS_SERVICE_INIT将Init函数符号灌段到__zinitcall_sys_service_start和__zinitcall_sys_service_end中,由于Init函数是没有显式调用它,以是须要将它强制链接到最终的镜像。如下:
static void Init(void)
{
    static Bootstrap bootstrap;
    bootstrap.GetName = GetName;
    bootstrap.Initialize = Initialize;
    bootstrap.MessageHandle = MessageHandle;
    bootstrap.GetTaskConfig = GetTaskConfig;
    bootstrap.flag = FALSE;
    SAMGR_GetInstance()->RegisterService((Service *)&bootstrap);
}
SYS_SERVICE_INIT(Init);   --- 通过SYS启动即SYS_INIT启动就需要强制链接生成的lib ​ 在//base/startup/bootstrap_lite/services/source/BUILD.gn文件中,形貌了在out/v200zr/display_demo/libs 生成 libbootstrap.a,如下:
static_library("bootstrap") {
sources = [
    "bootstrap_service.c",
    "system_init.c",
]
.... ​ 那么须要在 vendor/bestechnic/display_demo/config.json 配置强制链接库bootstrap,如下:
"bin_list": [
    {
      "elf_name": "wifiiot",
      "bsp_target_name": "best2600w_liteos",
      "signature": "false",
      "burn_name": "rtos_main",
      "enable": "true",
      "force_link_libs": [
      "bootstrap",       --- 强制链接libbootstrap.a
      ...
      ]
    }, 适配syspara_lite部件时,系统参数会最终写到文件中进行长期化生存。在轻量系统中,文件操作相关接口有POSIX接口与HalFiles接口这两套实现。
由于对接内核的文件系统,采用POSIX相关的接口,以是features字段中须要增加enable_ohos_startup_syspara_lite_use_posix_file_api = true。
如果对接HalFiles相关的接口实现的,则无须修改。
在适配GetSerial接口时,开发板不像产线生产过程那样,会写入一个详细的Serial Number,因而须要确定一个数据对开发板进行唯一标识。本案例采用WiFi Mac地址进行适配。
#define ETH_ALEN 6
#define MAC_BITS 4
#define MAC_HIGH_MASK 0xf0
#define MAC_LOW_MASK 0x0f
#define HEX_A 0xa
#define CHAR_NUM_OFFSET 0x30
#define CHAR_CAPITAL_OFFSET 0x37
#define STR_END_FLAG '\0'

typedef unsigned char               u8;

static char serialNumber;               --- 最后一位留作'\0'结束符标识


static char Hex2Char(u8 hex)
{
    if (hex < HEX_A) {
      return hex + CHAR_NUM_OFFSET;                       --- 将数值0转为char的'0'
    } else {
      return hex + CHAR_CAPITAL_OFFSET;               --- 将数值0xa转为char的'A'
    }
}

const char* HalGetSerial(void)
{
    char macAddr;
    // as devboard has no production serial number, we just
    // use wifi mac address as device serial number.
    if (serialNumber == STR_END_FLAG) {               --- 只有第一次调用时,才去获取mac地址
      extern int bwifi_get_own_mac(u8 *addr);
      bwifi_get_own_mac(macAddr);                               --- 获取mac地址
      int j = 0;
      for (int i = 0; i < ETH_ALEN; i++) {
            u8 lowFour, highFour;
            highFour = (macAddr & MAC_HIGH_MASK) >> MAC_BITS;
            serialNumber = Hex2Char(highFour);
            j++;
            lowFour = macAddr & MAC_LOW_MASK;
            serialNumber = Hex2Char(lowFour);
            j++;
      }               --- 将mac地址值转化为serial number
    }
    return serialNumber;
} DFX子系统适配

进行DFX子系统适配须要添加hilog_lite部件,直接在config.json文件配置即可。
{
"subsystem": "hiviewdfx",
"components": [
        {
          "component": "hilog_lite",
          "optional": "true"
        }
]
}, 配置完成之后,在//device/soc/bestechnic/bes2600/liteos_m/components/utils/src/hm_sys.c中注册日志输出实现函数。
boolean HilogProc_Impl(const HiLogContent *hilogContent, uint32 len)
{
    char tempOutStr = {0};
    if (LogContentFmt(tempOutStr, sizeof(tempOutStr), hilogContent) > 0) {
      printf(tempOutStr);
    }
        return TRUE;   
}

HiviewRegisterHilogProc(HilogProc_Impl); 系统服务管理子系统适配

进行系统服务管理子系统适配须要添加samgr_lite部件,直接在config.json配置即可。
{
"subsystem": "systemabilitymgr",
"components": [
        {
          "component": "samgr_lite",
          "features": [
                "config_ohos_systemabilitymgr_samgr_lite_shared_task_size = 4096"
          ]
        }
]
}, 在轻量系统中,samgr_lite配置的共享任务栈巨细默认为0x800。当函数调用栈较大时,会出现栈溢出的问题。在本次适配过程中,将其调整为0x1000。
安全子系统适配

进行安全子系统适配须要添加huks/deviceauth_lite部件,直接在config.json配置即可。
{
      "subsystem": "security",
      "components": [
      {
          "component": "huks",
          "features": [
            "huks_use_lite_storage = true",
            "huks_use_hardware_root_key = true",
            "huks_config_file = \"hks_config_lite.h\"",
            "huks_key_store_path = \"/data/\"",
            "ohos_security_huks_mbedtls_porting_path = \"//device/soc/bestechnic/hals/mbedtls\""
          ]
      },
      {
          "component": "deviceauth_lite",
          "features": [
            "deviceauth_storage_path = \"/data/\"",
            "deviceauth_hichain_thread_stack_size = 9472"
          ]
      }
      ]
    } huks部件适配时,huks_key_store_path配置选项用于指定存放秘钥路径,ohos_security_huks_mbedtls_porting_path配置选项用于指定进行mbedtls适配的目次,用于芯片对mbedtls进行硬件随机数等适配。
deviceauth_lite部件适配时,deviceauth_storage_path配置选项用于指定存放装备认证信息的路径,deviceauth_hichain_thread_stack_size用于指定线程栈巨细。
媒体子系统适配

进行媒体子系统适配须要添加histreamer部件,直接在config.json配置即可。
{
"subsystem": "multimedia",
"components": [
    {
      "component": "histreamer",
      "features": [
      "histreamer_enable_plugin_hdi_adapter = true",
      "histreamer_enable_plugin_minimp3_adapter = true",
      "histreamer_enable_plugin_ffmpeg_adapter = false",
      "config_ohos_histreamer_stack_size = 65536"
      ]
    }
]
}, histreamer部件配置项说明如下:
配置项说明histreamer_enable_plugin_hdi_adapter是否使能histreamer对接到hdi接口histreamer_enable_plugin_minimp3_adapter是否使能插件适配minimp3histreamer_enable_plugin_ffmpeg_adapter是否使能插件适配FFmpegconfig_ohos_histreamer_stack_sizehistreamer栈巨细设置 公共底子库子系统适配

进行公共底子库子系统适配须要添加kv_store/js_builtin/timer_task/kal_timer部件,直接在config.json配置即可。
{
"subsystem": "utils",
"components": [
        {
          "component": "kv_store",
          "features": [
                "enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true"
          ]
        },
        {
          "component": "js_builtin"
        },
        {
          "component": "timer_task"
        },
        {
          "component": "kal_timer",
        }
]
}, 与适配syspara_lite部件类似,适配kv_store部件时,键值对会写到文件中。在轻量系统中,文件操作相关接口有POSIX接口与HalFiles接口这两套实现。由于对接内核的文件系统,采用POSIX相关的接口,以是features须要增加enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true。如果对接HalFiles相关的接口实现的,则无须修改。
图形子系统适配

进行图形子系统适配须要添加graphic_utils部件,直接在config.json配置即可。
{
      "components": [
      {
          "component": "graphic_utils",
          "features": [
            "enable_ohos_graphic_utils_product_config = true"
          ]
      },
      {
          "component": "ui"
      }
      ]
    }, graphic配置文件见 //vendor/bestechnic/display_demo/graphic_config/product_graphic_lite_config.h。
graphic适配见//device/soc/bestechnic/bes2600/liteos_m/components/ui, 主要功能如下:


[*]display_device:实例化BaseGfxEngine。
[*]touch_input:实例化PointerInputDevice。
[*]UiMainTask:初始化字体引擎,执行渲染任务等。
图形子系统层次:
aafwk_lite + appexecfwk_lite    (AAFWK + APPEXECFWK)
      |
ace_engine_lite + jerryscript + i18n_lite + resmgr_lite + utils/native/lite/... (ACE,JS引擎及其依赖)
      |
arkui_ui_lite + graphic_utils      (图形框架)
      |
giflib + libjpeg + libpng + qrcodegen + freetype... (图形第三方库) 图形应用示例见文件//vendor/bestechnic/display_demo/tests/app.cpp,如下:
/* ui app entry */
void RunApp()
{
#ifdef UI_TEST
    AnimatorDemoStart();        --- native ui demo
#elif defined(ABILITY_TEST)
    StartJSApp();                        --- js demo
#endif
}

void AppEntry(void)
{
    UiMain();
}

APP_FEATURE_INIT(AppEntry); ACE开发框架子系统适配

进行ACE开发框架子系统适配须要添加ace_engine_lite部件,直接在config.json配置即可。
{
"subsystem": "ace",
"components": [
    {
      "component": "ace_engine_lite",
      "features": [
      "enable_ohos_ace_engine_lite_product_config = true"
      ]
    }
]
}, ace_engine_lite部件配置文件见 //vendor/bestechnic/display_demo/ace_lite_config/product_acelite_config.h。
ace_lite的应用采用js语言进行开发,详细步调如下:

[*]用DevEco Studio编写js应用,参考轻量级智能穿着开发。
[*]使用预览功能进行预览,并且得到js包:entry\.preview\intermediates\res\debug\lite\assets\js\default。
[*]将js包放到对应的文件系统目次下,文件系统路径为vendor/bestechnic/display_demo/fs/data/data/js,如下:
├── app.js
├── common
├── i18n
├── manifest.json
└── pages

[*]最终编译生成系统镜像,烧录到单板后,系统会从app.js加载启动ace的应用。
元本领子系统适配

进行元本领子系统适配须要添加aafwk_lite部件,直接在config.json配置即可。
{
      "subsystem": "aafwk",
      "components": [
      {
          "component": "aafwk_lite",
          "features": [
            "enable_ohos_appexecfwk_feature_ability = true",       --- 支持FA特性,即包含图形能力
            "config_ohos_aafwk_ams_task_size = 4096"                       --- 配置aafwk栈的大小
          ]
      }
      ]
    }, aafwk_lite相关的应用样例见vendor/bestechnic/display_demo/tests/ability目次,包含launcher和js app这两类应用,应用的函数调用流程形貌如下:

[*] launcher应用,通过InstallLauncher安装BundleName为 "com.example.launcher"的native ui应用,在AbilityMgrSliteFeature启动后会调用AbilityMgrHandler::StartLauncher()启动launcher应用。
[*] StartJSApp应用,通过StartAbility启动任意Want,通过将want data通报JS_APP_PATH, SetWantData(&want, JS_APP_PATH, strlen(JS_APP_PATH) + 1)。
包管理子系统适配

进行包管理子系统适配须要添加appexecfwk_lite部件,直接在config.json配置即可。
{
      "subsystem": "appexecfwk",
      "components": [
      {
          "component": "appexecfwk_lite"
      }
      ]
    },
最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道须要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。以是有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有须要的。 
鸿蒙HarmonyOS Next全套学习资料←点击领取!(安全链接,放心点击)
这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习资料可以大概给大家带来资助,有须要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 鸿蒙Harmony南向开发子系统适配