天天看點

OpenHarmony輕量系統移植示例

1.1移植類型

OpenHarmony輕量系統的移植比較簡單,代碼中解耦做得非常好。從代碼的設計理念上來看,移植主要是3部分的内容:

(1)ARCH部分的代碼

(2)SoC部分的代碼

(3)board級的代碼

從上至下我們可以用一張圖來做對比:

OpenHarmony輕量系統移植示例

ARCH也就是架構,例如ARM架構、RISC-V架構等

SoC是具體晶片,例如STM32、海思等,一個架構可以有多個晶片。

Board是具體開發闆,例如3861有潤和的開發闆、也有小熊派的開發闆。

通常來說,相關架構的不同SoC,應該是共用一套ARCH代碼,不需要為每個SoC都重新寫一遍ARCH代碼,可以增加代碼的複用。

相關SoC的不通過board開發闆,也應該共用一套SoC代碼即可,闆卡之間的代碼差異應該放到board中。

基于如上設計,我們移植的類型可以分為3部分:

(1)ARCH移植:全新的架構級别的移植

(2)SoC移植:已支援的架構做SoC級别的移植

(3)board級别的移植:隻針對開發闆做少量移植。

移植的難度也是ARCH最難,SoC較難、board較簡單。

1.2 相關代碼

我們看下OpenHarmony輕量系統之3部分的代碼分别在哪裡:

(1)ARCH相關代碼

ARCH相關的代碼存放在kernel\liteos_m\arch檔案夾中

OpenHarmony輕量系統移植示例

可以看到目前已支援的架構有ARM(M3、M4、M33、M7、ARM9)、csky、risc-v、xtensa。

(2)SoC相關代碼

SoC相關的代碼位于:device\soc

OpenHarmony輕量系統移植示例

(3)board相關代碼

board相關的代碼位于:device/board

OpenHarmony輕量系統移植示例

(4)vendor相關代碼

除了以上3部分的代碼之外,還有廠商配置相關代碼,這一部分主要是用于編譯系統、HDF配置等,路徑為: vendor

内容如下:

OpenHarmony輕量系統移植示例

1.3移植思路

建議是先從最簡單的開始,路線如下:

vendor —— board —— soc —— ARCH

下一篇文章,将開始講解如何建立一個自己的vendor廠商配置和編譯流程。

一開始會基于GD32單片機

1.4 代碼倉庫

代碼倉庫如下:

OpenHarmony輕量系統移植示例

其中,01_vendor_soc_board 是初步移植的示例,編譯不通過

02_vendor_soc_board是已經可以編譯通過并且燒錄到GD32F303上可以正常跑的。

1.5 使用說明

(1)代碼下載下傳

開發者可以直接先下載下傳最新的openharmony代碼,參考文章:

https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-sourcecode-acquire.md

然後下載下傳本倉庫的代碼,将對應的代碼拷貝到device/board 、device/soc、vendor中

OpenHarmony輕量系統移植示例

(2)交叉編譯器下載下傳:

我們使用的編譯器是arm-none-eabi-gcc,下載下傳位址:

git clone https://gitee.com/harylee/gcc-arm-none-eabi-10-2020-q4-major.git

将交叉編譯器環境變量bin目錄配置到.bashrc檔案中。

執行arm-none-eabi-gcc -v,有如下列印則表示交叉編譯器配置正确。

OpenHarmony輕量系統移植示例

(3)編譯

執行hb set,選擇gd32f303_lianzhian

OpenHarmony輕量系統移植示例

然後執行hb build -f,如下提示,則表示編譯成功

OpenHarmony輕量系統移植示例

2.1 hb編譯原理

當我們輸入hb set指令後,會提示我們選擇要編譯建構的工程。

OpenHarmony輕量系統移植示例

那麼,hb 怎麼知道有哪些工程可以編譯呢?

事實上這些工程都是在vendor檔案夾中的,為了驗證,我們可以在vendor中建立一個空的檔案夾:gd,然後gd檔案夾下面又建立了gd32f303_lianzhian檔案夾。

但是這裡還不夠,一個标準簡單的vendor檔案夾結構如下:

OpenHarmony輕量系統移植示例

其中debug.config内容為空即可,因為它的内容是自動生成的,後面我們配置的核心的時候需要用到。

這幾個檔案我們可以直接複制3861的過來,然後删去我們不需要的子系統,我們隻需要保留如下即可:

config.json檔案:

