OpenHarmony LiteOS C-SKY指令集移植指北

華為雲開發者社群發表於2021-11-10
摘要:本文介紹在OpenHarmony社群LiteOS-M專案中新增C-SKY指令集的開發流程,以及適配相應qemu工程的方法和步驟,供LiteOS核心相關開發者學習交流。

本文分享自華為雲社群《OpenHarmony LiteOS指令集移植指南(C-SKY)》,作者: Lionlace。

C-SKY指令集體系結構(ISA)是指第二代獨立的指令集體系結構CK-Core系列智慧財產權指令集體系結構。CSKY ISA具有高效能、高程式碼密度、低功耗和可擴充套件性等特點。

SmartL_E802採用C-SKY V2自主指令架構的E802處理器,是平頭哥半導體有限公司自主研發的低功耗、低成本嵌入式CPU核。其中,SmartL平臺是用於E801/E802/E803S/E804/E805/E902/E906/E907整合和除錯模擬的綜合演示平臺。

本文介紹在OpenHarmony社群LiteOS-M專案中新增C-SKY指令集的開發流程,以及適配相應qemu工程的方法和步驟,供LiteOS核心相關開發者學習交流。

環境搭建

SmartL_E802需要使用官方提供的csky編譯器和qemu工程,以下介紹安裝步驟。

編譯工具鏈安裝

• 獲取csky-elfabiv2編譯器

$ mkdir csky_toolchain && cd csky_toolchain
$ wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource/1356021/1619529111421/csky-elfabiv2-tools-x86_64-minilibc-20210423.tar.gz
$ tar -xf csky-elfabiv2-tools-x86_64-minilibc-20210423.tar.gz

• 將編譯工具鏈新增到環境變數

開啟~/.bashrc檔案

$ vim ~/.bashrc

在末尾加入如下命令列並儲存

export PATH=$PATH:使用者自定義路徑/csky_toolchain/bin

使環境變數生效

$ source ~/.bashrc

qemu安裝

• 獲取qemu軟體

$ mkdir csky_qemu && cd csky_qemu
$ wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource/1356021/1612269502091/csky-qemu-x86_64-Ubuntu-16.04-20210202-1445.tar.gz
$ tar -xf csky-qemu-x86_64-Ubuntu-16.04-20210202-1445.tar.gz

• 將qemu加入環境變數(user_qemu_xxx_path修改為自己的安裝路徑)

開啟~/.bashrc檔案

$ vim ~/.bashrc

在末尾加入如下命令列並儲存

e export PATH=$PATH:使用者自定義路徑/csky-qemu/bin

使環境變數生效

$ source ~/.bashrc

• 安裝依賴

使用ldd指令檢視缺少的依賴庫檔案並下載。

$ ldd qemu_installation_path/bin/qemu-system-cskyv2

注:更詳細的安裝指導,請參考官方指南:

碼源獲取

原始碼獲取教程請參考:

移植

移植過程按照已實現的riscv的qemu開發板目錄結構新增csky的qemu的目錄結構,並在kernel、device和vendor中實現csky指令集及開發板相關程式碼。

新增目錄結構

分別在device、vendor和kernel建立SmartL_E802開發板所需檔案。

• 在device/qemu目錄下建立SmartL_E802資料夾,並在該資料夾中新增如下內容:

OpenHarmony LiteOS C-SKY指令集移植指北

表1 SmartL_E802資料夾目錄

• 在vendor/ohemu目錄下建立qemu_csky_mini_system_demo資料夾,並在該資料夾中新增如下內容:

OpenHarmony LiteOS C-SKY指令集移植指北

表2 開發板資料夾目錄

• 在kernel/liteos_m/kernel/arch目錄下建立csky資料夾,並在該資料夾中新增如下內容:

OpenHarmony LiteOS C-SKY指令集移植指北

表3 csky資料夾目錄

修改kernel程式碼

