当前位置: 首页 > news >正文

WordPress的登录页面什么网站利于优化

WordPress的登录页面,什么网站利于优化,wordpress产品开启评论,免费网站推荐软件本文章基于恒玄科技 BES2600W 芯片的欧智通 Multi-modal V200Z-R 开发板#xff0c;进行轻量带屏开发板的标准移植#xff0c;开发了智能开关面板样例#xff0c;同时实现了 ace_engine_lite、arkui_ui_lite、aafwk_lite、appexecfwk_lite、HDF 等部件基于 OpenHarmony Lite…本文章基于恒玄科技 BES2600W 芯片的欧智通 Multi-modal V200Z-R 开发板进行轻量带屏开发板的标准移植开发了智能开关面板样例同时实现了 ace_engine_lite、arkui_ui_lite、aafwk_lite、appexecfwk_lite、HDF 等部件基于 OpenHarmony LiteOS-M 内核的适配。移植架构上采用 Board 与 SoC 分离的方案工具链 Newlib C 库与 Musl C 库可选LiteOS-M 内核编译采用 gn 结合 Kconfig 图形化配置等需求。 编译构建 目录规划 本案例在芯片移植架构方面进行了一些改进以前的芯片适配目录规划为 device └── device_company└── device_name 这样会导致小熊派 BearPi-HM Nano 开发板与润和的 HiSpark Pegasus 开发板使用小海思的 hi3861 的 SoC 时需要在这两款开发板里面都放置一份重复的代码。为了解决该问题本案例将单板厂商与 SoC 厂商进行分离可以参考 Board 和 SoC 解耦的设计思路并把芯片适配目录规划为 device ├── board --- 单板厂商目录 │   └── fnlink --- 单板厂商名字欧智通 │   └── v200zr --- 单板名v200zr └── soc --- SoC厂商目录└── bestechnic --- SoC厂商名字恒玄└── bes2600 --- SoC Series名bes2600是一个系列里面包含bes2600w等SoC名 产品样例目录规划为 vendor └── bestechnic --- 开发产品样例厂商目录恒玄开发的带屏样例因此以bestechnic命名└── display_demo --- 产品名字以智能开关面板的带屏显示样例 预编译适配 在进行移植之前需要进行预编译适配。 预编译适配主要使用 hb set 命令设置整个项目的根目录、单板目录、产品目录、单板公司名等环境变量为编译做准备。 具体的预编译适配步骤如下 在 vendor/bestechnic/display_demo 目录下新增 config.json 文件用于描述这个产品样例所使用的单板、内核等信息描述信息可参考如下内容 {product_name: display_demo, --- 用于hb set进行选择时显示的产品名称type: mini, --- 构建系统的类型mini/small/standardversion: 3.0, --- 构建系统的版本1.0/2.0/3.0device_company: fnlink, --- 单板厂商名用于编译时找到/device/board/fnlink目录board: v200zr, --- 单板名用于编译时找到/device/board/fnlink/v200zr目录kernel_type: liteos_m, --- 内核类型因为OpenHarmony支持多内核一块单板可能适配了多个内核所以需要指定某个内核进行编译kernel_version: 3.0.0, --- 内核版本一块单板可能适配了多个linux内核版本所以需要指定某个具体的内核版本进行编译subsystems: [ ] --- 选择所需要编译构建的子系统 } 在 device/board/fnlink/v200zr/liteos_m 目录下新增 config.gni 文件用于描述这个产品样例所使用的单板、内核等信息描述信息可参考如下内容 # Kernel type, e.g. linux, liteos_a, liteos_m. kernel_type liteos_m --- 内核类型跟config.json中kernel_type对应 # Kernel version. kernel_version 3.0.0 --- 内核版本跟config.json中kernel_version对应 ​ 验证 hb set 配置是否正确输入 hb set 能够显示如下图片表示配置正确。 执行 hb set 输入项目根目录并且回车hb 命令会遍历所有 //vendor/product_company/product_name 目录下的 config.json给出可选产品编译选项config.json 的 product_name 用于显示产品名device_company 和 board 用于关联出 //device/board/device_company/board 目录并且匹配 any_dir_name/config.gni 文件如果能够匹配多个文件表示该单板适配了多个内核那么可以根据 config.json 的 kernel_type 和 kernel_version 来唯一匹配 config.gni 的 kernel_type 和 kernel_version即可确定了需要编译适配了哪个内核的单板。 通过 hb env 可以查看选择出来的预编译环境变量。 在执行 hb build 之前需要准备好 LiteOS-M 内核适配具体适配步骤请参内核移植。 内核移植 内核移植需要完成 LiteOS-M Kconfig 适配、gn 的编译构建和内核启动最小适配。 LiteOS-M Kconfig 适配 在 //kernel/liteos_m 目录下执行 make menuconfig 命令完成编译配置选项的选择。在 Makefile 文件中会将 hb env 的结果转换成环境变量即 PRODUCT_PATH、DEVICE_PATH 和 BOARD_COMPANY。如下代码块所示 $(foreach line,$(shell hb env | sed s/\[OHOS INFO\]/ohos/g;s/ /_/g;s/:_//g || true),$(eval $(line))) ifneq ($(ohos_kernel),liteos_m) $(error The selected product ($(ohos_product)) is not a liteos_m kernel type product) endif --- 将hb env的每一行输出转化为变量形式例如将[OHOS INFO] device company: fnlink转换为ohos_device_companyfnlink …… ifeq ($(BOARD_COMPANY),) BOARD_COMPANY:$(ohos_device_company) endif …… export BOARD_COMPANY --- 将ohos_device_company转化为BOARD_COMPANY环境变量 ​ 在 //kernel/liteos_m/Kconfig 文件中使用这些导出的环境变量Kconfiglib 采用 ulfalizer 开发基于 python 的版本源码地址功能介绍连接参考里面用到了 orsource 关键字其中 o 表示 optional表示这个文件是否存在可选r 表示 relative表示这个文件相对当前文件的相对路径。 config SOC_COMPANYstring SoC company name to locate soc build pathhelpThis option specifies the SoC company name, used to locate the build path for soc. This option is set by theSoCs Kconfig file, and should be exactly the same with SoC company path, and the user should generally avoidmodifying it via the menu configuration. orsource ../../device/board/*/Kconfig.liteos_m.shields --- 将所有扩展板配置信息加载进来因为单板厂商A提供扩展板可以给单板厂商B使用所以这里使用*匹配所有的扩展板而非BOARD_COMPANY。另外由于OpenHarmony支持多内核设计Kconfig文件采用liteos_m作为后缀在进行单板适配过程中其他内核在适配过程中可以使用对应的内核名作为后缀名进行扩展。 orsource ../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.defconfig.boards --- 加载BOARD_COMPANY的所有单板预定义配置 choiceprompt Board Selection orsource ../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.boards --- 提供Board选择列表 endchoice orsource ../../device/soc/*/Kconfig.liteos_m.defconfig --- 加载所有SoC的默认配置定义 choiceprompt SoC Series Selection orsource ../../device/soc/*/Kconfig.liteos_m.series --- 提供所有SoC Series选择列表 endchoice orsource ../../device/soc/*/Kconfig.liteos_m.soc --- 加载所有SoC配置 ​ 从 //kernel/liteos_m/Kconfig 文件可以看出需要在 //device/board/fnlink 目录下新增如下 Kconfig 文件进行适配 . ├── v200zr --- v200zr单板配置目录 │   ├── Kconfig.liteos_m.board --- 提供v200zr单板的配置选项 │   ├── Kconfig.liteos_m.defconfig.board --- 提供v200zr单板的默认配置项 │   └── liteos_m │   └── config.gni ├── Kconfig.liteos_m.boards --- 提供fnlink单板厂商下Boards配置信息 ├── Kconfig.liteos_m.defconfig.boards --- 提供fnlink单板厂商下Boards默认配置信息 ├── Kconfig.liteos_m.shields --- 提供fnlink单板厂商下扩展板配置信息 └── shields --- fnlink单板厂商的扩展板目录├── v200zr-t0 --- fnlink单板厂商的扩展板v200zr-t0│   ├── Kconfig.liteos_m.defconfig.shield --- 扩展板v200zr-t0默认配置│   └── Kconfig.liteos_m.shield --- 扩展板v200zr-t0配置信息├── v200zr-t1│   ├── Kconfig.liteos_m.defconfig.shield│   └── Kconfig.liteos_m.shield└── Kconfig.liteos_m.shields ​ 在 v200zr/Kconfig.liteos_m.board 需要配置选择该单板的选项以及它依赖的 SoC如下 config BOARD_v200zrbool select board v200zrdepends on SOC_BES2600W --- v200zr单板用的bes2600w的SoC只有 bes2600w的SoC被选择后v200zr单板配置选项才可见可以被选择。 ​ 在 v200zr/Kconfig.liteos_m.defconfig.board 需要配置选择该单板后默认定义 BOARD 的名字为 v200zr 如下 if BOARD_v200zr config BOARDstring --- string后没有带提示因此用户不可见default v200zr endif # BOARD_v200zr ​ 从 //kernel/liteos_m/Kconfig 文件可以看出需要在 //device/soc/bestechnic 目录下新增如下 Kconfig 文件进行适配 . ├── bes2600 --- bes2600 SoC系列 │   ├── Kconfig.liteos_m.defconfig.bes2600w --- bestechnic芯片厂商bes2600w SoC Series配置 │   ├── Kconfig.liteos_m.defconfig.series --- bestechnic芯片厂商bes2600默认配置 │   ├── Kconfig.liteos_m.series --- bestechnic芯片厂商bes2600 SoC Series配置 │   └── Kconfig.liteos_m.soc --- bestechnic芯片厂商bes2600 SoC配置 ├── Kconfig.liteos_m.defconfig --- bestechnic芯片厂商SoC默认配置 ├── Kconfig.liteos_m.series --- bestechnic芯片厂商SoC Series配置 └── Kconfig.liteos_m.soc --- bestechnic芯片厂商 SoC配置 ​ 在 bes2600/Kconfig.liteos_m.series 需要配置 bes2600 SoC series以及它的芯片架构等信息如下 config SOC_SERIES_BES2600 --- 提供bes2600 SoC Series选项bool Bestechnic 2600 Seriesselect ARM --- 选择bes2600后默认选择ARM架构select SOC_COMPANY_BESTECHNIC --- 选择bes2600后默认选择bestechnic芯片公司驱动会依赖这个宏配置选择配置编译对应厂商的驱动select CPU_CORTEX_M33 --- 选择bes2600后默认选择cortex-m33 CPUhelpEnable support for Bestechnic 2600 series ​ 在 bes2600/Kconfig.liteos_m.soc 需要提供 bes2600 SoC series 下有多少个具体的 SoC 可供选择如下 choiceprompt Bestechnic 2600 series SoCdepends on SOC_SERIES_BES2600 --- 只有选择了bes2600 Series后才会出现如下配置选项 config SOC_BES2600W --- 增加bes2600w SoC配置选择项bool SoC BES2600w endchoice ​ 在 bes2600/Kconfig.liteos_m.defconfig.series 需要提供 bes2600 SoC series 选择后的默认配置如下 if SOC_SERIES_BES2600 --- 选择了bes2600 Series后才会增加如下默认配置选项 rsource Kconfig.liteos_m.defconfig.bes2600w --- 增加bes2600w SoC的默认配置 config SOC_SERIES --- 增加SOC_SERIES的默认配置stringdefault bes2600 endif ​ 配置完成后还需要根据 kernel/liteos_m/Makefile 文件配置 make menuconfig 的 defconfig 保存路径 ifeq ($(TEE:1y),y) tee _tee endif ifeq ($(RELEASE:1y),y) CONFIG ? $(PRODUCT_PATH)/kernel_configs/release$(tee).config else CONFIG ? $(PRODUCT_PATH)/kernel_configs/debug$(tee).config --- 配置文件保存在$(CONFIG)中由产品最终定义 endif …… update_config menuconfig:$(HIDE)test -f $(CONFIG) cp -v $(CONFIG) .config menuconfig $(args) savedefconfig --out $(CONFIG) ​ 在这个例子中defconfig 配置路径为 $(PRODUCT_PATH)/kernel_configs/debug.config创建该文件后内容为空产品的目录文件结构如下 . └── display_demo├── config.json└── kernel_configs└── debug.config ​ 配置完成后在 kernel/liteos_m 目录下执行 make menuconfig 能够对 SoC Series/SoC/Board 进行选择如下 结果将自动保存在 $(PRODUCT_PATH)/kernel_configs/debug.config下次执行 make menuconfig 时会导出保存的结果。 gn 编译适配 在上一步 Kconfig 的图形化配置后将其生成的配置结果可以作为 gn 编译的输入以控制不同模块是否编译。另外为了解决之前 gn 编写时随意 include 的问题内核编译做了模块化编译的设计使得整个编译逻辑更加清晰设计思路请参考 LiteOS-M 内核 BUILD.gn 编写指南。 在 kernel/liteos_m/BUILD.gn 中指定了 Board 和 SoC 的编译入口为 //device/board/fnlink 和 //device/soc/bestechnic。 deps [ //device/board/$device_company ] deps [ //device/soc/$LOSCFG_SOC_COMPANY ] ​ 在 //device/board/fnlink/BUILD.gn 中新增内容如下 if (ohos_kernel_type liteos_m) { --- 由于多内核设计对于LiteOS-M内核适配需要用宏来隔离import(//kernel/liteos_m/liteos.gni) --- 引入内核gn编写模板module_name get_path_info(rebase_path(.), name) --- 动态获取当前文件目录作为模块名防止目录名修改后这里还需要跟着修改module_group(module_name) { --- 采用module_group模板modules [ --- 添加需要编译的模块]} } ​ 同理 //device/soc/bestechnic/BUILD.gn 也是一样。 内核启动适配 系统启动流程分为三个阶段 阶段名称分区规划描述BOOT1[0, 0x10000]第一阶段启动进行固件启动BOOT2[0x2C010000, 0x2C020000]第二阶段启动进行 OTA 升级启动RTOS_MAIN[0x2C080000, 0x2C860000]第三阶段启动进行内核启动在第三阶段内核启动中需要适配的文件路径在 //device/soc/bestechnic/bes2600/liteos_m/sdk/bsp/rtos/liteos/liteos_m/board.c内核启动适配总体思路如下 中断向量的初始化 os_vector_init 初始化中断的处理函数。内核初始化 osKernelInitialize 。创建线程 board_main进行芯片平台初始化。内核启动开始调度线程 osKernelStart 。 其中本章节详细对第 3 步进行展开其他几步为对内核函数调用不作详细描述。 第 3 步中 board_main 在启动 OHOS_SystemInit 之前需要初始化必要的动作如下 ...if(!ret) {...OhosSystemAdapterHooks(); --- 系统启动时候设置钩子启动OpenHarmonyOHOS_SystemInit的之前完成打印和驱动的初始化...OHOS_SystemInit(); --- 启动OpenHarmony服务以及组件初始化} .... ​ OhosSystemAdapterHooks 函数在 device/soc/bestechnic/bes2600/liteos_m/components/utils/src/hm_sys.c 文件中如下 int OhosSystemAdapterHooks(void) {init_trace_system(); --- 初始化打印函数DeviceManagerStart(); --- 调用DeviceManagerStart函数进行HDF驱动初始化这个过程会调用单板代码中的驱动配置文件hdf.hcs以及drivers源码实现return 0; } ​ littlefs 文件系统移植 V200Z-R 开发板开发板采用最大 32MB 的支持 XIP 的 Nor Flash文件系统可以使用 example适配过程中需要在指定路径下放置文件系统预置文件根据配置可自动生成文件系统镜像可以实现自动化生成和打包到烧录包中。 配置指定目录放置打包文件系统 config.json通过 flash_partition_dir 指定目录 flash_partition_dir: fs --- 表示在vendor/bestechnic/display_demo/fs目录下放置文件系统预置文件 ​ 在指定目录 vendor/bestechnic/display_demo/fs 下放置两部分内容 wifi_Download_cfg.yaml镜像的烧录配置文件可以根据实际情况调整分区。/data/data第一个/data 是挂载的根目录第二个 data 是根目录里面的 data 目录里面可以存放预置文件或者在第二个 data 的同级目录再创建一个目录打包的时候只认第一个 data 挂载根目录。 config.json 中根据 wifi_Download_cfg.yaml 最后调整结果。 fs_src 配置文件系统挂载名字。fs_name 是最后生成文件系统的名字。block_size 配置成 4K 对齐建议不修改。fs_size 是生成文件系统的大小。burn_name 是烧录 bin 名字的大小。enable 表示是否生成这个文件系统 在 //device/soc/bestechnic/bes2600/liteos_m/components/hdf_config/hdf.hcs 文件配置文件系统的烧录的起始地址、文件系统的大小以及读数据块的大小 block_size 等信息参考配置如下 misc {fs_config {example_config {match_attr littlefs_config;mount_points [/data];partitions [10];block_size [4096];block_count [1024];}}storage_config {flash_config {match_attr flash_config;partitions [10];owner [0];description [littlefs];start_addr [0xB60000];length [0x400000];options [3];}}} ​ 最后在 device/soc/bestechnic/bes2600/liteos_m/components/fs/fs_init.c 中通过 hdf 加载数据进行读写 flash如下 static int32_t FsDriverInit(struct HdfDeviceObject *object) {if (object NULL) {return HDF_FAILURE;}if (object-property) {if (FsGetResource(fs, object-property) ! HDF_SUCCESS) {HDF_LOGE(%s: FsGetResource failed, __func__);return HDF_FAILURE;}}for (int i 0; i sizeof(fs) / sizeof(fs[0]); i) {if (fs[i].mount_point NULL)continue;fs[i].lfs_cfg.read littlefs_block_read;fs[i].lfs_cfg.prog littlefs_block_write;fs[i].lfs_cfg.erase littlefs_block_erase;fs[i].lfs_cfg.sync littlefs_block_sync;fs[i].lfs_cfg.read_size 256;fs[i].lfs_cfg.prog_size 256;fs[i].lfs_cfg.cache_size 256;fs[i].lfs_cfg.lookahead_size 16;fs[i].lfs_cfg.block_cycles 1000;int ret mount(NULL, fs[i].mount_point, littlefs, 0, fs[i].lfs_cfg);HDF_LOGI(%s: mount fs on %s %s\n, __func__, fs[i].mount_point, (ret 0) ? succeed : failed);}return HDF_SUCCESS; } ​ C 库适配 在轻量系统中C 库适配比较复杂设计思路请参考 LiteOS-M 内核支持 musl 与 newlib 平滑切换方案由于我们的工具链采用 gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 自带 newlib 的 C 库那么系统移植整体采用 newlib 的 C 库。那么在内核的 make menuconfig 中选择 newlib如下图 malloc 适配 malloc 适配参考 The Red Hat newlib C Library-malloc。实现 malloc 适配有以下两种方法 实现 _sbrk_r 函数。这种方法中内存分配函数使用 newlib 中的。实现 _malloc_r, _realloc_r, _reallocf_r, _free_r, _memalign_r, 和 _malloc_usable_size_r。这种方法中内存分配函数可以使用内核的。 为了方便地根据业务进行内存分配算法调优和问题定位在这两种方法中本案例选择后者。 首先由于 newlib 中已经存在这些函数的符号因此需要用到 gcc 的 wrap 的链接选项替换这些函数符号为内核的实现内核的实现为 //kernel/liteos_m/kal/libc/newlib/porting/src/malloc.c。 然后在 //device/board/fnlink/v200zr/liteos_m/config.gni 的新增这些函数的 wrap 链接选项。 board_ld_flags [-Wl,--wrap_malloc_r,-Wl,--wrap_realloc_r,-Wl,--wrap_reallocf_r,-Wl,--wrap_free_r,-Wl,--wrap_memalign_r,-Wl,--wrap_malloc_usable_size_r, ] ​ vsprintf 等适配 参考 The Red Hat newlib C Library 实现 vprintf, vfprintf, printf, snprintf 和 sprintf。 类似 malloc 适配首先要提供这些函数的实现//device/soc/bestechnic/bes2600/liteos_m/components/utils/src/printf.c本案例直接采用开源协议友好的实现。与 malloc 适配不同的是这个函数由芯片原厂提供。因为就打印来说根据项目的需要实现可大可小内核不方便提供统一的实现。 然后在 //device/board/fnlink/v200zr/liteos_m/config.gni 的新增这些函数的 wrap 链接选项。 board_ld_flags [-Wl,--wrapprintf,-Wl,--wrapsprintf,-Wl,--wrapsnprintf,-Wl,--wrapvsnprintf,-Wl,--wrapvprintf, ] ​ open 等适配 这部分实现由内核统一实现芯片适配无须关注内核文件 //kernel/liteos_m/kal/libc/newlib/porting/src/fs.c适配了 newlib 的 _read、_write 等函数如下 …… ssize_t _read(int fd, void *buf, size_t nbyte) {return LOS_Read(fd, buf, nbyte); } ssize_t _write(int fd, const void *buf, size_t nbyte) {return LOS_Write(fd, buf, nbyte); } off_t _lseek(int fd, off_t offset, int whence) {return LOS_Lseek(fd, offset, whence); } …… ​ 板级系统移植 驱动移植 SoC 芯片平台 HDF 驱动移植 驱动适配相关文件放置在 drivers/adapter/platform 中对应有 gpioi2cpwmspiuartwatchdog都是通过 HDF 机制加载本章节以 gpio 为例进行详细说明。 GPIO 驱动适配 gpio 驱动适配需要完成编译的适配、源码的适配。 在 //drivers/adapter/platform/gpio/BUILD.gn 文件中描述了恒玄 gpio 驱动的编译适配。如下 module_switch defined(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO) --- 如果打开HDF的GPIO配置开关才进行如下编译 module_name get_path_info(rebase_path(.), name) hdf_driver(module_name) {sources []if (defined(LOSCFG_SOC_COMPANY_BESTECHNIC)) { --- 如果打开恒玄的芯片配置开关才进行恒玄GPIO的驱动编译sources [ gpio_bes.c ]}include_dirs [ . ] } ​ 在 //drivers/adapter/platform/gpio/gpio_bes.c 文件中描述了恒玄 gpio 驱动的源码适配。 首先按照 OpenHarmony 的 HDF 驱动框架加载驱动基本适配框架如下 struct HdfDriverEntry g_GpioDriverEntry {.moduleVersion 1,.moduleName BES_GPIO_MODULE_HDF,.Bind GpioDriverBind,.Init GpioDriverInit,.Release GpioDriverRelease, }; HDF_INIT(g_GpioDriverEntry); --- 通过HDF_INIT 加载GPIO驱动 ​ 然后在初始化的时候会获取 hcs 参数进行初始化如下 static int32_t GpioDriverInit(struct HdfDeviceObject *device) {int32_t ret;struct GpioCntlr *gpioCntlr NULL;if (device NULL) {HDF_LOGE(%s: device is NULL, __func__);return HDF_ERR_INVALID_PARAM;}gpioCntlr GpioCntlrFromDevice(device); --- gpioCntlr节点变量就可以获取具体gpio配置if (gpioCntlr NULL) {... ​ 编码规范和设计思想见 bes 驱动适配 PR 的评论。 Board 外设器件 HDF 驱动移植 Board 外设器件表示通过 SoC 平台总线连接的外设器件在本案例中显示屏属于外设器件其驱动适配放在 //device/board/fnlink/drivers/liteos_m 目录中。 显示驱动适配 同 SoC 驱动适配在 //device/board/fnlink/drivers/liteos_m/display/BUILD.gn 文件中根据 hdf_driver 模板加载驱动模块如下 module_name get_path_info(rebase_path(.), name) hdf_driver(module_name) {sources [zzw395.c,]include_dirs [//drivers/peripheral/display/interfaces/include,...] } ​ 在 //device/board/fnlink/drivers/liteos_m/display/zzw395.c 文件中根据驱动框架加载显示驱动如下 static struct HdfDriverEntry g_ZZW395DriverEntry {.moduleVersion 1,.moduleName HDF_PANEL_ZZW395,.Bind PanelDriverBind,.Init PanelDriverInit,.Release PanelDriverRelease, }; HDF_INIT(g_ZZW395DriverEntry); ​ 其中的驱动参数根据 hcs 配置在 PanelDriverInit 初始化时加载如下 static int32_t PanelDriverInit(struct HdfDeviceObject *object) {if (object NULL) {return HDF_FAILURE;}HDF_LOGD(%s entry !!!, __func__);if (object-property) {if (PanelGetResource(priv, object-property) ! HDF_SUCCESS) {HDF_LOGE(%s: PanelGetResource failed, __func__);return HDF_FAILURE;}} ... ​ OpenHarmony 子系统适配 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_LWIP1 ]defines [ CHECKSUM_BY_HARDWARE1 ] } config(public) {defines [ _BSD_SOURCE1 ]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_HARDWAREeth_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)标识应用层功能的初始化启动入口说明通过上面加载的组件编译出来的 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[2*ETH_ALEN 1]; --- 最后一位留作\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[ETH_ALEN];// as devboard has no production serial number, we just// use wifi mac address as device serial number.if (serialNumber[0] 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[i] MAC_HIGH_MASK) MAC_BITS;serialNumber[j] Hex2Char(highFour);j;lowFour macAddr[i] MAC_LOW_MASK;serialNumber[j] 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[LOG_FMT_MAX_LEN] {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_TESTAnimatorDemoStart(); --- 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}]}, 兼容性认证 产品兼容性规范 产品兼容性规范文档请参考产品兼容性 SIG 介绍。 XTS 用例 XTS 测试参考资料见 xts 参考资料进行 XTS 子系统适配需要添加 xts_acts/xts_tools 部件直接在 config.json 配置即可配置如下 { subsystem: xts, components: [ { component: xts_acts, features: [ config_ohos_xts_acts_utils_lite_kv_store_data_path /data, enable_ohos_test_xts_acts_use_thirdparty_lwip true ] }, { component: xts_tools, features:[] } ] } 其中 config_ohos_xts_acts_utils_lite_kv_store_data_path 是配置挂载文件系统根目录的名字。enable_ohos_test_xts_acts_use_thirdparty_lwip 表示如果使用 thirdparty/lwip 目录下的源码编译则设置为 true否则设置为 false。 全部跑完会有显示 xx Tests xx Failures xx Ignored如下 ... [16:53:43:438]../../../test/xts/acts/utils_lite/kv_store_hal/src/kvstore_func_test.c:793:testKvStoreMaxSize004:PASS [16:53:43:438]------------------------------------------- [16:53:43:438] [16:53:43:438]----------------------- [16:53:43:438]32 Tests 0 Failures 0 Ignored [16:53:43:438]OK [16:53:43:439]All the test suites finished! ​ 报告提交 将上图 XTS 用例的情况保存为测试报告上传到 OpenHarmony 兼容性测试网站进行认证作为 sig 仓库转正到 master 仓库的必要条件。详细步骤如下 步骤 1将 XTS 测试报告压缩成 zip 文件。 步骤 2生成测试报告的 SHA 校验码。本案例是将 zip 文件传到在线生成 hash 的网站生成 SHA 校验码。 步骤 3进入 OpenHarmony 兼容性测试网站上传报告。 其中 API Level 填写报告中的 sdkApiLevel 字段OS 版本号填写报告中的 OS Version 字段。 todo 后续会补充以下方面的移植 蓝牙bms 包安装验证运行 JS 的 bytecode分布式能力dms、dm分布式音乐播放器样例 最后 有很多小伙伴不知道学习哪些鸿蒙开发技术不知道需要重点掌握哪些鸿蒙应用开发知识点而且学习时频繁踩坑最终浪费大量时间。所以有一份实用的鸿蒙HarmonyOS NEXT资料用来跟着学习是非常有必要的。  这份鸿蒙HarmonyOS NEXT资料包含了鸿蒙开发必掌握的核心知识要点内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等鸿蒙HarmonyOS NEXT技术知识点。 希望这一份鸿蒙学习资料能够给大家带来帮助有需要的小伙伴自行领取限时开源先到先得~无套路领取 获取这份完整版高清学习路线请点击→纯血版全套鸿蒙HarmonyOS学习资料 鸿蒙HarmonyOS NEXT最新学习路线 HarmonOS基础技能 HarmonOS就业必备技能  HarmonOS多媒体技术 鸿蒙NaPi组件进阶 HarmonOS高级技能 初识HarmonOS内核 实战就业级设备开发 有了路线图怎么能没有学习资料呢小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙OpenHarmony 学习手册共计1236页与鸿蒙OpenHarmony 开发入门教学视频内容包含ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。 获取以上完整版高清学习路线请点击→纯血版全套鸿蒙HarmonyOS学习资料 《鸿蒙 (OpenHarmony)开发入门教学视频》 《鸿蒙生态应用开发V2.0白皮书》 《鸿蒙 (OpenHarmony)开发基础到实战手册》 OpenHarmony北向、南向开发环境搭建 《鸿蒙开发基础》 ArkTS语言安装DevEco Studio运用你的第一个ArkTS应用ArkUI声明式UI开发.…… 《鸿蒙开发进阶》 Stage模型入门网络管理数据管理电话服务分布式应用开发通知与窗口管理多媒体技术安全技能任务管理WebGL国际化开发应用测试DFX面向未来设计鸿蒙系统移植和裁剪定制…… 《鸿蒙进阶实战》 ArkTS实践UIAbility应用网络案例…… 获取以上完整鸿蒙HarmonyOS学习资料请点击→纯血版全套鸿蒙HarmonyOS学习资料 总结 总的来说华为鸿蒙不再兼容安卓对中年程序员来说是一个挑战也是一个机会。只有积极应对变化不断学习和提升自己他们才能在这个变革的时代中立于不败之地。
http://www.zqtcl.cn/news/196548/

