OpenHarmony设备开发轻量系统芯片移植指导

zh_ff
发布于 2023-3-22 10:23
浏览
0收藏

概述

本文档从芯片适配的端到端视角,为芯片/模组制造商提供基于OpenHarmony的芯片适配指导。典型的芯片架构,例如cortex-m、risc-v系列都可以按照本文档进行适配移植。

约束与限制

本文档适用于OpenHarmony LTS 3.0.1及之前版本的轻量系统的适配。

说明:

 本文仅对OpenHarmony移植适配过程中需要关注的文件和配置项进行介绍,其他文件以及配置项开发者无需关注,故不作详细介绍。

适配流程

主要开展基于伙伴硬件平台面向OpenHarmony系统的移植适配工作,具体细分为:移植准备、移植内核、移植子系统和移植验证四个环节,见表1芯片适配步骤。

表1 芯片适配步骤

步骤

介绍

移植准备

从OpenHarmony开源社区下载代码,并完成编译环境搭建,基于此初步熟悉和了解OpenHarmony的编译构建框架。

移植内核

将伙伴的SDK移植到OpenHarmony平台,同时根据芯片arch支持情况确认是否需要开展arch的适配工作。

移植子系统

开展包括启动子系统、文件子系统、安全子系统、通信子系统和外设驱动的移植。

移植验证

在适配完成之后使用OpenHarmony社区提供的兼容性测试套件对适配的工程进行基本接口的测试验证,同时伙伴需要使用自有测试能力对适配工程开展质量验证活动。

图1 业务总体流程

OpenHarmony设备开发轻量系统芯片移植指导-鸿蒙开发者社区

基本概念

表2 基本概念

名词

介绍

子系统

是一个逻辑概念,它由一个或多个具体的部件组成。OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 部件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的子系统或部件。

部件

系统最小的可复用、可配置、可裁剪的功能单元。部件具备目录独立可并行开发、可独立编译、可独立测试的特征。

hb

OpenHarmony的命令行工具,用来执行编译命令。

kv

键值对(key-value),描述数据存储的格式。

移植准备

由于OpenHarmony工程需要在Linux环境下进行编译,此章节将指导厂商搭建OpenHarmony的编译环境、获取OpenHarmony源码,并且创建厂商工作目录完成厂商芯片的编译框架适配。

搭建编译环境

开展移植前请参考​​开发环境准备​​完成环境搭建工作。

获取源码

获取操作

请参考​​获取源码​​完成源码下载并进行编译。

说明:

 本文档仅适用于OpenHarmony LTS 3.0.1及之前版本,所以请获取对应版本的源码。

目录介绍

OpenHarmony源码重要目录介绍见表1 OpenHarmony重要目录,其中device和vendor目录为芯片厂商和终端模组厂商工作区域(在​​搭建编译框架​​部分详细介绍)。

表1 OpenHarmony重要目录

目录

用途

build

编译框架所在目录。

kernel/liteos_m

内核所在的目录,其中arch目录描述支撑的内核架构。

device

芯片厂商适配目录,其中“config.gni”描述当前芯片使用的arch,工具链,编译链接选项等。

vendor

终端模组厂商适配目录,其中“config.json”描述需要集成的OpenHarmony子系统列表。

utils

file,kv等相关的适配。

搭建编译框架

厂商开展移植工作时,需要在工程中按照公司名、芯片型号、开发板型号等创建工作目录,并且将所创目录加入到OpenHarmony的编译框架中,使厂商的工作目录能够参与编译,开发者可参照以下步骤进行操作。

  1. 新增芯片厂商。 基于某款芯片进行OpenHarmony的适配,需要在device目录下创建芯片厂商目录,目录内文件描述内核类型,编译工具链,编译链接选项,内核配置选项等。
    创建目录规则:“device/{芯片厂商}/{芯片开发板}”。
    例:“device/MyDeviceCompany/MyBoard”

device
├── hisilicon                                   # hisilicon芯片相关目录,创建目录时可供参考
├── MyDeviceCompany                             # MyDeviceCompany 芯片厂商
│   └── MyBoard                                 # MyBoard 芯片型号
│          ├── BUILD.gn
│          ├── liteos_m
│          │   └── config.gni                   # 芯片工具链,编译链接选项
│          └── target_config.h                  # 内核配置选项
└── qemu                                        # qemu相关

