找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

641

积分

0

好友

93

主题
发表于 昨天 01:33 | 查看: 2| 回复: 0

当前,多核处理器已广泛应用于各行各业,嵌入式领域也不例外。本文将基于瑞萨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() 函数中,主要完成以下工作:

  1. 映射并配置电源控制寄存器(PRCRS/PRCRN),使能相关功能。
  2. 通过ioremap建立CA55核访问R52核内存(如ATCM, BTCM, SRAM)的地址映射。这些映射关系在芯片手册中有明确说明。
  3. 将编译好的固件(firmware)拷贝到R52核对应的内存区域。
  4. 通过写入特定的复位控制寄存器(如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之间的数据共享

数据传输流程

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

图片
图五 数据共享的消息序列图

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

图片
图六 数据共享地址

RZ/T2H 多核启动顺序

图片
图七 T2H多核启动顺序

RZ/T2H上电后的启动流程是一个多阶段的过程:

  1. BootROM:系统上电后,首先执行芯片内部的BootROM代码。它总是从CR52_0的启动介质(如QSPI Flash)中加载第二阶段引导程序(BL2)到系统RAM中。
  2. BL2:BL2执行后,会根据配置将第三阶段引导程序(BL3)和U-Boot加载到DDR内存中,然后跳转到BL3。
  3. BL3:BL3主要完成一些早期硬件初始化和安全配置,为U-Boot的运行做好准备,然后跳转到U-Boot。
  4. U-Boot:作为功能丰富的引导加载程序,U-Boot负责加载Linux内核、设备树 blob(DTB)和根文件系统镜像,并最终启动Linux内核。掌握Linux的引导过程对于嵌入式开发至关重要。
  5. Linux 内核:Linux内核启动后,初始化系统各项服务。
  6. 启动R52核:最后,通过前文详述的Linux内核中的remoteproc框架,按顺序加载并启动CR52_0和CR52_1上的专用固件,完成整个多核系统的启动。

至此,一个由CA55核处理复杂应用和网络通信、两个R52核分别负责实时EtherCAT通信和高性能电机驱动的“驱控一体”多核异构系统便搭建完成。




上一篇:微服务拆分七大原则与反例详解:从分布式大单体到云原生架构
下一篇:Vue3动态路由深度解析:从权限管理到模块化架构实践
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-11 04:33 , Processed in 0.078135 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表