相关文章:

  • wordpress 分类文章置顶整站优化推广品牌
  • 网站手机验证码如何做官方网站在家做兼职
  • 东莞三合一网站制作网站建设 千助
  • 114网站做推广怎么样江苏建设培训网站
  • 如何让网站做网页适配网站上的产品五星怎样做优化
  • 怎么做网站排名优化免费jq网站模板
  • 源码时代培训机构官网自己建网站怎么做seo
  • 宜都网站制作济南比较大的网站制作公司
  • 怎么用电脑做网站主机假网站怎么制作
  • 网站 微信网络营销方案设计心得
  • 淘宝客 wordpress网站wordpress类似的工具
  • 农村建设房子建设网站建设渭南房产网站制作
  • php网站开发用什么win2008 iis 新建网站
  • 中山营销网站建设杭州网站建设开发有限公司
  • 被他人备案后做违法网站抖音seo推广
  • 手机网站广告代码南靖县建设局网站
  • 郑州网站建设智巢高德地图有外资背景吗
  • 网站开发常遇到客户问题wordpress怎么升级
  • 网站的空间是网站 建设 维护 公司
  • 关于网站建设的书籍网站设计的趋势
  • 临漳+网站建设深圳国贸网站建设
  • 安全的南昌网站制作上海网站建设网
  • 360网站制作潍坊医疗网站建设方案
  • 深圳网站策划公司域名解析暂时失败
  • 怎么做安居客网站wordpress 函数文件
  • 微名片网站怎么做html代码表示
  • 两学一做纪实评价系统网站如何做好百度推广
  • 网站设置手机才能播放企业网站开发需求
  • 网站建设微信运营销售做网站用啥语言
  • dw建设网站步骤活动汪活动策划网站