编译脚本:将“device/MyDeviceCompany/MyBoard”下的文件添加到OpenHarmony编译框架中。

路径:“device/MyDeviceCompany/MyBoard/BUILD.gn”

group("MyBoard") {    #将此BUILD.gn文件加入解析
    print("MyDeviceCompany MyBoard is under developing.")
}

开发板编译配置:包括内核类型、工具链类型以及编译参数等内容(详见表2“config.gni”主要配置项)。

路径:“device/MyDeviceCompany/MyBoard/liteos_m/config.gni”

# Kernel type, e.g. "linux", "liteos_a", "liteos_m".
kernel_type = "liteos_m"
 
# Kernel version.
kernel_version = ""
 
# Board CPU type, e.g. "cortex-a7", "riscv32".
board_cpu = "cortex-m4"
 
# Board arch, e.g.  "armv7-a", "rv32imac".
board_arch = ""
 
# Toolchain name used for system compiling.
# E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang,  riscv32-unknown-elf.
# Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain.
board_toolchain = "arm-none-eabi-gcc"
 
# The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc.
board_toolchain_path = ""
 
# Compiler prefix.
board_toolchain_prefix = "arm-none-eabi-"
 
# Compiler type, "gcc" or "clang".
board_toolchain_type = "gcc"
 
# Board related common compile flags.
board_cflags = []
board_cxx_flags = board_cflags
board_ld_flags = []
 
# Board related headfiles search path.
board_include_dirs = []
 
# Board adapter dir for OHOS components.
board_adapter_dir =""

表2 “config.gni”主要配置项

配置项

介绍

kernel_type

开发板使用的内核类型,例如:“liteos_a”,“liteos_m”,“linux”。

kernel_version

开发板使用的内核版本。

board_cpu

开发板CPU类型,例如:“cortex-m4”,“cortex-a7”,“riscv32”。

board_arch

开发芯片arch指令集, 例如:“armv7-a”。

board_toolchain

开发板自定义的编译工具链名称,例如:“gcc-arm-none-eabi”。若为空,则使用默认为ohos-clang。


board_toolchain_path

编译工具链路径,为空则默认使用环境变量中的工具链。

board_toolchain_prefix

编译工具链前缀,例如:“arm-none-eabi-”。

board_toolchain_type

编译工具链类型,目前支持gcc和clang。

board_cflags

开发板配置的c文件编译选项。

board_cxx_flags

开发板配置的cpp文件编译选项。

board_ld_flags

开发板配置的链接选项。

board_include_dirs

开发板配置的系统头文件路径列表。

board_adapter_dir

开发板适配文件路径。

2.新增模组终端厂商。 基于某款具备OpenHarmony能力的芯片进行模组终端开发,需要在vendor下创建模组厂商目录,目录内容主要是使用的OpenHarmony子系统能力。
创建目录规则:“vendor/{产品模组厂商}/{产品模组名称}”。
例:“vendor/MyVendorCompany/MyProduct”

vendor
├── hisilicon                                            # hisilicon 产品相关目录,可供参考
└── MyVendorCompany                                      # MyVendorCompany 产品模组厂商
       └── MyProduct                                     # 具体产品
              ├── BUILD.gn
              └── config.json                            # 产品子系统列表

编译脚本:将“vendor/MyVendorCompany/MyProduct/BUILD.gn”下的文件添加到OpenHarmony编译框架中。

路径:“vendor/MyVendorCompany/MyProduct/BUILD.gn”

group("MyProduct") {
    print("MyVendorCompany MyProduct is under developing.")
}

产品配置信息:包括产品名、设备厂商、内核类型以及所添加的子系统列表等信息(详见表3)。

路径:“vendor/MyVendorCompany/MyProduct/config.json”

{
    "product_name": "MyProduct",
    "ohos_version": "OpenHarmony 1.0",
    "device_company": "MyDeviceCompany",
    "board": "MyBoard",
    "kernel_type": "liteos_m",
    "kernel_version": "",
    "subsystems": [
      {
        "subsystem": "startup",
        "components": [
          { "component": "bootstrap", "features":[] },
          { "component": "syspara_lite", "features":
            [
              "enable_ohos_startup_syspara_lite_use_thirdparty_mbedtls = false"
            ]
          }
        ]
      }
    ],
    "vendor_adapter_dir": "",
    "third_party_dir": "",
    "product_adapter_dir": "//vendor/MyVendorCompany/MyProduct/hals",
}

