Hardware Information
Development Board:Raspberry Pi 2 Model B
CPU:Broadcom BCM2836
Clock Speed:900MHz
Memory:1GB
GPU:VideoCore IV GPU
Porting Preparation
-
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
-
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.
-
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
/* 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.
Note:In 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
Adapt Interrupt
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
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);
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!) |
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
-
Add .img generation command
-
Use Raspberry Pi Imager tool to create the Raspberry Pi system.
-
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 #
References Link
[1] Raspberry Pi hardware – Raspberry Pi Documentation:https://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
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.

– End –