[bsp][zynqmp] 为 DFZU2EG MPSoC 开发板支持标准版和Smart版内核 (#8773)

zynqmp support RT-Thread  and RT-smart
This commit is contained in:
liYangYang
2024-04-16 22:53:59 -04:00
committed by Meco Man
parent fcad5e16d7
commit ea1ab21051
20 changed files with 2701 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+34
View File
@@ -0,0 +1,34 @@
mainmenu "RT-Thread Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../../"
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
config SOC_ZYNQMP_AARCH64
bool
select ARCH_ARMV8
select ARCH_CPU_64BIT
select ARCH_ARM_MMU
select RT_USING_CACHE
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select RT_USING_GIC
select BSP_USING_GIC
select ARCH_MM_MMU
default y
source "$BSP_DIR/drivers/Kconfig"
+157
View File
@@ -0,0 +1,157 @@
# DFZU2EG MPSoC 板级支持包说明
## 1. 简介
正点原子 DFZU2EG MPSoC 开发板采用Xilinx的Zynq UltraScale+ MPSoC芯片作为主控芯片。它主要分为PS和PL两部分,在PS部分中主要由Arm Cortex A53(APU 共4个核)、Arm Cortex R5F(RPU 共两个核)以及Arm Mali 400 MP2(GPU)三种内核处理器构成,并且还包括DDR 控制单元、平台管理单元、高速外设控制器以及普通外设控制器等外设组成。
该板级支持包主要是针对APU做的一份移植,支持RT-Thread标准版和Smart版内核。
DFZU2EG MPSoC 开发板的详细资源信息可以查阅正点原子此开发板的相关手册,也可以参考下图:
![2eg_mpsoc_board](figures/2eg_mpsoc_board.png)
## 2. 编译说明
推荐使用ubuntu20的[env环境](https://github.com/RT-Thread/env),当然也可以使用windows上的[env工具](https://www.rt-thread.org/download.html#download-rt-thread-env-tool)进行编译。下面介绍**标准版**和**Smart版本**的编译流程。
### 2.1 RT-Thread编译
**1.menuconfig配置工程:**
该BSP默认menuconfig支持的就是RT-Thread标准版,无需配置工程。
**2.配置工具链相关环境:**
依次执行下面命令进行环境变量的相关配置:
```shell
export RTT_CC=gcc
export RTT_EXEC_PATH="/opt/tools/gnu_gcc/arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-elf/bin"
export RTT_CC_PREFIX=aarch64-none-elf-
export PATH=$PATH:$RTT_EXEC_PATH
```
**3.编译:**
```shell
scons -j12
```
### 2.2 RT-Smart编译
**1.menuconfig配置工程:**
```shell
RT-Thread Kernel --->
[*] Enable RT-Thread Smart (microkernel on kernel/userland)
```
**2.配置工具链相关环境:**
依次执行下面命令进行环境变量的相关配置:
```shell
export RTT_CC=gcc
export RTT_EXEC_PATH="/opt/tools/gnu_gcc/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu/bin"
export RTT_CC_PREFIX=aarch64-linux-musleabi-
export PATH=$PATH:$RTT_EXEC_PATH
```
**3.编译:**
```shell
scons -j12
```
如果编译正确无误,会产生 `rtthread.elf`, `rtthread.bin` 文件。
## 3. 环境搭建
### 3.1 准备好串口线
连线情况如下图所示:
![2eg_mpsoc_uart](figures/2eg_mpsoc_uart.png)
串口参数: 115200 8N1 ,硬件和软件流控为关。
### 3.2 RTT固件放在SD卡运行
暂时不支持,需要使用 u-boot 加载。
### 3.3 RTT程序用uboot加载
需要注意的以下问题:
- 保证开发板和保存固件的PC机处于同一网段,互相可以ping通。
- 保证PC机已经成功配置TFTP的相关服务。
可以使用开发板出厂自带的uboot(EMMC)来加载RTT程序,将网线连接到开发板的PS网口,然后在uboot控制台输入下列命令:
```shell
setenv ipaddr 192.168.1.50
setenv ethaddr b8:ae:1d:01:00:00
setenv gatewayip 192.168.1.1
setenv netmask 255.255.255.0
setenv serverip 192.168.1.3
tftpboot 0x00200000 rtthread.bin
go 0x00200000
```
其中`192.168.1.3`为TFTP服务器的PC机的IP地址,大家可以根据自己的实际情况进行修改。
执行完上述命令后,uboot就可以自动从tftp服务器上获取固件,然后开始执行了。
完成后可以看到串口的输出信息:
**标准版log信息:**
```shell
heap: [0x00299540 - 0x04000000]
\ | /
- RT - Thread Operating System
/ | \ 5.1.0 build Apr 11 2024 11:43:19
2006 - 2024 Copyright by RT-Thread team
hello rt-thread
msh />
```
**Smart版log信息:**
```shell
heap: [0x002fd030 - 0x04000000]
\ | /
- RT - Thread Smart Operating System
/ | \ 5.1.0 build Apr 11 2024 11:47:02
2006 - 2024 Copyright by RT-Thread team
Press any key to stop init process startup ... 3
Press any key to stop init process startup ... 2
Press any key to stop init process startup ... 1
Starting init ...
[E/lwp] lwp_startup: init program not found
Switching to legacy mode...
hello rt-thread
msh />
```
## 4. 支持情况
| 驱动 | 支持情况 | 备注 |
| ------ | ---- | :------: |
| UART | 支持 | UART0 |
| GPIO | 暂不支持 | - |
| SPI | 暂不支持 | - |
| SDIO | 暂不支持 | - |
| ETH | 暂不支持 | - |
目前BSP仅保证成功运行,驱动后续会慢慢支持!
## 5. 注意事项
对于ZYNQ的开发,需要使用Vivado软件对开发板的硬件进行一些配置,来生产相应的fsbl.elf文件,比如串口引脚的初始化等等,所以如果大家需要修改串口的输出引脚信息,需要更新fsbl.elf,而这些知识是需要具备一定的ZYNQ开发基础的。
## 6. 联系人信息
维护人:[liYony](https://github.com/liYony)
+14
View File
@@ -0,0 +1,14 @@
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
+44
View File
@@ -0,0 +1,44 @@
import os
import sys
import rtconfig
import re
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.join(os.getcwd(), '..', '..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
TRACE_CONFIG = ""
content = ""
with open("rtconfig.h") as f:
for line in f.readlines():
if line.find("RT_BACKTRACE_FUNCTION_NAME") != -1:
for token in line.split(" "):
if re.match(r'RT_BACKTRACE_FUNCTION_NAME$', token, flags=0):
TRACE_CONFIG = " "
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS + TRACE_CONFIG,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS + TRACE_CONFIG,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS + TRACE_CONFIG,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env['ASCOM'] = env['ASPPCOM']
env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group'
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT)
# make a building
DoBuilding(TARGET, objs)
@@ -0,0 +1,9 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020/10/7 bernard the first version
*/
#include <rtthread.h>
int main(void)
{
rt_kprintf("hello rt-thread\n");
return 0;
}
+32
View File
@@ -0,0 +1,32 @@
menu "Hardware Drivers Config"
config BSP_SUPPORT_FPU
bool "Using Float"
default y
menuconfig BSP_USING_UART
bool "Using UART"
select RT_USING_SERIAL
default y
if BSP_USING_UART
config BSP_USING_UART0
bool "Enabel UART 0"
default y
endif
config BSP_USING_GIC
bool
default y
choice
prompt "GIC Version"
default BSP_USING_GICV2
config BSP_USING_GICV2
bool "GICv2"
config BSP_USING_GICV3
bool "GICv3"
endchoice
endmenu
+11
View File
@@ -0,0 +1,11 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd , cwd + '/zynqmp']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-04-11 liYony the first version
*/
#include <mmu.h>
#include <board.h>
#include <mm_aspace.h>
#include <mm_page.h>
#include <drv_uart.h>
#include <gtimer.h>
extern size_t MMUTable[];
#ifdef RT_USING_SMART
struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x7FF00000 - 1, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM}
};
#else
struct mem_desc platform_mem_desc[] =
{
{0x00200000, 0x7FF00000 - 1, 0x00200000, NORMAL_MEM},
{GIC400_DISTRIBUTOR_PPTR, GIC400_DISTRIBUTOR_PPTR + GIC400_SIZE - 1, GIC400_DISTRIBUTOR_PPTR, DEVICE_MEM},
{GIC400_CONTROLLER_PPTR, GIC400_CONTROLLER_PPTR + GIC400_SIZE - 1, GIC400_CONTROLLER_PPTR, DEVICE_MEM},
};
#endif
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]);
void idle_wfi(void)
{
asm volatile("wfi");
}
void rt_hw_board_init(void)
{
#ifdef RT_USING_SMART
rt_hw_mmu_map_init(&rt_kernel_space, (void *)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
#else
rt_hw_mmu_map_init(&rt_kernel_space, (void *)0xffffd0000000, 0x10000000, MMUTable, 0);
#endif
rt_region_t init_page_region;
init_page_region.start = PAGE_START;
init_page_region.end = PAGE_END;
rt_page_init(init_page_region);
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
#ifdef RT_USING_HEAP
/* initialize system heap */
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
/* initialize hardware interrupt */
rt_hw_interrupt_init();
/* initialize uart */
rt_hw_uart_init();
/* initialize timer for os tick */
rt_hw_gtimer_init();
rt_thread_idle_sethook(idle_wfi);
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
rt_kprintf("heap: [0x%08x - 0x%08x]\n", HEAP_BEGIN, HEAP_END);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-04-11 liYony the first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <zynqmp.h>
extern unsigned char __bss_end;
#define HEAP_BEGIN ((void*)&__bss_end)
#ifdef RT_USING_SMART
#define HEAP_END ((size_t)KERNEL_VADDR_START + 64 * 1024 * 1024)
#define PAGE_START HEAP_END
#define PAGE_END ((size_t)KERNEL_VADDR_START + 128 * 1024 * 1024)
#else
#define KERNEL_VADDR_START 0x0
#define HEAP_END (KERNEL_VADDR_START + 64 * 1024 * 1024)
#define PAGE_START HEAP_END
#define PAGE_END ((size_t)PAGE_START + 64 * 1024 * 1024)
#endif
void rt_hw_board_init(void);
int rt_hw_uart_init(void);
#endif /* __BOARD_H__ */
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-04-11 liYony the first version
*/
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include <rtthread.h>
int rt_hw_uart_init(void);
#endif /* __DRV_UART_H__ */
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-04-11 liYony the first version
*/
#ifndef __ZYNQMP_H__
#define __ZYNQMP_H__
#include <rtdef.h>
#include <ioremap.h>
#ifdef RT_USING_SMART
#include <mmu.h>
#endif
#define __REG32(x) (*((volatile unsigned int *)(x)))
#define __REG16(x) (*((volatile unsigned short *)(x)))
/* UART */
#define ZYNQMP_UART0_BASE 0xFF000000
#define ZYNQMP_UART0_SIZE 0x00010000
#define ZYNQMP_UART0_IRQNUM (32 + 21)
#define ZYNQMP_UART0_CLK_FREQ_HZ (99999001)
/* GIC */
#define MAX_HANDLERS 195
#define GIC_IRQ_START 0
#define ARM_GIC_NR_IRQS 195
#define ARM_GIC_MAX_NR 1
/* GICv2 */
#define GIC400_DISTRIBUTOR_PPTR 0xF9010000U
#define GIC400_CONTROLLER_PPTR 0xF9020000U
#define GIC400_SIZE 0x00001000U
/* the basic constants and interfaces needed by gic */
rt_inline rt_ubase_t platform_get_gic_dist_base(void)
{
return GIC400_DISTRIBUTOR_PPTR;
}
rt_inline rt_ubase_t platform_get_gic_cpu_base(void)
{
return GIC400_CONTROLLER_PPTR;
}
#endif /* __ZYNQMP_H__ */
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ZYNQMP_REG_H__
#define __ZYNQMP_REG_H__
/* bit field helpers. */
#define __M(n) (~(~0<<(n)))
#define __RBF(number, n) ((number)&__M(n))
#define __BF(number, n, m) __RBF((number>>m), (n-m+1))
#define REG_BF(number, n, m) (m<n ? __BF(number, n, m) : __BF(number, m, n))
#define readb(reg) (*((volatile unsigned char *)(reg)))
#define readw(reg) (*((volatile unsigned short *)(reg)))
#define readl(reg) (*((volatile unsigned int *)(reg)))
#define readq(reg) (*((volatile unsigned long long *)(reg)))
#define writeb(data, reg) ((*((volatile unsigned char *)(reg))) = (unsigned char)(data))
#define writew(data, reg) ((*((volatile unsigned short *)(reg))) = (unsigned short)(data))
#define writel(data, reg) ((*((volatile unsigned int *)(reg))) = (unsigned int)(data))
#define writeq(data, reg) ((*((volatile unsigned long long *)(reg))) = (unsigned long long)(data))
#define clrsetreg(addr, clr, set) writel(((clr) | (set)) << 16 | (set), addr)
#define clrreg(addr, clr) writel((clr) << 16, addr)
#define setreg(addr, set) writel((set) << 16 | (set), addr)
#define DUMP_REG(base, reg) \
do { \
rt_uint32_t status = 0x00000000; \
status = readl(base + reg); \
rt_kprintf(#reg ":\n"); \
rt_kprintf("\t%p 0x%.8x\n", base + reg, status); \
} while(0);
#endif /* __ZYNQMP_REG_H__ */
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 KiB

File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
import os
# toolchains options
ARCH ='aarch64'
CPU ='cortex-a'
CROSS_TOOL = 'gcc'
PLATFORM = 'gcc'
EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
BUILD = 'debug'
if PLATFORM == 'gcc':
# toolchains
PREFIX = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
CC = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
CPP = PREFIX + 'cpp'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
STRIP = PREFIX + 'strip'
CFPFLAGS = ' '
AFPFLAGS = ' '
DEVICE = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing'
CPPFLAGS= ' -E -P -x assembler-with-cpp'
CXXFLAGS= DEVICE + CFPFLAGS + ' -Wall -fdiagnostics-color=always'
CFLAGS = DEVICE + CFPFLAGS + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always'
AFLAGS = ' -c' + AFPFLAGS + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + ' -lsupc++ -lgcc -static'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2'
CXXFLAGS += ' -O0 -gdwarf-2'
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -Os'
CXXFLAGS += ' -Os'
CXXFLAGS += ' -Woverloaded-virtual -fno-exceptions -fno-rtti'
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'