在kernel/liteos_m/kernel/arch下建立csky資料夾,並完成以下步驟。

• 新增csky架構的選項

在kernel/BUILD.gn下新增對csky架構的選擇:

else if ("$board_cpu" == "e802") {
deps = [ "arch/csky/v2/gcc:arch" ]
}

• 編寫架構程式碼

在kernel/liteos_m/kernel/arch中編寫架構程式碼。

a.編寫異常檔案-los_exc.S

將前32位異常統一入口為HandleEntry,在HandleEntry函式中儲存當前棧 和異常地址並傳參給HalExcHandleEntry函式。該函式將會通過中斷號、g_newTask的值和入參判斷異常發生時所處位置型別(初始化、任務、中斷),並呼叫OsExcInfoDisplay函式輸出記憶體檢測結果、函式呼叫棧回溯結果、任務描述塊資訊、異常型別及原因和異常時暫存器狀態。

OpenHarmony LiteOS C-SKY指令集移植指北

表4 異常向量分配(圖片來源:平頭哥玄鐵E802使用者手冊)

b.編寫排程程式碼-los_dispatch.S

在los_dispatch.S中編寫HalStartToRun函式和HalTaskContextSwitch函式,通過儲存及恢復R0~R15、epc、epsr和psr幾個暫存器,實現任務的上下文切換。在los_context.c中適配系統邏輯,編寫任務棧初始化函式並在該檔案中呼叫排程函式。

OpenHarmony LiteOS C-SKY指令集移植指北

表5 通用暫存器(圖片來源:平頭哥玄鐵E802使用者手冊)

c.編寫系統中斷檔案-los_interrupt.c

將VIC中斷地址VIC_REG_BASE並轉換成結構體,按手冊描述編寫中斷的優先順序,遮蔽、使能和清除功能。使用相關中斷彙編指令實現中斷開關,讀取中斷號等功能。

OpenHarmony LiteOS C-SKY指令集移植指北

表6 緊耦合IP的記憶體地址分配(圖片來源:平頭哥玄鐵E802使用者手冊)

d.編寫定時器檔案-los_timer.c

取定時器地址CORE_TIM_BASE並轉換成對應的地址結構體,按手冊編寫控制和過載等功能。適配系統獲取cycle等介面。

OpenHarmony LiteOS C-SKY指令集移植指北

表7 系統計時器暫存器定義(圖片來源:平頭哥玄鐵E802使用者手冊)

e.在kernel/arch/csky/v2/gcc/BUILD.gn中新增所編寫的檔案

static_library("arch") {
…(加入需要編譯連結的檔案)
}

• 編寫csky架構的backtrace

a.在components/backtrace中增加csky架構的backtrace的相關程式碼。通過棧回溯找到函式呼叫過程中的lr地址並儲存,最後在OsExcInfoDisplay中輸出,為使用者分析異常原因提供參考。

b.在kernel/include/los_config.h的LOSCFG_BACKTRACE_TYPE上增加csky架構backtrace的描述。

5: Call stack analysis for c-sky by scanning the stack.

注:架構相關內容詳情請檢視平頭哥玄鐵E802使用者手冊。

修改device程式碼

在device/qemu下新增SmartL_E802資料夾,並完成以下步驟。

• 移植SDK中程式碼到device目錄下

a.將SmartL_E802 SDK驅動程式碼整理拷貝到driver目錄內,並編寫BUILD.gn檔案編譯驅動程式碼。

b.參考SDK中的gcc_csky.ld中暫存器配置修改liteos.ld檔案,分配程式碼到指定區間。

{
I-SRAM : ORIGIN = 0x0 , LENGTH = 0x20000 /* I-SRAM 128KB */
D-SRAM : ORIGIN = 0x20000000 , LENGTH = 0x20000 /* D-SRAM 128KB */
O-SRAM : ORIGIN = 0x50000000 , LENGTH = 0x800000 /* off-chip SRAM 8MB */
SRAM : ORIGIN = 0x60000000 , LENGTH = 0x20000 /* on-chip SRAM 128KB */
}
…

