乐趣区

关于物联网:手把手带你做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/Lite…
  • 本试验须要下载官网的镜像制作工具(Raspberry Pi Imager),下载地址:https://www.raspberrypi.org/s…

移植步骤

创立目录构造

在 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 寄存器偏移地址,读者想理解具体寄存器相干信息请参考官网芯片手册。

适配 zhongduan

树莓派 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)/$@.elf $(OUT)/kernel7.img,用来将生成的 elf 文件转换生成 kernel7.img 文件。

制作启动 SDcard

  • 应用 Raspberry Pi Imager 工具制作 Raspberry Pi 零碎。

Raspberry Pi Imager 下载链接:https://www.raspberrypi.org/s…

  • 将编译生成的 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/Lite…

参考文献链接

[1] Raspberry Pihardware – Raspberry Pi Documentation:https://www.raspberrypi.org/d…

[2] 树莓派官网芯片手册:

https://datasheets.raspberryp…

[3] Cortex-A7 MPCore Technical Reference Manual:

https://developer.arm.com/doc…

点击关注,第一工夫理解华为云陈腐技术~

退出移动版