表3 “config.json”文件配置项

配置项

介绍

product_name

产品名称,hb set时显示产品名称。

ohos_version

OpenHarmony版本号,与实际版本保持一致即可。

device_company

芯片厂商名称,与device的二级目录名称一致。

board

开发板名称,与device的三级目录名称一致。

kernel_type

内核类型,应与开发板移植的OpenHarmony系统内核类型匹配。

kernel_version

内核版本号,与config.gni中kernel_version值匹配。

subsystem

产品选择的子系统,应为OS支持的子系统。子系统定义请见build/lite/components目录下的各子系统描述文件。

components

产品选择的某个子系统下的组件,子系统支持的组件详见build/lite/components/{子系统}.json文件。

features

产品配置的某个组件的特性,详见子系统源码目录对应的BUILD.gn文件。

vendor_adapter_dir

适配IOT外设,UtilsFile文件读写能力,一般指向device下目录。使用详见​​文件子系统移植实例步骤2。​

third_party_dir

芯片厂自身三方软件目录,例如mbedtls,lwip等。如果使用OpenHarmony提供的三方软件,可暂时设空,也可参考hispark_pegasus的配置 。

product_adapter_dir

适配hal_token以及系统参数,一般指向vendor下目录。使用详见​​启动恢复子系统移植实例步骤1。​

说明:

  1. 编译构建系统会对字段进行有效性检查,其中:
  • device_company,board,kernel_type,kernel_version应与芯片厂商配置匹配。
  • subsystem,component应与“build/lite/components”下的部件描述匹配。

移植内核

移植芯片架构

芯片架构的移植是内核移植的基础,在OpenHarmony中芯片架构移植是可选过程,如果当前OpenHarmony已经支持对应芯片架构则不需要移植操作,在“liteos_m/arch”目录下可看到当前已经支持的架构,如表1:

表1 OpenHarmony已支持的架构

系列

型号

arm

arm9

cortex-m3

cortex-m4

cortex-m7

cortex-m33

csky

v2

risc-v

nuclei

riscv32

xtensa

lx6

如果当前OpenHarmony尚未支持对应芯片架构,则需要芯片厂商自行适配,arch/include目录包含了通用的芯片架构适配所需要实现的函数。部分芯片架构代码由汇编实现,而汇编代码会因编译器的不同而不同,因此在具体的芯片架构下,还包含使用不同编译器(iar、keil、gcc等)编译的架构代码。

kernel/liteos_m/arch          # 不同版本路径有差异
├── arm                       # arm系列
│   ├── arm9
│   ├── cortex-m3
│   ├── cortex-m33
│   │   ├── gcc               # 使用gcc编译器编译的架构代码
│   │   └── iar               # 使用iar编译器编译的架构代码
│   ├── cortex-m4
│   ├── cortex-m7
├── csky                      # csky系列
├── include                   # 包含通用的芯片架构所需要实现的函数
│   ├── los_arch.h            # 定义芯片架构初始化所需要的函数
│   ├── los_atomic.h          # 定义芯片架构所需要实现的原子操作函数
│   ├── los_context.h         # 定义芯片架构所需要实现的任务上下文相关函数
│   ├── los_interrupt.h       # 定义芯片架构所需要实现的中断和异常相关的函数
│   └── los_timer.h           # 定义芯片架构所需要实现的系统时钟相关的函数
├── risc-v                    # risc-v系列
│   ├── nuclei
│   └── riscv32
└── xtensa                    # xtensa系列
     └── lx6

移植芯片厂商SDK

编译框架搭建完成后,需要将芯片厂商的SDK加入OpenHarmony编译框架,从而可以编译出带SDK的烧录文件(此时编译出的是不带系统的裸机工程),以便OpenHarmony可以调用SDK中的接口。通过以下步骤将厂商SDK加入OpenHarmony编译框架中:

  1. 将芯片厂商sdk置于device目录下合适的位置,SDK的编译脚本/镜像打包脚本整合进编译框架中。 参考编译脚本:“device/MyDeviceCompany/MyBoard/BUILD.gn”

import("//build/lite/config/component/lite_component.gni")
 
