LiteOS 树莓派移植指南(一)

Lionlace 发表于 2021/10/11 10:03:50 2021/10/11
【摘要】 树莓派是英国的慈善组织“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。

关闭SMPMMU

在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

[6]

SMP

Enables coherent requests to the processor:

0Disables coherent requests to the processor. This is the reset value.

1Enables coherent requests to the processor.

When coherent requests are disabled:

loads to cacheable memory are not cached by the processor.

Load-Exclusive instructions take a precise abort if the memory attributes are:

Inner Write-Back and Outer Shareable.

Inner Write-Through and Outer Shareable.

Outer Write-Back and Outer Shareable.

Outer Write-Through and Outer Shareable.

Inner Write-Back and Inner Shareable.

Inner Write-Through and Inner Shareable.

Outer Write-Back and Inner Shareable.

Outer Write-Through and Inner Shareable.

NoteYou must ensure this bit is set to 1 before the caches and MMU are enabled, or any cache and TLB maintenance operations are performed. The only time this bit is set to 0 is during a processor power-down sequence. See Power management.

上表是ACTLRAuxiliary 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

[0]

M

Address translation enable bit. This is a global enable bit for the MMU stage 1 address translation:

0Address translation disabled, this is the reset value.

1Address translation enabled.

上表是SCTLR System Control Register寄存器bit0功能描述信息,了解更多寄存器相关信息可以参考Cortex-A7MPCore Technical Reference Manual

删除调用SMP相关函数

删除los_startup_gcc.S中的enable_scusecondary_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

以上前两行代码用于设置CP10CP11的访问权限,后两行用于设置寄存器FPEXCEN位来使能FPU

:在arm的协处理器设计中,最多可以支持16个协处理器,通常被命名为cp0~cp15。

[23:22]

cp11

Defines the access rights for coprocessor 11:

0b00:Access denied. Attempted accesses generate an Undefined Instruction exception. This is the reset value.

0b01:Access at PL1 or higher only.Attempted accesses in User mode generate an Undefined Instruction exception.Any attempt to access the coprocessor from software executing at PL0 generates an Undefined Instruction exception.

0b10:Reserved. The effect of this value is unpredictable.

0b11:Full access.

If FPU and Advanced SIMD are not implemented, this field is RAZ/WI.

[21:20]

cp10

Defines the access rights for coprocessor 10:

0b00:Access denied. Attempted accesses generate an Undefined Instruction exception. This is the reset value.

0b01:Access at PL1 or higher only. Any attempt to access the coprocessor from software executing at PL0 generates an Undefined Instruction exception.

0b10:Reserved. The effect of this value is unpredictable.

0b11:Full access.

If FPU and Advanced SIMD are not implemented, thisfield is RAZ/WI.

上表为寄存器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树莓派2Bcpu32位架构,因此设置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.cusart.h文件,在usart.c中编写串口初始化函数UartInit,并实现uart_debug.c文件中uart_getcuart_hwiCreateuart_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,
};

Address offset

Name

0x200

IRQ basic pending

0x204

IRQ pending 1

0x208

IRQ pending 2

0x20C

FIQ control

0x210

Enable IRQs 1

0x214

Enable IRQs 2

0x218

Enable Basic IRQs

0x21C

Disable IRQs 1

0x220

Disable IRQs 2

0x224

Disable Basic IRQs

以上表格是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中断。

Address offset

Description

0x400

Load

0x404

Value (Read Only)

0x408

Control

0x40C

IRQ Clear/Ack (Write only)

0x410

RAW IRQ (Read Only)

0x414

Masked IRQ (Read Only)

0x418

Reload

0x41C

Pre-divider (Not in real 804!)

0x420

Free running counter (Not in real 804!)

以上是Timer寄存器偏移地址,读者想了解详细寄存器相关信息请参考官方芯片手册。


配置编译

targets目录下新增kconfig.raspberry文件:

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/software/

将编译生成的kernel7.img文件替换掉SDcardkernel7.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


结语


感谢您的阅读,有任何问题、建议,都可以留言给我们,让我们一起进步:  https://gitee.com/LiteOS/LiteOS/issues

为了更容易找到“LiteOS”代码仓,建议访问https://gitee.com/LiteOS/LiteOS,关注Watch点赞Star、并Fork到自己账号下,如下图。

0 (1).png




【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。