手把手帶你做LiteOS的樹莓派移植

摘要:樹莓派是英國的慈善組織“Raspberry Pi 基金會”開發的一款基於arm的微型電腦主板。本文介紹基於LiteOS的樹莓派移植過程。

本文分享自華爲雲社區《2021 LiteOS樹莓派移植指南(一)》,作者: Lionlace 。

樹莓派是英國的慈善組織“Raspberry Pi 基金會”開發的一款基於arm的微型電腦主板。本文介紹基於LiteOS的樹莓派移植過程。

硬件信息

開發板:Raspberry Pi 2 Model B(樹莓派2B)

CPU:Broadcom BCM2836

主頻:900MHz

內存:1GB

GPU:VideoCore IV GPU

移植準備

硬件環境

本實驗使用了Raspberry Pi 2 Model B開發板、USB轉TTL模塊、SDcard和讀卡器。

軟件環境

  • 本實驗需要先按照碼雲上的LiteOS教程搭建好linux環境(make、arm-none-eabi編譯工具鏈)。環境搭建教程:https://gitee.com/LiteOS/LiteOS/blob/master/doc/LiteOS_Build_and_IDE.md
  • 本實驗需要下載官方的鏡像製作工具(Raspberry Pi Imager),下載地址:https://www.raspberrypi.org/software/

移植步驟

創建目錄結構

在targets目錄下新增Raspberry_Pi2B目錄,參考與cortex-A7架構差異較小的realview-pbx-a9的啓動流程進行移植。

  • 將realview-pbx-a9目錄下的reset_vector.S和main.c拷貝到Raspberry_Pi2B目錄下並將reset_vector.S重命名爲los_startup_gcc.S。
  • 將realview-pbx-a9目錄下的board.ld和liteos.ld中內容合併到Raspberry_Pi2B目錄下liteos.ld文件中。
  • 拷貝realview-pbx-a9目錄下include、os_adapt文件夾到Raspberry_Pi2B目錄下,並刪除不需要的dma相關頭文件include/asm/dma.h。

關閉SMP和MMU

在los_startup_gcc.S文件中增加關閉SMP和MMU的代碼。

  • 關閉SMP功能
mrc p15, 0, r0, c1, c0, 1
bic r0, r0, #0x40
mcr p15, 0, r0, c1, c0, 1

上表是ACTLR(Auxiliary Control Register)寄存器bit6功能描述信息,瞭解更多寄存器相關信息可以參考Cortex-A7 MPCore Technical Reference Manual。

  • 關閉MMU的功能
mrc     p15, #0, r0, c1, c0, #0
bic     r0, r0, #1
mcr     p15, #0, r0, c1, c0, #0    @ clear mmu bit

上表是SCTLR (System Control Register)寄存器bit0功能描述信息,瞭解更多寄存器相關信息可以參考Cortex-A7MPCore Technical Reference Manual。

  • 刪除調用SMP相關函數

刪除los_startup_gcc.S中的enable_scu和secondary_cpu_start。

使能FPU/ENON

配置FPU/NEON:

/* enable fpu+neon */
LDR     r0, =(0xF << 20)
MCR     p15, 0, r0, c1, c0, 2
MOV     r3, #0x40000000
VMSR    FPEXC, r3

以上前兩行代碼用於設置CP10和CP11的訪問權限,後兩行用於設置寄存器FPEXC的EN位來使能FPU。

:在arm的協處理器設計中,最多可以支持16個協處理器,通常被命名爲cp0~cp15。

上表爲寄存器CPACR bit20-23功能描述信息,瞭解更多寄存器相關信息可以參考Cortex-A7 MPCore Technical Reference Manual。

修改鏈接腳本

樹莓派啓動時首先加載SD卡中的start.elf文件,該程序會讀取SD卡中的config.txt文件內容,該文件記錄了一些配置信息。如果沒有設置啓動地址和啓動文件,則默認會加載kernel8.img文件,該文件是aarch64編譯的程序,啓動地址爲0x80000。如果SD卡中無kernel8.img鏡像文件,則會加載kernel7.img鏡像文件,該文件是32位編譯器編譯的程序,啓動地址爲0x8000。樹莓派2B的cpu是32位架構,因此設置liteos.ld文件中啓動地址爲0x8000。

棧初始化

樹莓派2B啓動文件los_startup_gcc.S中只設置了SVC模式的sp寄存器,新增cpuInit函數來初始化其他模式的sp指針。如下所示:

VOID cpuInit(VOID)
{
    __asm__ (
    "msr    cpsr_c, %1\n\t"
    "mov    sp,     %0\n\t"
    "msr    cpsr_c, %3\n\t"
    "mov    sp,     %2\n\t"
    "msr    cpsr_c, %5\n\t"
    "mov    sp,     %4\n\t"
    "msr    cpsr_c, %7\n\t"
    "mov    sp,     %6\n\t"
    "msr    cpsr_c, %8\n\t"
        :
        : "r" (__irq_stack_top),
          "I" (PSR_F_BIT | PSR_I_BIT | CPSR_IRQ_MODE),
          "r" (__abt_stack_top),
          "I" (PSR_F_BIT | PSR_I_BIT | CPSR_ABT_MODE),
          "r" (__undef_stack_top),
          "I" (PSR_F_BIT | PSR_I_BIT | CPSR_UNDEF_MODE),
          "r" (__fiq_stack_top),
          "I" (PSR_F_BIT | PSR_I_BIT | CPSR_FIQ_MODE),
          "I" (PSR_F_BIT | PSR_I_BIT | CPSR_SVC_MODE)
        : "r14");
}