executable("OHOS_Image.elf") {    # 生成可执行程序
  libs = [
    "xxx/xxx/libxxx.a",           # 链接厂商闭源静态库方法一
  ]
  asmflags = [                    # 汇编编译参数
    "",
  ]
  ldflags = [
    "-T./xxx/xxx/xxx.ld",         # 链接脚本文件
    "-Lxxx/xxx/",                 # 指定厂商静态库路径
    "-lxxx",                      # 链接厂商闭源静态库方法二
    "-Wl,--whole-archive",
    "-lmodule_xxx",
    "-Wl,--no-whole-archive",
  ]
  deps = [
    "//build/lite:ohos",          # 依赖OpenHarmony静态库编译完成,链接OpenHarmony编译出来的静态库
    ":sdk",                       # 依赖厂商源码静态库编译完成,链接厂商源码生成的静态库
  ]
}
 
copy("prebuilt") {                # 准备镜像生成工具等,一般把镜像生成工具拷贝到out目录
  sources = [ ]                   # 复制的源文件
  outputs = [ ]                   # 复制的目标文件
}
static_library("sdk") {
  sources = [ ]                   # 添加厂商源码编译成静态库
  include_dirs = [ ]              # 厂商源码包含头文件路径
}
build_ext_component("image") {    # 调用shell命令,生成可烧写镜像文件                             
  exec_path = rebase_path(root_out_dir)   #指定shell命令执行目录
  objcopy = "arm-none-eabi-objcopy"
  objdump = "arm-none-eabi-objdump"
  command = "$objcopy -O binary OHOS_Image.elf OHOS_Image.bin" 
  command += " && sh -c '$objdump -t OHOS_Image.elf | sort > OHOS_Image.sym.sorted'" 
  command += " && sh -c '$objdump -d OHOS_Image.elf > OHOS_Image.asm'"                  
  deps = [
    ":prebuilt",                  # 无需准备镜像生成工具等可以删除此依赖
    ":OHOS_Image.elf",            # 依赖elf文件的生成
  ]
}
group("MyBoard") {                # MyBoard与当前路径名称一致
}

图1 目标的依赖执行顺序   

OpenHarmony设备开发轻量系统芯片移植指导-鸿蒙开发者社区

2.自定义芯片厂“target_config.h”文件。 厂商应在“device/MyDeviceCompany/MyBoard”下合适位置创建内核配置文件“target_config.h”,并根据芯片的硬件资源修改参数(具体参数介绍详见表2target_config.h文件主要配置项)。
参考文件路径:“device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/targets/hi3861v100/include/target_config.h”

说明:

  1. 若已有的配置项不能满足需求,可查看“kernel/liteos_m/kernel/include/los_config.h”,其为liteos_m内核的全量配置文件。
  2. “target_config.h”文件中出现的配置将会覆盖“los_config.h”中的配置。

表2 target_config.h文件主要配置项

配置项

说明

参考值

OS_SYS_CLOCK

系统时钟。

40000000UL

LOSCFG_BASE_CORE_TICK_PER_SECOND

操作系统节拍的时钟周期。

100UL

LOSCFG_BASE_CORE_TICK_HW_TIME

定时器裁剪的外部配置项。

YES

LOSCFG_PLATFORM_HWI

是否采用接管中断的方式。

YES

LOSCFG_BASE_CORE_TSK_LIMIT

支持的最大任务个数(除去空闲任务)。

32

LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE

空闲任务的堆栈大小。

0x180UL

LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE

指定默认的任务栈大小,任务栈的大小按 8 字节大小对齐。

0x1000UL

LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE

表示任务最小需要的堆栈大小。

ALIGN(0x180, 4)

LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT

具有相同优先级任务的最长执行时间。

2

LOSCFG_BASE_IPC_SEM_LIMIT

最大支持信号量的个数。

100

LOSCFG_BASE_IPC_MUX_LIMIT

最大支持互斥量的个数。

64

LOSCFG_BASE_IPC_QUEUE_LIMIT

最大支持消息队列量的个数。

64

LOSCFG_BASE_CORE_SWTMR_LIMIT

支持的最大软件定时器数量,而不是可用的软件定时器数量。

80

LOSCFG_BASE_MEM_NODE_SIZE_CHECK

配置内存节点大小检查。

NO

LOSCFG_PLATFORM_EXC

异常模块配置项。

YES

LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT

是否使用OS默认的中断。

NO

3.修改内核中断。 内核提供了两种中断修改方式:

  1. 使用厂商默认中断。

