写点什么

手把手带你做 LiteOS 的树莓派移植

发布于: 刚刚

摘要:树莓派是英国的慈善组织“Raspberry Pi 基金会”开发的一款基于 arm 的微型电脑主板。本文介绍基于 LiteOS 的树莓派移植过程。


本文分享自华为云社区《2021 LiteOS树莓派移植指南(一)》,作者:  Lionlace 。

硬件信息


开发板:Raspberry Pi 2 Model B(树莓派 2B) 

CPU:Broadcom BCM2836

主频:900MHz

内存:1GB

GPU:VideoCore IV GPU

移植准备


硬件环境

本实验使用了 Raspberry Pi 2 Model B 开发板、USB 转 TTL 模块、SDcard 和读卡器。


软件环境

移植步骤


创建目录结构

在 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, 1bic r0, r0, #0x40mcr 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) /* 前4MB内存空间用来存放liteos的代码及堆栈信息 */#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 文件:


config LOSCFG_PLATFORM    string    default "Raspberry_Pi2B"      if LOSCFG_PLATFORM_Raspberry_Pi2Bchoice    prompt "Board"    depends on LOSCFG_FAMILY_RASPBERRY    default LOSCFG_PLATFORM_Raspberry_Pi2B    help      Raspberry_Pi2Bconfig 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_SYSTICKendchoice
复制代码


  • 修改 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/software/

  • 将编译生成的 kernel7.img 文件替换掉 SDcard 中 kernel7.img 文件。

  • 将写入镜像文件的 SDcard 插入树莓派 2B 中并上电,树莓派 2B 即可运行 LiteOS 系统。运行结果如下:


********Hello Huawei LiteOS********LiteOS Kernel Version : 5.1.0build data : Jul 13 2021 16:40:42**********************************OsAppInitcpu 0 entering schedulerapp 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 Documentation:https://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

 

点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 2
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
手把手带你做LiteOS的树莓派移植