{
    "product_name": "gd32f303_lianzhian",
    "type": "mini",
    "version": "3.0",
    "device_company": "lianzhian",
    "board": "gd32f303_lianzhian",
    "kernel_type": "liteos_m",
    "kernel_version": "",
    "subsystems": [
      {
        "subsystem": "kernel",
        "components": [
          { "component": "liteos_m",
            "features":[
            ]
          }
        ]
      }
    ],
    "third_party_dir": "",
    "product_adapter_dir": ""
}
           

BUILD.gn檔案

group("gd32f303_lianzhian") {
}
           

此時,我們再去執行hb set,就可以看到我們自己建立的工程了:gd32f303_lianzhian

OpenHarmony輕量系統移植示例

2.2 設計思想

最新的master分支的代碼設計采用Board和SoC解耦的設計思路,具體可以看這個文章:https://gitee.com/openharmony-sig/sig-content/blob/master/devboard/docs/board-soc-arch-design.md

按照硬體進行層次劃分為晶片架構層、片上系統層和單闆層。從下向上依次進行包含關系,例如:

(1)架構

ARMv7E-M架構具有ARM Cortex-M4, ARM Cortex-M7等CPU實作

(2)晶片系列

ARM Cortex-M4 CPU對應的SoC Family有STMicro STM32、NXP i.MX等,反過來,如圖SoC Family 2跨越CPU1和CPU2,意味着一個SoC Family可以包含多個CPU實作,

例如STMicro STM32可以包含Cortex-M0、Cortex-M4等CPU,又例如複雜的STM32MP157 SoC包含兩個Cortex-A7 CPU核與一個Cortex-M4 CPU核,對于異構多核SoC,需要通過OpenAMP來進行分解成多個同構多核的部分。

(3)晶片與開發闆對應關系

STM32 SoC Family有STM32F4、STM32G4等SoC Series。

STM32F4 SoC Series 有 STM32F401、STM32F429等SoC。

STM32F429 SoC 有 野火STM32F429挑戰者開發闆、正點原子stm32f429阿波羅開發闆等。如圖Board 5上面還有一個shields,意味着一個Board可以通過增加擴充闆的形式來提供更強的功能。例如,單闆可以利用序列槽通信外接Hi3861模組,以提供WLAN能力。

OpenHarmony輕量系統移植示例

基于硬體結構劃分層次圖,OpenHarmony頂層目錄結構設計如下,

OpenHarmony輕量系統移植示例

2.3 board配置

1 建立 board檔案夾

當我們輸入hb set指令後,

我們選擇 gd32f303_lianzhian 可以看到會提示報錯:

我們需要建立該檔案夾:device/board/lianzhian

為啥是lianzhian ????

因為我們在vendor中的config.json中指定了device_company 裝置廠家是lianzhian,大家可以回頭看看

标準的board檔案夾目錄結構如下:

OpenHarmony輕量系統移植示例

2 Kconfig配置檔案

我們可以在kernel/liteos_m核心目錄下執行make menuconfig進行圖形化配置,Makefile檔案會周遊board下的所有Kconfig檔案,是以我們需要添加對應的Kconfig檔案。

這裡核心是分層設計的,即廠商配置和具體開發闆分開,一個廠商下面可以有多個開發闆。

例如我們現在移植的裝置廠商是是lianzhian,那麼lianzhian是廠商檔案夾,lianzhian下面有Kconfig,主要是廠商級别的配置。

然後lianzhian下面可以有多個開發闆,我們這裡隻寫了gd32f303_lianzhian開發闆。同樣gd32f303_lianzhian檔案夾下面也有Kconfig配置檔案。

3 廠商Kconfig配置檔案

我們先看下lianzhian廠商的Kconfig檔案

(1)Kconfig.liteos_m.boards 檔案内容:

orsource "*/Kconfig.liteos_m.board"
           

可以看到很簡單,事實上它就是簡單的把目前目錄下的所有檔案夾下的Kconfig.liteos_m.board檔案都導入進來。

(2)Kconfig.liteos_m.defconfig.boards檔案

orsource "*/Kconfig.liteos_m.defconfig.board"
           

同樣把目前目錄下的所有檔案夾下的Kconfig.liteos_m.defconfig.board檔案都導入進來。

(3)Kconfig.liteos_m.shields 檔案

這裡我們暫時不需要,可以内容為空

4 具體開發闆的Kconfig配置檔案

我們先看下gd32f303_lianzhian廠商的Kconfig檔案

(1)Kconfig.liteos_m.board檔案:

需要配置選擇該單闆的選項,以及它依賴的SoC

config BOARD_GD32F303_LIANZHIAN
    bool "select board gd32f303 lianzhian"
    depends on SOC_GD32F303	#隻有當我們晶片型号選擇為GD32F303時才可見
           