将“target_config.h”中的宏"LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT"置为NO (0),但需要在xxx.s启动文件中作以下修改:

  • PendSV_Handler:厂商sdk自带中断入口函数,需要替换为OpenHarmony的接口HalPendSV;
  • SysTick_Handler:厂商sdk自带时钟中断入口函数,需要替换为OpenHarmony的接口OsTickHandler。
  1. 系统初始化时重定向中断。

将“target_config.h”中的宏"LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT"和"LOSCFG_PLATFORM_HWI"置为YES (1)。

说明:

 重定向后的中断向量表g_hwiForm需要根据arch手册要求进行字节对齐,通常0x200字节对齐。

添加内核子系统

添加完内核子系统后,可以编译出带有系统的工程。通过以下步骤添加内核子系统:

  1. 在“config.json”中添加内核子系统。 路径:“vendor/MyVendorCompany/MyProduct/config.json”
    修改如下:

{
  "subsystem": "kernel",          # 添加内核子系统
  "components": [
    { 
      "component": "liteos_m", "features":[""] 
    }
  ]
},

2.开启/关闭内核特性。 轻量级系统的内核提供了一些特性,此步骤将指导如何查看、开启/关闭这些特性。
内核特性:liteos_m提供了包括文件系统、backtrace在内的一系列内核特性开关。
路径:“kernel/liteos_m/BUILD.gn”

declare_args() {
  enable_ohos_kernel_liteos_m_cppsupport = true        # cpp支持
  enable_ohos_kernel_liteos_m_cpup = true              # CPU占用率支持
  enable_ohos_kernel_liteos_m_exchook = true           # 异常处理支持
  enable_ohos_kernel_liteos_m_kal = true               # kal接口支持
  enable_ohos_kernel_liteos_m_fs = true                # 文件系统支持
  enable_ohos_kernel_liteos_m_backtrace = true         # backtrace支持
}
group("kernel") {
deps = [
    "components/bounds_checking_function:sec",
    "kernel:kernel",
    "utils:utils",
  ]
  if (enable_ohos_kernel_liteos_m_cppsupport == true) {
    deps += [ "components/cppsupport:cppsupport" ]     # 如果内核特性true,则会加入相应的代码进行编译
  }
  ……
  if (enable_ohos_kernel_liteos_m_kal == true) {
    deps += [ "kal:kal" ]
  }
}

特性:可以选择cmsis接口或者posix接口支持。

路径:“kernel/liteos_m/kal/BUILD.gn”

declare_args() {
  enable_ohos_kernel_liteos_m_cmsis = true  # cmsis支持
  enable_ohos_kernel_liteos_m_posix = true  # posix支持
}
static_library("kal") {
  sources = [ "kal.c" ]
  if (enable_ohos_kernel_liteos_m_cmsis == true) {
    deps += [ "cmsis/" ]                    # 如果cmsis enable,加入cmsis目录编译
  }
  if (enable_ohos_kernel_liteos_m_posix == true) {
    deps += [ "posix/" ]                    # 如果posix enable,加入posix目录编译
  }
}

特性:可以选择fatfs支持。

路径:“kernel/liteos_m/components/fs/BUILD.gn”

declare_args() {
  enable_ohos_kernel_liteos_m_fatfs = true   # fatfs支持
}
group("fs") {
  deps = []
  if (enable_ohos_kernel_liteos_m_fatfs == true) {
    deps += [ "fatfs:fatfs" ] 
  }
}

说明:

 内核特性开关可以在具体产品模组中配置。例如关闭fs和cppsupport特性

“vendor/MyVendorCompany/MyProduct/config.json”

"subsystem": "kernel",
"components": [
 { 
    "component": "liteos_m", 
    "features":["enable_ohos_kernel_liteos_m_fs = false",
    "enable_ohos_kernel_liteos_m_cppsupport = false"] 
  }
]
}


文章转载自:​​https://docs.openharmony.cn/pages/v3.2Beta/zh-cn/device-dev/porting/porting-minichip-kernel.md/​


分类
2
收藏
回复
举报
2条回复
按时间正序
/
按时间倒序
wx652359fa0424a
wx652359fa0424a

写的很详细 好好好!

1
回复
2024-2-1 10:02:46
忙忙忙困困困
忙忙忙困困困

非常详细,感谢

1
回复
2024-2-13 22:29:49
回复
    相关推荐