配置動態內存地址

#define OS_SYS_MEM_ADDR        ((void *)(&__bss_end))
#define LOS_HEAP_ADDR_END      (void*)(0x0 + 4 * 1024 * 1024)
#define OS_SYS_MEM_SIZE        (UINT32)(((UINT32)LOS_HEAP_ADDR_END - (UINT32)OS_SYS_MEM_ADDR + (64 - 1)) & ~(64 - 1))

以上代碼定義OS_SYS_MEM_ADDR爲動態內存起始地址,LOS_HEAP_ADDR_END爲動態內存結束地址,OS_SYS_MEM_SIZE爲動態內存大小。

串口實現

樹莓派2B原理圖引出了mini_uart串口TXD0、RXD0,對應的引腳爲GPIO14、GPIO15,如下圖所示:

創建usart.c和usart.h文件,在usart.c中編寫串口初始化函數UartInit,並實現uart_debug.c文件中uart_getc、uart_hwiCreate、uart_write接口,實現printf函數從串口輸出。

適配中斷

樹莓派2B的中斷屬於bcm特定的中斷控制器。在drivers/interrupt目錄下新增arm_control.c文件,並在該文件中實現HwiControllerOps結構體內的回調函數。

STATIC const HwiControllerOps g_armControlOps = {
    .enableIrq      = HalIrqUnmask,
    .disableIrq     = HalIrqMask,
    .getCurIrqNum   = HalCurIrqGet,
    .getIrqVersion  = HalIrqVersion,
    .getHandleForm  = HalIrqGetHandleForm,
    .handleIrq      = IrqEntryArmControl,
    .clearIrq       = HalIrqClear,
    .triggerIrq     = HalIrqPending,
};

以上表格是interrupt寄存器偏移地址,讀者想了解詳細寄存器相關信息請參考官方芯片手冊。

適配systick

樹莓派2B通過Timer(arm side)來觸發systick中斷。具體操作細節請參考文件:drivers\timer\rasp_systick.c。

/* systime=250000000 */
timer->preDivider = (OS_SYS_CLOCK / OS_SYS_US_PER_SECOND - 1);
timer->reload   = 0;    
timer->load     = 0;    
timer->IRQClear = 0;    
timer->control  = 0;    
timer->reload   = LOSCFG_BASE_CORE_TICK_PER_SECOND;    
timer->load     = LOSCFG_BASE_CORE_TICK_PER_SECOND;    
/* 23-bit counter, enable interrupt, enable timer */    timer->control = (1 << 1) | (1 << 5) | (1 << 7);    
UINT32 ret = LOS_HwiEnable(ARM_TIMER_INI);

以上代碼配置定時器Timer爲每1ms觸發一次systick中斷。

以上是Timer寄存器偏移地址,讀者想了解詳細寄存器相關信息請參考官方芯片手冊。

配置編譯

在targets目錄下新增kconfig.raspberry文件:

ConfigLOSCFG_PLATFORM
    config LOSCFG_PLATFORM
    string
    default "Raspberry_Pi2B"      if LOSCFG_PLATFORM_Raspberry_Pi2B
choice
    prompt "Board"
    depends on LOSCFG_FAMILY_RASPBERRY
    default LOSCFG_PLATFORM_Raspberry_Pi2B
    help
      Raspberry_Pi2B
config LOSCFG_PLATFORM_Raspberry_Pi2B
    bool "Raspberry_Pi2B"
    select LOSCFG_ARCH_CORTEX_A7
    select LOSCFG_USING_BOARD_LD
    select LOSCFG_PLATFORM_ARM_CONTROL
    select LOSCFG_Raspberry_Pi2B_SYSTICK
endchoice

修改Makefile文件

分別修改以下路徑Makefile(詳情請參考gitee倉庫對應文件):driver/timer/Makefiledriver/interrupt/Makefiletargets/Raspberry_Pi2B/Makefile

添加.img生成指令

在根目錄下Makefile中添加指令$(OBJCOPY) -O binary $(OUT)/[email protected] $(OUT)/kernel7.img,用來將生成的elf文件轉換生成kernel7.img文件。

製作啓動SDcard

  • 使用Raspberry Pi Imager工具製作Raspberry Pi系統。

Raspberry Pi Imager 下載鏈接:https://www.raspberrypi.org/software/

  • 將編譯生成的kernel7.img文件替換掉SDcard中kernel7.img文件。
  • 將寫入鏡像文件的SDcard插入樹莓派2B中並上電,樹莓派2B即可運行LiteOS系統。運行結果如下:
********Hello Huawei LiteOS********
LiteOS Kernel Version : 5.1.0
build data : Jul 13 2021 16:40:42
**********************************
OsAppInit
cpu 0 entering scheduler
app init!
Hello, welcome to liteos demo!
Huawei LiteOS #

至此,LiteOS系統成功啓動和運行。該移植工程已經在Gitee LiteOS社區上線,相關代碼鏈接地址爲:https://gitee.com/LiteOS/LiteOS/tree/master/targets/Raspberry_Pi2B

參考文獻鏈接

[1] Raspberry Pihardware - Raspberry Pi Documentationhttps://www.raspberrypi.org/documentation/hardware/raspberrypi/README.md

[2] 樹莓派官方芯片手冊:

https://datasheets.raspberrypi.org/bcm2835/bcm2835-peripherals.pdf

[3] Cortex-A7 MPCore Technical Reference Manual

https://developer.arm.com/documentation/ddi0464/f?lang=en

 

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章