這裡是增加一個配置選項,即後面我們可以在make menuconfig中看到"select board gd32f303 lianzhian"配置項。

OpenHarmony輕量系統移植示例

(2)Kconfig.liteos_m.defconfig.board 檔案

需要配置選擇該單闆後,預設定義 BOARD 的名字,該檔案我們可以留白,也可以如下配置:

if BOARD_GD32F303_LIANZHIAN
config BOARD
    string
    default "gd32f303_lianzhian"

endif #BOARD_GD32F303_LIANZHIAN
           

(3)gd32f303_lianzhian_defconfig 檔案

内容為:

LOSCFG_BOARD_GD32F303_LIANZHIAN=y
LOSCFG_SOC_SERIES_GD32F303=y
LOSCFG_SOC_GD32F303ZET6=y
           

這裡表示我們選中的闆卡、SOC、SOC具體子型号系列等。

5 config.gni配置檔案

liteos_m檔案夾下的config.gni檔案是用來進行核心配置的

OpenHarmony輕量系統移植示例

該檔案内容如下:

# Copyright (C) 2020 Hisilicon (Shanghai) Technologies Co., Ltd. All rights reserved.

# 選擇核心類型, e.g. "linux", "liteos_a", "liteos_m".
kernel_type = "liteos_m"

# 核心版本,留白即可.
kernel_version = ""

# 晶片架構, e.g. "cortex-a7", "riscv32".
board_cpu = "cortex-m4"

# 這裡一般不用謝, 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 toolchain.
# 交叉編譯器名稱
board_toolchain = "arm-none-eabi-gcc"

# The toolchain path installed, it's not mandatory if you have added toolchain 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 = [
  "-mcpu=cortex-m4",
  "-mfpu=fpv4-sp-d16",
  "-mfloat-abi=hard",
  "-mthumb",
  "-Og",
  # "-g",
  #"-Wall",
  "-fdata-sections",
  "-ffunction-sections",
  # 注意,這裡我們需要定義GD32F30X_HD宏
  "-DGD32F30X_HD",
  # 我們需要浮點數計算
  "-D__FPU_PRESENT",
]
board_cxx_flags = board_cflags
board_ld_flags = []

# 頭檔案路徑,一般需要soc相關 Board related headfiles search path.
board_include_dirs = [
  "${ohos_root_path}device/soc/gd32/gd32f303/liteos_m",
  "${ohos_root_path}device/soc/gd32/CMSIS",
  "${ohos_root_path}device/soc/gd32/CMSIS/GD/GD32F30x/Include",
  "${ohos_root_path}device/soc/gd32/gd32f303/GD32F3XX_Driver/Inc",
  "${ohos_root_path}device/soc/gd32/gd32f303",
  "${ohos_root_path}utils/native/lite/include",
  "${ohos_root_path}kernel/liteos_m/components/cpup",
  "${ohos_root_path}kernel/liteos_m/components/exchook",
  
]

# 開發闆用到哪個soc Board adapter dir for OHOS components.
board_adapter_dir = "${ohos_root_path}device/soc/gd32"

# Sysroot path.
board_configed_sysroot = ""

# Board storage type, it used for file system generation.
storage_type = ""
           

2.4 SOC配置

1 建立 SOC檔案夾

我們進入到device/soc檔案夾,建立 gd32檔案夾,gd32檔案夾内容如下:

OpenHarmony輕量系統移植示例

其中GD32官方标準庫檔案和CMSIS都可以在GD官網下載下傳到,而且不需要我們修改編寫,故而本節不會講其中的内容,重點放在Kconfig配置檔案中。

同樣,soc也是分為晶片廠家的Kconfig 和具體晶片信号的Kconfig,gd32是晶片廠家,gd32f303隻是其中的一款型号而已。

2 gd32晶片廠家Kconfig配置檔案

(1)先看Kconfig.liteos_m.soc檔案

config SOC_COMPANY_GD32
    bool

if SOC_COMPANY_GD32
config SOC_COMPANY
    default "gd32"

rsource "*/Kconfig.liteos_m.soc"
endif # SOC_COMPANY_GD32
           

這裡很簡單,就是配置我們的晶片廠商預設為 gd32

之後導入所有檔案夾的 Kconfig.liteos_m.soc 配置檔案

(2)Kconfig.liteos_m.series檔案

這個檔案就比較簡單了,導入所有檔案夾的 Kconfig.liteos_m.series 配置檔案

rsource "*/Kconfig.liteos_m.series"
           

(3)Kconfig.liteos_m.defconfig

同樣,導入所有檔案夾的Kconfig.liteos_m.defconfig

rsource "*/Kconfig.liteos_m.defconfig.series"
           

