Guide to Porting LiteOS on Raspberry Pi

Guide to Porting LiteOS on Raspberry Pi

Guide to Porting LiteOS on Raspberry Pi

Hardware Information

Development BoardRaspberry Pi 2 Model B

CPUBroadcom BCM2836

Clock Speed900MHz

Memory1GB

GPUVideoCore IV GPU

Porting Preparation

Hardware Environment
This experiment uses the Raspberry Pi 2 Model B development board, a USB to TTL module, SD card, and a card reader.
Software Environment
  • This experiment requires setting up the Linux environment (make, arm-none-eabi toolchain) according to the LiteOS tutorial on Gitee. Environment setup tutorial: https://gitee.com/LiteOS/LiteOS/blob/master/doc/LiteOS_Build_and_IDE.md

  • This experiment needs to download the official image creation tool (Raspberry Pi Imager), download link: https://www.raspberrypi.org/software/

Porting Steps

Creating Directory Structure
Add a Raspberry_Pi2B directory under the targets directory, refer to the boot process of realview-pbx-a9 which has minor differences from cortex-A7 architecture for porting.
  • Copy reset_vector.S and main.c from the realview-pbx-a9 directory to the Raspberry_Pi2B directory and rename reset_vector.S to los_startup_gcc.S.

  • Merge the contents of board.ld and liteos.ld from the realview-pbx-a9 directory into the liteos.ld file in the Raspberry_Pi2B directory.

  • Copy the include and os_adapt folders from the realview-pbx-a9 directory to the Raspberry_Pi2B directory, and delete unnecessary DMA-related header files include/asm/dma.h.

Disabling SMP and MMU
Add code to disable SMP and MMU in the los_startup_gcc.S file.
  • Disable SMP Functionality

 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:

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

1:Enables 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.

Note:You 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.

The above table describes the function of ACTLR (Auxiliary Control Register) register bit6, for more information about registers, refer to Cortex-A7 MPCore Technical Reference Manual.

  • Disable MMU Functionality

mrc     p15, #0, r0, c1, c0, #0bic     r0, r0, #1mcr     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:

0:Address translation disabled, this is the reset value.

1:Address translation enabled.

The above table describes the function of SCTLR (System Control Register) register bit0, for more information about registers, refer to Cortex-A7 MPCore Technical Reference Manual.

  • Remove Calls to SMP Related Functions

Remove enable_scu and secondary_cpu_start from los_startup_gcc.S.

Enable FPU/NEON

Configure FPU/NEON:
/* enable fpu+neon */LDR     r0, =(0xF << 20)MCR     p15, 0, r0, c1, c0, 2MOV     r3, #0x40000000VMSR    FPEXC, r3

The above two lines of code are used to set the access permissions for CP10 and CP11, and the last two lines are used to set the FPEXC register’s EN bit to enable FPU.

NoteIn the design of ARM coprocessors, up to 16 coprocessors can be supported, usually named 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, this field is RAZ/WI.

The above table describes the function of CPACR bit20-23 register, for more information about registers, refer to Cortex-A7 MPCore Technical Reference Manual.

Modify Link Script

When the Raspberry Pi starts, it first loads the start.elf file from the SD card, which reads the contents of the config.txt file on the SD card, which records some configuration information. If the boot address and boot file are not set, it defaults to load the kernel8.img file, which is aarch64 compiled program, with a boot address of 0x80000. If there is no kernel8.img image file on the SD card, it will load the kernel7.img image file, which is a program compiled by a 32-bit compiler, with a boot address of 0x8000. The Raspberry Pi 2B’s CPU is 32-bit architecture, so set the boot address in the liteos.ld file to 0x8000.

Stack Initialization

The Raspberry Pi 2B boot file los_startup_gcc.S only sets the sp register in SVC mode, add a cpuInit function to initialize the sp pointers for other modes. As shown below:

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");}

Configure Dynamic Memory Address

#define OS_SYS_MEM_ADDR        ((void *)(&__bss_end))#define LOS_HEAP_ADDR_END      (void*)(0x0 + 4 * 1024 * 1024) /* The first 4MB memory space is used to store liteos code and stack information */#define OS_SYS_MEM_SIZE        (UINT32)(((UINT32)LOS_HEAP_ADDR_END - (UINT32)OS_SYS_MEM_ADDR +  (64 - 1)) & ~(64 - 1)

The above code defines OS_SYS_MEM_ADDR as the starting address of dynamic memory, LOS_HEAP_ADDR_END as the ending address of dynamic memory, and OS_SYS_MEM_SIZE as the size of dynamic memory.

Serial Port Implementation

The Raspberry Pi 2B schematic draws out the mini_uart serial port TXD0, RXD0, corresponding to GPIO14, GPIO15, as shown in the figure below:

Guide to Porting LiteOS on Raspberry Pi

Create usart.c and usart.h files, write the serial port initialization function UartInit in usart.c, and implement uart_debug.c file uart_getc, uart_hwiCreate, uart_write interfaces to output printf function from the serial port.

Adapt Interrupt

The interrupts of Raspberry Pi 2B belong to the bcm specific interrupt controller. Add a arm_control.c file under the drivers/interrupt directory, and implement the callback functions in the HwiControllerOps structure in that file.
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

The above table is the interrupt register offset address, readers who want to learn more about the detailed register information can refer to the official chip manual.

Adaptsystick

The Raspberry Pi 2B triggers the systick interrupt through Timer (arm side). For specific operational details, please refer to the file: drivers imer
asp_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);
The above code configures the Timer to trigger the systick interrupt every 1ms.
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!)
The above is the Timer register offset address, readers who want to learn more about the detailed register information can refer to the official chip manual.

Configure Compilation

  • Add a kconfig.raspberry file under the targets directory:

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
  • Modify the Makefile file

Modify the following paths in the Makefile (details can refer to the corresponding files in the gitee repository):
driver/timer/Makefile
driver/interrupt/Makefile
targets/Raspberry_Pi2B/Makefile
  • Add .img generation command

Add the command $(OBJCOPY) -O binary $(OUT)/[email protected] $(OUT)/kernel7.img in the root Makefile to convert the generated elf file to kernel7.img file.
Creating Boot SD Card
  • Use Raspberry Pi Imager tool to create the Raspberry Pi system.

Guide to Porting LiteOS on Raspberry Pi

Raspberry Pi Imager Download link:https://www.raspberrypi.org/software/
  • Replace the compiled kernel7.img file with the kernel7.img file on the SD card.

  • Insert the SD card with the written image file into Raspberry Pi 2B and power on, the Raspberry Pi 2B can run the LiteOS system. The running result is as follows:

********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 #
At this point, the LiteOS system has successfully started and run. This porting project has been launched on the Gitee LiteOS community, the related code link is:https://gitee.com/LiteOS/LiteOS/tree/master/targets/Raspberry_Pi2B

References Link

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

[2] Raspberry Pi official chip manual:

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

[3] Cortex-A7 MPCore Technical Reference Manual:

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

Conclusion

Thank you for reading, if you have any questions or suggestions, please leave a message for us, let’s improve together:

https://gitee.com/LiteOS/LiteOS/issues

To make it easier to find the “LiteOS” code repository, it is recommended to visithttps://gitee.com/LiteOS/LiteOS, follow “ Watch”, like “Star”, and “Fork” it to your account, as shown in the figure below.

Guide to Porting LiteOS on Raspberry Pi

Guide to Porting LiteOS on Raspberry Pi

– End –

Guide to Porting LiteOS on Raspberry Pi

Leave a Comment

×