c.參考SDK中的startup.S檔案,刪除vector定義並編寫中斷總入口

.text
.align 2
.global IrqE
IrqEntry:
psrset ee
subi sp, 72
stm r0-r15, (sp)
mfcr r0, epsr
stw r0, (sp, 64)
mfcr r0, epc
stw r0, (sp, 68)
jbsr HalInterrupt
ldw r0, (sp, 68)
mtcr r0, epc
ldw r0, (sp, 64)
bseti r0, r0, 6
mtcr r0, epsr
ldm r0-r15, (sp)
addi sp, 72
rte

• 編寫串列埠驅動

參考SDK中串列埠demo和printf實現邏輯,編寫dprintf.c/.h並在main.c中呼叫串列埠初始化。

• 適配檔案系統

參考LiteOS程式碼,將fs適配層檔案移植到SmartL_E802中。

• 編寫config.gni檔案

參考device/qemu/riscv32_virt中config.gni 的格式,再參考SDK中的編譯選項和需要對外呼叫的介面,在liteos_m資料夾下編寫config.gni檔案。

• 編寫test測試程式碼

參考device/qemu/riscv32_virt編寫測試程式碼。

• 編寫BUILD.gn檔案

編寫BUILD.gn檔案,將fs適配層,driver開發板驅動程式碼等編譯出來的靜態庫合成liteos可執行檔案。

• 編寫README.md

在SmartL_E802資料夾下編寫中英文使用者指南:README_zh.md及README.md,並修改device/qemu目錄下的中英文文件,新增對csky開發板的介紹。

修改vendor程式碼

在vendor/ohemu下建立qemu_csky_mini_system_demo資料夾,並完成以下步驟。

• 拷貝hals/utils資料夾

參考vendor/ohemu/qemu_riscv32_mini_system_demo,在qemu_csky_mini_system_demo資料夾下新增hals/utils資料夾。

• 編寫BUILD.gn檔案

參考vendor/ohemu/qemu_riscv32_mini_system_demo,編寫BUILD.gn檔案並增加./qemu-run指令碼的使用。

• 修改config.json檔案

參考vendor/ohemu/qemu_riscv32_mini_system_demo,將其中riscv內容修改為csky相關內容。

• 編寫qemu_run.sh指令碼

使用./qemu-run對應的架構指令碼,參考vendor/ohemu/qemu_riscv32_mini_system_demo和平頭哥官方提供的qemu使用手冊()編寫該指令碼。

編譯執行

編譯

• 執行hb set命令並選擇專案qemu_csky_mini_system_demo;

• 執行hb clean && hb build命令構建產生 liteos 可執行檔案。

$ hb set
$ hb clean && hb build

在Qemu中執行映象

• 啟動qemu(不配合GDB)

$ ./qemu-run

• 啟動qemu(配合GDB)

a.啟動GDB伺服器,等待連線

$ ./qemu-run -g

b.新建終端並使用GDB連線qemu

$ csky-abiv2-elf-gdb out/SmartL_E802/qemu_csky_mini_system_demo/unstripped/bin/liteos -ex "target remote localhost:1234"

注:

1.預設使用帶符號表的elf檔案;

2.qemu退出方式為:按下ctrl加a鍵,然後鬆開再按下x鍵。

qemu執行結果關鍵日誌如下:

entering kernel init...
Entering scheduler
Register littlefs done.
../../../third_party/littlefs/lfs.c:1072:error: Corrupted dir pair at {0x0, 0x1}
Littlefs mount at /littlefs/ done.
Littlefs inited.
TaskSampleEntry1 running...
TaskSampleEntry2 running...

本次移植適配的相關原始碼路徑為:

kernel : 

qemu : 

vendor : 

 

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章