Linux与RTOS AMP
一句话结论:RK3576 SoC 支持 AMP(Asymmetric Multi-Processing)异构多核架构,可在 AP 核(Cortex-A72)上运行 Linux,同时在远程核(Cortex-A53,32 位模式)上运行 RT-Thread 或 HAL 裸机程序,通过 RPMsg 共享内存机制实现核间通信。
适用范围
- 适用系统:RK3576 Linux 6.1 SDK + RT-Thread 3.1/4.1(32 位模式)或 HAL 裸机
- 适用硬件:C-3576BQ V10 核心板 + M4-R2(ShimetaPi)底板
- 平台差异说明:RK3576 没有 Cortex-M0 核心,AMP/RTOS 全部运行在 Cortex-A53 核心(32 位模式)上;本文件技术方法来自 Rockchip 官方通用 AMP 指南(标注为参考说明),RK3576 具体寄存器/地址/中断号以实际发布的 RK3576 SDK 为准
前置条件
- 已获取 RK3576 Linux SDK(含 AMP 支持,以实际发布为准)
- 已安装 RT-Thread 开发环境(SCons 构建系统)或 HAL 编译工具链
- 已确认目标硬件平台为 C-3576BQ V10 + M4-R2(ShimetaPi)
1. 概述
1.1 什么是 AMP
AMP(Asymmetric Multi-Processing,异构多处理)是指在同一个 SoC 上,不同处理器核心运行不同的操作系统或裸机程序。与 SMP(Symmetric Multi-Processing,对称多处理)不同,AMP 模式下各核心独立调度,不共享操作系统内核。
RK3576 SoC 的处理器架构(S-02 已验证):
| 核心类型 | 数量 | 最高主频 | 支持的操作系统 |
|---|---|---|---|
| Cortex-A72 (大核) | 4 | 2.2 GHz | Linux Kernel(仅限 Linux) |
| Cortex-A53 (小核) | 4 | 1.8 GHz | Linux、RT-Thread 3.1-32/4.1-32、HAL-32 |
注意:RK3576 无 M0 核(S-02 已验证),AMP/RTOS 全部运行在 Cortex-A53 核心(32 位模式)上,与含 M0 核的 RK3588 方案不同。
1.2 RK3576 AMP 支持模式
RK3576 支持以下 AMP 组合(Rockchip 通用 AMP 方案,适配 RK3576):
| 模式 | 主核(Master Core) | 远程核(Remote Core) | 典型场景 |
|---|---|---|---|
| AP+AP | A72 核心运行 Linux | A53 核心运行 RT-Thread | 通用 AMP 场景 |
| SMP+AMP | 部分 A-cores 运行 Linux SMP | 剩余 A-cores 运行 RT-Thread | 灵活核心分配 |
RK3588 的 AP+MCU(M0)模式在 RK3576 上不适用(无 M0 核)。
关键概念:
- Master Core(主核):运行 Linux 操作系统的核心,通常为 A72 大核
- Remote Core(远程核):运行 RTOS 或裸机程序的核心,通常为 A53 小核
- RPMsg(Remote Processor Messaging):核间通信框架,基于共享内存 + 中断触发机制
1.3 核心支持矩阵
| 处理器核心 | Linux Kernel | RT-Thread 3.1-32 | RT-Thread 4.1-32 | HAL |
|---|---|---|---|---|
| A72 | 支持(仅限) | 不支持 | 不支持 | 不支持 |
| A53 | 支持 | 支持 | 支持 | 支持 |
注意:A72 核心仅支持 Linux Kernel,不支持 RT-Thread 或 HAL。
2. 硬件准备
2.1 硬件清单
| 类别 | 实际名称或版本 | 实际来源路径 | 实际验证状态 |
|---|---|---|---|
| 核心板 | C-3576BQ V10 | 04-硬件资料/0-核心板/ | 已验证 |
| 底板 | M4-R2(ShimetaPi) | 04-硬件资料/1-底板/ | 已验证 |
2.2 AMP 硬件资源
RK3576 AMP 架构涉及以下硬件资源:
- 共享内存区域:用于核间 RPMsg 通信
- 中断控制器:GIC(Generic Interrupt Controller)支持跨核中断
- Mailbox 硬件:可选的核间中断触发源
- 时钟控制器(CRU):各核心独立时钟管理
- 引脚复用(Pin Mux):外设引脚在核心间的分配
3. 软件准备
3.1 SDK 目录结构
RK3576 AMP 开发基于标准 SDK 目录(Rockchip 通用 AMP SDK 结构,以实际发布的 RK3576 SDK 为准):
| 目录 | 用途 |
|---|---|
app/ | 应用层代码 |
device/ | 设备配置文件(含 DTS) |
docs/ | 文档 |
hal/ | 硬件抽象层(HAL) |
kernel-*/ | Linux 内核源码 |
rkbin/ | 二进制工具和固件 |
rtos/ | RTOS 源码(RT-Thread) |
tools/ | 构建工具 |
u-boot/ | U-Boot 引导加载程序 |
uefi/ | UEFI 固件 |
yocto/ | Yocto 构建系统 |
3.2 AMP 配置文件
- defconfig:每个核心的内核配置文件
- ITS 文件:
amp_linux.its:Linux 镜像打包配置amp.its:RTOS 镜像打包配置:RK3576 无 M0 核,不需要 MCU 侧打包配置amp_mcu.its
3.3 构建工具
| 工具 | 用途 | 命令 |
|---|---|---|
| SCons | RT-Thread 构建 | scons -j8 |
| Make | HAL 裸机构建 | make -j8 |
| build.sh | 全量构建 | ./build.sh [选项] |
3.4 构建命令
# 全量构建(交互式选择)
./build.sh
# 可选参数
# chip - 选择芯片型号
# lunch - 选择目标配置
# amp - 构建 AMP 镜像
# uboot - 构建 U-Boot
# kernel - 构建内核
# cleanall - 清理所有构建产物
# 仅构建 RT-Thread
scons -j8
# 仅构建 HAL
make -j8
# 清理所有构建产物
./build.sh cleanall待板上验证:RK3576 的 chip/lunch 具体选项名以实际 RK3576 AMP SDK 为准。
3.5 输出产物
- amp.img:合并后的 AMP 镜像,包含所有核心的固件
- 分区表:嵌入在 amp.img 中,定义各核心内存区域
4. 操作步骤
4.1 步骤 1:Linux 内核 DTS 配置
4.1.1 AMP DTS 头文件
在 Linux 设备树中包含 AMP 配置头文件(文件名为 rk3576-amp.dtsi,以实际 SDK 为准):
/* 在主设备树中包含 AMP DTS 头文件 */
#include "rk3576-amp.dtsi"4.1.2 AMP DTS 头文件内容(参考模板)
/* AMP 中断配置 —— 所有地址/中断号以实际 RK3576 SDK 为准(待板上确认) */
rockchip_amp: rockchip-amp {
compatible = "rockchip,amp";
clocks = <&cru SCLK_AMP>, <&cru PCLK_AMP>;
clock-names = "amp-clk", "amp-pclk";
/* 中断号配置(+32 偏移,具体中断号待板上确认) */
amp-irqs = <GIC_SPI XXX IRQ_TYPE_EDGE_RISING>;
/* CPU 亲和性配置 */
amp-cpu-aff = <0xXX>; /* 仅指定 A53 核心 */
/* 传递给 RTOS 的外设中断 */
interrupts = <GIC_SPI XXX IRQ_TYPE_EDGE_RISING>;
/* 引脚复用配置 */
pinctrl-names = "default";
pinctrl-0 = <&_pin>;
status = "okay";
};
/* AMP 共享内存区域 —— 地址与大小以实际 RK3576 SDK 为准 */
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
/* AMP 共享内存 */
amp@XXXXXXX {
compatible = "shared-dma-pool";
reg = <0x0 0xXXXXXXX 0x0 0xXXXXXXX>; /* 以实际 SDK 为准 */
no-map;
};
/* RPMsg 通信内存 */
rpmsg@XXXXXXX {
compatible = "shared-dma-pool";
reg = <0x0 0xXXXXXXX 0x0 0xXXXXXXX>; /* 以实际 SDK 为准 */
no-map;
};
};4.1.3 关键配置说明
| 配置项 | 说明 |
|---|---|
amp-irqs | 中断号列表,用于 AMP 通信。注意:中断号有 +32 偏移,即硬件 IRQ 号 + 32 = GIC 中断号 |
amp-cpu-aff | CPU 亲和性位掩码,指定 AMP 中断绑定到哪个核心 |
interrupts | 传递给 RTOS 的外设中断列表 |
pinctrl | 引脚复用配置,将外设引脚从 Linux 移交到 RTOS |
reserved-memory | 预留内存区域,Linux 不可访问 |
重要:上述 DTS 中的内存地址、中断号、时钟 ID 均为示例占位符,具体数值以实际发布的 RK3576 SDK 设备树为准(待板上确认),绝不沿用 RK3588 参考值。
4.2 步骤 2:Linux 核心分配
4.2.1 将 A53 核心分配给 RTOS
要将 A53 小核从 Linux 中移除并分配给 RTOS:
- 删除 DTS 中目标 A53 核心节点:
/* 删除以下节点(核心 reg 值以实际 RK3576 设备树为准) */
cpu_xxx: cpu@XXX {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x0 0xXXX>;
enable-method = "psci";
/* cpu-speedbin-hz 等属性以实际 RK3576 设备树为准 */
next-level-cache = <&a53_l2>;
#cooling-cells = <2>;
};- 删除 cpus 节点中对该核心的引用:
cpus {
cpu@000 { ... };
cpu@100 { ... };
/* 删除已分配给 RTOS 的核心节点引用 */
cpu@400 { ... };
cpu@500 { ... };
};效果:删除核心节点后,Linux 调度器将不再管理该核心,该核心可供 RTOS 使用。
4.3 步骤 3:Linux 外设资源移交
将外设从 Linux 移交到 RTOS 的步骤:
4.3.1 禁用 Linux 中的外设
/* 在 Linux DTS 中禁用目标外设(外设名以实际 RK3576 设备树为准) */
&uartx {
status = "disabled"; /* 禁用 UARTx,准备移交到 RTOS */
};4.3.2 添加到 rockchip-amp 节点
rockchip_amp: rockchip-amp {
/* ... 其他配置 ... */
/* 添加要传递给 RTOS 的中断(注意 +32 偏移,中断号待板上确认) */
interrupts = <GIC_SPI XXX IRQ_TYPE_EDGE_RISING>; /* UARTx 中断 */
/* 添加引脚复用配置(以实际 RK3576 引脚为准) */
pinctrl-names = "default";
pinctrl-0 = <&uartx_xfer>;
/* 添加时钟配置(时钟 ID 以实际 RK3576 SDK 为准) */
clocks = <&cru SCLK_UARTx>, <&cru PCLK_UARTx>;
clock-names = "uartx-clk", "uartx-pclk";
};4.3.3 中断号偏移规则
重要:amp-irqs 中的中断号有 +32 偏移。计算公式:
amp-irqs 中断号 = 硬件 IRQ 号 + 32具体外设的硬件 IRQ 号与中断号以实际 RK3576 TRM/设备树为准(待板上确认),此处不列 RK3588 参考值。
4.4 步骤 4:RTOS 侧配置
4.4.1 RT-Thread 板级文件
RT-Thread 的板级配置文件位于(路径以实际 RK3576 AMP SDK 为准):
| 文件路径 | 用途 |
|---|---|
rtos/board/common/board_base.c | 通用板级初始化 |
rtos/board/common/iomux_base.c | 通用引脚复用配置 |
rtos/board/rk3576_xxx/board.c | 板级特定初始化 |
rtos/board/rk3576_xxx/iomux.c | 板级引脚复用配置 |
4.4.2 RT_WEAK 函数覆盖
RT-Thread 使用 RT_WEAK 关键字允许用户覆盖默认实现:
/* 自定义板级初始化 */
RT_WEAK void rt_hw_board_init(void)
{
/* 自定义初始化代码 */
/* ... */
/* 调用 HAL 初始化 */
hal_board_init();
}
/* 自定义引脚复用 */
RT_WEAK void rt_hw_iomux_config(void)
{
/* 自定义引脚配置 */
/* ... */
}4.4.3 内存布局(gcc_arm.ld.S)
RT-Thread 的链接脚本定义了内存布局(地址与长度以实际 RK3576 链接脚本为准):
/* 内存区域定义 —— ORIGIN/LENGTH 以实际 SDK 为准(待板上确认) */
MEMORY
{
SRAM (rw) : ORIGIN = 0xXXXXXXXX, LENGTH = XXXK
DRAM (rwx) : ORIGIN = 0xXXXXXXXX, LENGTH = XXXM
SHMEM (rw) : ORIGIN = 0xXXXXXXXX, LENGTH = XXXM
LINUX_RPMSG (rw) : ORIGIN = 0xXXXXXXXX, LENGTH = XXXM
}
/* RPMsg 共享内存符号 */
__linux_share_rpmsg_start__ = ADDR(.linux_rpmsg);
__linux_share_rpmsg_end__ = SIZEOF(.linux_rpmsg) + ADDR(.linux_rpmsg);4.4.4 中断配置(GIC_AMP_IRQ_INIT_CFG)
/* AMP 中断初始化配置 —— 中断号以实际 RK3576 设备树为准(待板上确认) */
const GIC_AMP_IRQ_INIT_CFG irqsConfig[] =
{
/* UARTx 中断 */
{
.irqNum = XXX, /* amp-irqs 中的中断号 */
.irqType = IRQ_TYPE_EDGE_RISING,
.handler = uartx_irq_handler,
},
/* 表结束标记 */
{ 0, 0, NULL }
};4.4.5 引脚配置(HAL_PINCTRL_SetIOMUX)
/* 引脚复用配置 —— 引脚编号以实际 RK3576 SDK 为准(待板上确认) */
void rt_hw_pinmux_config(void)
{
/* 配置 UARTx 引脚 */
HAL_PINCTRL_SetIOMUX(GPIO_BANKx, /* GPIO 组 */
GPIO_PIN_xx, /* 引脚号 */
IOMUX_FUNCx, /* 功能选择 */
IOMUX_DRIVER_STRENGTH); /* 驱动强度 */
}4.4.6 时钟模块
RT-Thread 内置 CRU(Clock Reset Unit)模块,用于管理时钟(时钟 ID 以实际 RK3576 SDK 为准):
/* 时钟配置示例 */
void rt_hw_clock_init(void)
{
/* 配置 UARTx 时钟源 */
cru_set_sclk_mux(SCLK_UARTx, CLK_SRC_PLL_xxx);
cru_set_div(SCLK_UARTx, 1, 1);
}4.5 步骤 5:核间通信(RPMsg)
4.5.1 RPMsg 通信机制
+------------------+ +------------------+
| Linux (Master) | | RTOS (Remote) |
| A72 Core | | A53 Core |
+------------------+ +------------------+
| |
v v
+------------------------------------------+
| 共享内存区域 (LINUX_RPMSG) |
| 大小: 以实际 SDK 为准 |
+------------------------------------------+
| |
v v
+------------------------------------------+
| 中断触发机制 |
| Mailbox / 软件中断 / SGI |
+------------------------------------------+4.5.2 RPMsg 共享内存符号
/* Linux 侧访问 */
extern char __linux_share_rpmsg_start__;
extern char __linux_share_rpmsg_end__;
/* RTOS 侧访问 */
extern char __linux_share_rpmsg_start__;
extern char __linux_share_rpmsg_end__;4.5.3 中断触发源
| 中断源 | 说明 | 适用场景 |
|---|---|---|
| Mailbox | 硬件 Mailbox 中断 | 核间通信 |
| 软件中断 | 软件触发的中断 | 通用场景 |
| SGI(Software Generated Interrupt) | 软件生成中断 | AP+AP 模式 |
参考说明:RPMsg 框架为标准 AMP 通信方案,RK3576 平台的具体中断号和共享内存地址需以设备树和实际配置为准(待板上确认)。
4.6 步骤 6:构建与烧录
4.6.1 构建流程
# 1. 进入 SDK 根目录
cd /path/to/rk3576_sdk
# 2. 清理旧构建产物
./build.sh cleanall
# 3. 全量构建(交互式选择 AMP 配置)
./build.sh
# 或指定 AMP 构建
./build.sh amp
# 4. 仅构建 RT-Thread
cd rtos/
scons -j8
# 5. 仅构建 HAL
cd rtos/
make -j84.6.2 输出产物
构建完成后,输出以下文件:
| 文件 | 说明 |
|---|---|
amp.img | 合并后的 AMP 镜像,包含所有核心固件 |
amp_linux.itb | Linux 镜像 |
amp.itb | RT-Thread 镜像 |
amp_mcu.itb | RK3576 无 M0 核,不生成 MCU 镜像 |
4.6.3 烧录方式
# 使用 rkdevtool / RKDevTool 烧录 amp.img(以实际烧录工具为准)
rkdevtool amp.img待板上验证:amp.img 的具体烧录方法与分区布局需在目标板上验证,详见系统烧录指南。
5. 代码详解
5.1 Linux 侧 AMP 驱动(rockchip_amp.c)
Linux AMP 驱动的核心功能(Rockchip 通用实现,参考说明):
/* 驱动探测函数 */
static int rockchip_amp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rockchip_amp *amp;
/* 1. 解析设备树属性 */
amp = devm_kzalloc(dev, sizeof(*amp), GFP_KERNEL);
/* 2. 获取预留内存 */
amp->reserved_mem = of_reserved_mem_region(dev->of_node);
/* 3. 配置中断 */
rockchip_amp_config_irq(amp);
/* 4. 配置引脚复用 */
rockchip_amp_config_pinctrl(amp);
/* 5. 配置时钟 */
rockchip_amp_config_clocks(amp);
return 0;
}5.2 RT-Thread 启动流程
rt_hw_board_init()
|
+---> rt_hw_clock_init() // 时钟初始化
|
+---> rt_hw_pinmux_config() // 引脚复用配置
|
+---> rt_hw_iomux_config() // I/O 复用配置
|
+---> rt_hw_gic_amp_init() // GIC AMP 中断初始化
|
+---> rt_system_timer_init() // 系统定时器初始化
|
+---> rt_system_heap_init() // 堆内存初始化
|
+---> rt_application_init() // 应用初始化
|
+---> rt_thread_startup() // 线程启动5.3 RPMsg 通信协议栈
+------------------------------------------+
| 用户应用程序 |
+------------------------------------------+
| RPMsg 框架 |
+------------------------------------------+
| 共享内存层 |
| (LINUX_RPMSG) |
+------------------------------------------+
| 中断触发层 |
| (Mailbox / SGI) |
+------------------------------------------+
| GIC 中断控制器 |
+------------------------------------------+5.4 内存布局图
RK3576 AMP 内存布局(基于 4GB LPDDR5,具体地址以实际 RK3576 链接脚本为准,待板上确认):
+------------------------------------------+ 0x000000000
| SRAM (片上 SRAM) | 保留区域
+------------------------------------------+ 0xXXXXXXXX
| 系统保留区域 |
+------------------------------------------+ 0xXXXXXXXX
| AMP 共享内存 |
| amp@XXXXXXX |
+------------------------------------------+ 0xXXXXXXXX
| RPMsg 通信内存 |
| LINUX_RPMSG |
+------------------------------------------+ 0xXXXXXXXX
| Linux 内核区域 |
+------------------------------------------+ 0xXXXXXXXX
| 剩余 DDR 区域 |
+------------------------------------------+ 0xXXXXXXXX待板上验证:各内存区域的具体起始地址和长度以 RK3576 实际链接脚本与设备树为准,需保证 Linux DTS 的 reserved-memory 与 RTOS 链接脚本一致。
6. 常见问题
6.1 RTOS 无法启动
| 现象 | 已确认原因 | 处理方法 | 来源路径 | 状态 |
|---|---|---|---|---|
| RTOS 启动后立即复位 | 内存区域配置错误 | 检查 DTS 中 reserved-memory 地址和大小是否与链接脚本一致 | Rockchip_Developer_Guide_AMP_CN.pdf | 待板上验证 |
6.2 核间通信失败
| 现象 | 已确认原因 | 处理方法 | 来源路径 | 状态 |
|---|---|---|---|---|
| RPMsg 消息收不到 | 共享内存地址不匹配 | 检查 Linux DTS 和 RTOS 链接脚本中的 RPMsg 地址是否一致 | Rockchip_Developer_Guide_AMP_CN.pdf | 待板上验证 |
| 中断未触发 | 中断号配置错误 | 验证 amp-irqs 中断号是否正确(注意 +32 偏移) | Rockchip_Developer_Guide_AMP_CN.pdf | 待板上验证 |
6.3 外设无法使用
| 现象 | 已确认原因 | 处理方法 | 来源路径 | 状态 |
|---|---|---|---|---|
| RTOS 访问外设异常 | 引脚未正确移交 | 检查 Linux DTS 中外设是否设置 status="disabled",且 pinctrl 已添加到 rockchip-amp 节点 | Rockchip_Developer_Guide_AMP_CN.pdf | 待板上验证 |
| 时钟未配置 | 时钟未正确初始化 | 检查 RTOS 时钟配置是否与 Linux DTS 中 clocks 属性一致 | Rockchip_Developer_Guide_AMP_CN.pdf | 待板上验证 |
6.4 构建问题
| 现象 | 已确认原因 | 处理方法 | 来源路径 | 状态 |
|---|---|---|---|---|
| SCons 构建失败 | RT-Thread 源码未正确配置 | 检查 rtos/ 目录下的 SCONS 构建文件是否完整 | Rockchip_Developer_Guide_AMP_CN.pdf | 待板上验证 |
| amp.img 生成失败 | ITS 文件配置错误 | 检查 amp_linux.its、amp.its 中的镜像路径是否正确 | Rockchip_Developer_Guide_AMP_CN.pdf | 待板上验证 |
7. 相关文档
| 文档 | 说明 |
|---|---|
| RT-Thread环境与工程入口 | AMP 架构、SDK 目录、构建流程入口 |
| BSP与启动 | RT-Thread BSP 配置与启动流程详解 |
| 调试与日志 | RTOS 调试与日志方法 |
| 故障排除 | RTOS 常见问题与故障排除 |
| RTOS与Linux协同 | Linux 侧 RTOS 协同开发 |
| 核心板参数 | 硬件事实基线(RK3576 无 M0 核、核心配置) |
| 系统烧录指南 | 烧录工具与 LOADER 模式 |
