当前,多核处理器已广泛应用于各行各业,嵌入式领域也不例外。本文将基于瑞萨RZ/T2H MPU,深入探讨其在多轴控制与驱动场景下的多核异构应用方案。
本例程运行于RZ/T2H硬件平台,该平台包含两个Cortex-R52实时核和四个Cortex-A55应用核。在该架构中:Cortex-A55核运行Linux操作系统及EtherCAT主站软件;Cortex-R52核1运行EtherCAT从站协议栈,负责与主站进行9轴控制/状态数据的实时交互;Cortex-R52核2则专门负责9轴电机的驱动程序。
基础架构

图一 多核异构的软硬件框架
- EtherCAT 主站:位于CA55 Linux侧,运行CODESYS RUNTIME(EtherCAT Master),负责上位机通信控制,包括EtherCAT主站通信、电机控制指令下发及现场数据采集等。
- EtherCAT 从站:位于CR52_1核,运行EtherCAT从站协议栈,执行EtherCAT数据帧处理与设备对象管理。其运行在裸机环境中,以确保最高的实时性。CA55端的ECAT主站与CR52_1端的ECAT从站通过内部端口直连,数据流无需经过外部网络回环。
- 电机驱动:位于CR52_0核,负责伺服电机驱动(如多轴机器人控制),其功能包括PWM计算与输出、编码器反馈数据采集、电流环/速度环/位置环计算等,同样运行于裸机环境以保证实时性能。
整个数据流路径如下:运行于CA55的CODESYS RUNTIME通过EtherCAT协议向CR52_1发送控制数据,CR52_1解析后通过共享内存转发给CR52_0,CR52_0最终控制外设驱动电机。反之,电机的实时状态数据由CR52_0采集,经由共享内存传递至CR52_1,再通过EtherCAT协议回传至主站。
CA55端使用OpenAMP的RemoteProc启动R52核

图二 remoteProc启动CR52_0和CR52_1
在Linux侧,通过RemoteProc框架来加载并启动运行在R52核上的裸机固件。相关驱动代码位于 /sources/linux-renesas/drivers/remoteproc/rz_rproc.c。
操作结构体
rz_rproc_ops 是一个 struct rproc_ops 类型的结构体,它定义了远程处理器(remoteproc)的核心操作函数集,在驱动探测时被注册。
rproc = devm_rproc_alloc(dev, np->name, &rz_rproc_ops, NULL, sizeof(*pdata));
该结构体包含的关键操作函数有:
prepare:准备远程处理器资源。
start:启动远程处理器。
stop:停止远程处理器。
da_to_va:执行设备地址到虚拟地址的转换,用于A55核访问R52核的地址空间。
parse_fw:解析固件。
驱动加载与启动流程
驱动通过设备树匹配 compatible="renesas,rz-cr52" 进行加载。当用户通过sysfs写入固件名并执行启动命令时,内核会触发一系列调用链:
# 加载固件
echo gcc_rzn2h_cr52_0_rpmsg_linux_baremetal_demo.elf > /sys/class/remoteproc/remoteproc0/firmware
# 启动远程处理器
echo start > /sys/class/remoteproc/remoteproc0/state
执行 start 命令后,内核调用链大致为:rproc_boot() -> rz_rproc_prepare() -> request_firmware() -> rz_rproc_parse_fw() -> rz_rproc_start()。
设备树配置分析
设备树节点中定义了关键资源,例如内存区域(SRAM, DDR)、核间通信使用的预留缓冲区(vring/buffer),以及处理器特定的参数。
renesas,rz-core = <0x0>; // 指定CR52核编号(0或1)
renesas,rz-swint = <10>; // 使用的软中断通道
renesas,rz-start_address = <0x00000000>; // 固件加载的起始地址
注意:renesas,rz-start_address 必须与固件编译时指定的链接地址一致。例如,CR52_0的启动地址常设为0x00000000,而CR52_1可能为0x10061000。
启动函数实现简析
在 rz_rproc_start() 函数中,主要完成以下工作:
- 映射并配置电源控制寄存器(PRCRS/PRCRN),使能相关功能。
- 通过
ioremap建立CA55核访问R52核内存(如ATCM, BTCM, SRAM)的地址映射。这些映射关系在芯片手册中有明确说明。
- 将编译好的固件(firmware)拷贝到R52核对应的内存区域。
- 通过写入特定的复位控制寄存器(如SWRCPU0)的值来释放并对R52核进行复位,随后该核便开始执行固件代码。
一个典型的启动脚本如下:
# 指定固件
echo CR52_0_motor.elf > /sys/class/remoteproc/remoteproc0/firmware
echo CR52_1_ECAT.elf > /sys/class/remoteproc/remoteproc1/firmware
# 启动远程核
echo start > /sys/class/remoteproc/remoteproc0/state
echo start > /sys/class/remoteproc/remoteproc1/state
CR52_0 与 CR52_1 之间的数据共享
这两个实时核之间通过共享内存进行高速数据交换,辅以核间中断实现同步,从而传递电机控制参数与状态信息。这里利用了瑞萨FSP(Flexible Software Package)提供的 r_shared_memory 驱动模块。

图四 CR52_0与CR52_1之间的数据共享
数据传输流程
- 发送方(CR52_1):使用SHARED_MEMORY API将结构化的控制数据写入到双方共享的内存区域。为提升效率,通常只在数据实际发生变化时才执行写入操作。写入完成后,CR52_1触发一个核间中断通知CR52_0。
- 接收方(CR52_0):在收到核间中断后,中断服务例程被触发,CR52_0从共享内存区读取最新数据。读取完成后,会在回调函数中设置一个软件标志位,通知主循环数据处理完成。

图五 数据共享的消息序列图
在RZ/T2H芯片自带的2MB系统SRAM中,为CR52_0和CR52_1之间的数据共享预留了1.5KB的空间,其地址映射关系如图六所示。通过精细的中断和共享内存管理,可以构建高效的实时控制系统,这也是实现复杂网络/系统间通信的基础。

图六 数据共享地址
RZ/T2H 多核启动顺序

图七 T2H多核启动顺序
RZ/T2H上电后的启动流程是一个多阶段的过程:
- BootROM:系统上电后,首先执行芯片内部的BootROM代码。它总是从CR52_0的启动介质(如QSPI Flash)中加载第二阶段引导程序(BL2)到系统RAM中。
- BL2:BL2执行后,会根据配置将第三阶段引导程序(BL3)和U-Boot加载到DDR内存中,然后跳转到BL3。
- BL3:BL3主要完成一些早期硬件初始化和安全配置,为U-Boot的运行做好准备,然后跳转到U-Boot。
- U-Boot:作为功能丰富的引导加载程序,U-Boot负责加载Linux内核、设备树 blob(DTB)和根文件系统镜像,并最终启动Linux内核。掌握Linux的引导过程对于嵌入式开发至关重要。
- Linux 内核:Linux内核启动后,初始化系统各项服务。
- 启动R52核:最后,通过前文详述的Linux内核中的
remoteproc框架,按顺序加载并启动CR52_0和CR52_1上的专用固件,完成整个多核系统的启动。
至此,一个由CA55核处理复杂应用和网络通信、两个R52核分别负责实时EtherCAT通信和高性能电机驱动的“驱控一体”多核异构系统便搭建完成。