3 gd32F303晶片的Kconfig配置檔案

我們來看看具體的晶片型号gd32f303的配置檔案吧

(1)Kconfig.liteos_m.series檔案

需要配置晶片系列,以及它的晶片架構等資訊

内容:

config SOC_SERIES_GD32F303
    bool "GD32F303 chip"
    select ARM
    select SOC_COMPANY_GD32
    select CPU_CORTEX_M4
    help
        Enable support for GD32F303
           

這個是晶片系列的選擇,我們的晶片系列是GD32F303,架構是ARM、CORTEX_M4 晶片廠家是 SOC_COMPANY_GD32,這個在上一級gd32的Kconfig配置檔案中有定義。

(2)Kconfig.liteos_m.soc檔案

需要配置晶片系列有多少個型号的晶片。

内容:

choice
    prompt "GD32F303 series SoC"
    depends on SOC_SERIES_GD32F303  #隻有選擇了晶片系列SOC_SERIES_GD32F303後才會出現如下選項

config SOC_GD32F303ZET6		#增加一個SOC_GD32F303ZET6選項,我們現在隻有GD32F303ZET6,後面可以還有GD32F303RCT6等。
    bool "SoC GD32F303ZET6"

endchoice
           

(3)Kconfig.liteos_m.defconfig.series 檔案

選擇晶片系列後預設的配置

内容:

if SOC_SERIES_GD32F303

rsource "Kconfig.liteos_m.defconfig.gd32f303"

config SOC_SERIES
    string
    default "gd32f303"

config NUM_IRQS  #中斷數量,跟具體晶片相關
    int
    default 90

config SYS_CLOCK_HW_CYCLES_PER_SEC  #時鐘周期,GD32F303是120MHz
    int
    default 120000000

endif
           

(4)Kconfig.liteos_m.defconfig.gd32f303 檔案

Gd32f303的配置,内容比較簡單:

config SOC
    string
    default "gd32f303zet6"
    depends on SOC_GD32F303ZET6
           

預設是gd32f303zet6

至此我們的soc的kconfig配置基本完成

4 核心配置頭檔案

還有一個比較重要的核心配置頭檔案,target_config.h。這個大家可以直接複制我的就行,主要是核心功能配置相關。

OpenHarmony輕量系統移植示例

其中有一個比較重要的配置項:

/**
 * @ingroup los_config
 * Memory size
 */
#define LOSCFG_SYS_HEAP_SIZE                                (60*1024)

           

這個是配置核心的堆棧大小,這裡可以根據自己晶片的記憶體大小來定,GD32F303記憶體是64KB,這裡我用60k即可。

2.5 make menuconfig配置

完成上面移植内容後,接下來,我們就可以進行menuconfig配置了。

注意,這裡我們需要先執行一次hb set選擇我們的開發闆gd32f303_lianzhian。

我們進入 kernel/liteos_m 檔案夾

執行 make menuconfig

OpenHarmony輕量系統移植示例

進入Platform,我們選擇gd32f303晶片、gd32f303_lianzhian開發闆,如下:

OpenHarmony輕量系統移植示例

退出儲存。

結果将自動儲存在$(PRODUCT_PATH)/kernel_configs/debug.config

2.6 gn編譯

在上一步Kconfig的圖形化配置後,将其生成的配置結果可以作為gn編譯的輸入,以控制不同子產品是否編譯。另外為了解決之前gn編寫時,随意include的問題,核心編譯做了子產品化編譯的設計,使得整個編譯邏輯更加清晰。

我們需要編寫device/board/lianzhian 和 device/soc/gd32兩個檔案夾下的BUILD.gn。

這幾個BUILD.gn檔案比較簡單,都是子產品化編譯,大家可以直接參考我的。

2.7 編譯器安裝

我們使用的編譯器是arm-none-eabi-gcc,下載下傳位址:

git clone https://gitee.com/harylee/gcc-arm-none-eabi-10-2020-q4-major.git

将交叉編譯器環境變量bin目錄配置到.bashrc檔案中。

2.8 開始編譯

配置完BUILD.gn後,我們就可以開始執行hb build -f編譯了。

可以看到已經能編譯過一大半了:

OpenHarmony輕量系統移植示例

我們今天的目标就是要能讓編譯系統能開始編譯我們的開發闆

一步一腳印,接下來我們将繼續開始移植,接下來将配置libc庫、系統啟動、main函數、連結腳本,直到編譯通過并且在開發闆中成功運作~

想了解更多關于鴻蒙的内容,請通路:

51CTO和華為官方合作共建的鴻蒙技術社群

繼續閱讀