Cortex-R52使用Lauterbach的多核调试问题

文章目录

    • 一、调试问题描述
      • [1.1 芯片概况](#1.1 芯片概况)
      • [1.2 参考问题脚本内容](#1.2 参考问题脚本内容)
      • [1.3 错误现象](#1.3 错误现象)
    • 二、问题分析与解答
      • [2.1 问题分析](#2.1 问题分析)
      • [2.2 参考脚本](#2.2 参考脚本)
      • [2.3 方法分析](#2.3 方法分析)
        • [2.3.1 各步骤作用详解](#2.3.1 各步骤作用详解)
        • [2.3.2 为什么不一开始就使用 `CORE.ASSIGN 1. 2. 3. 4.`?](#2.3.2 为什么不一开始就使用 CORE.ASSIGN 1. 2. 3. 4.?)
      • [2.4 实际使用时的注意事项](#2.4 实际使用时的注意事项)

一、调试问题描述

在使用 Lauterbach 调试某 Cortex-R52 架构多核芯片时,加载 CMM 脚本后无法成功启动多核调试。

1.1 芯片概况

  • 包含两个 Cluster;
  • 每个 Cluster 各有 2 个内核,共计 4 个 Cortex-R52 同架构内核;
  • 该芯片尚未获得 Lauterbach 官方支持。

1.2 参考问题脚本内容

t32 复制代码
; --- 定义系统内核总数 ---
SYStem.CPU CortexR52               ; 选择 CPU 型号/架构
SYStem.CONFIG.CoreNumber 4         ; 声明芯片共有 4 个物理内核

; --- 分配参与 SMP 调试的内核(选择内核1,2,3,4)---
CORE.ASSIGN 1. 2. 3. 4.

; --- 为自定义芯片配置 CoreSight 组件地址 ---
; Lauterbach官方尚未支持的芯片型号,需手动指定每个内核的调试组件基址。
SYStem.CONFIG.COREDEBUG Base DAP:0x80010000 DAP:0x80110000 DAP:0x80210000 DAP:0x80310000
SYStem.CONFIG.CTI Base DAP:0x80020000 DAP:0x80120000 DAP:0x80220000 DAP:0x80320000

; --- 连接目标并加载程序 ---
SYStem.Mode Up
Data.LOAD.Elf "software.elf"

1.3 错误现象

执行 SYStem.Up 后,报出 debug port fail 错误。

AREA窗口显示如下信息:

复制代码
INFO: SW-DP DPv2 enabled; SwitchToSwd-TryAll->none; TARGETSEL=0xffffffff; DPIDR=0x6ba02477
C0:1 Failed to initialize slave core. Maybe debug port was not initialized by master

二、问题分析与解答

2.1 问题分析

"Failed to initialize slave core"的问题通常源于两种可能:一是DAP初始化时某些同步操作不完整,二是主核在连接过程中干扰了对从核的访问。

分析:在参考问题脚本 中,直接使用指令CORE.ASSIGN 1. 2. 3. 4.分配了全部四个核参与SMP调试,在SYStem.Up后,出现错误。

尝试单核连接:

核心错误信息中提到了master,暗示主核可能控制了调试端口。因此,我们可以先让主核单独连接,这能有效隔离问题根源。

那可以只连接主核。注释掉CORE.ASSIGN行,或仅分配主核。

t32 复制代码
; CORE.ASSIGN 1. 2. 3. 4.    ; 先注释掉多核分配
SYStem.Up

如果仅连接主核(CORE 0)成功,说明问题在于主核对从核的调试端口初始化/管理的责任。

查看官方示例脚本中的相似架构芯片例程,发现到有些脚本中先执行 CORE.ASSIGN 1.,再进行其他操作,之后执行 SYStem.Mode DownCORE.ASSIGN 1. 2. 3.

将问题脚本按照此种方式修改后,问题解决,使用Lauterbach能够正常进行多核调试。

2.2 参考脚本

按以下模板修改 CMM 脚本,问题解决。

t32 复制代码
; === 第一阶段:单核引导 ===
SYStem.Mode Down
SYStem.CPU CORTEX-R52
SYStem.CONFIG.CoreNumber 4          ; 仍声明总核数,但只分配一个
CORE.ASSIGN 1.
SYStem.Option DAPDBGPWRUPREQ ON
SYStem.Option EnReset OFF
SYStem.JtagClock 5000kHz
SYStem.Up                           ; 只连接内核 1

; --- 在此处执行唤醒从核的操作(例如写寄存器)---
Data.LONG DAP:0x40010000 %Long 0x1  ; 示例:使能从核调试电源

; === 第二阶段:断开,重建多核 SMP ===
SYStem.Mode Down
CORE.ASSIGN 1. 2. 3. 4.             ; 分配所有内核
SYStem.Up                           ; 再次连接,此时从核应可访问

; 后续加载程序等操作...

若第一阶段 SYStem.Up 能成功连接主核,但第二阶段仍失败,说明唤醒操作不完整或地址错误,需进一步调整。

2.3 方法分析

先用单核模式对主核进行"引导"操作(如唤醒从核的调试电源、解锁调试访问权限等),然后断开连接,再以完整的多核模式重新建立SMP调试会话。这是一种分阶段初始化 的技巧,常用于调试未获官方支持的复杂多核 SoC,特别是当从核的调试接口默认由主核控制或处于断电状态时。

2.3.1 各步骤作用详解
  1. CORE.ASSIGN 1.

    调试器只"声称"系统有一个内核。这样在执行 SYStem.Up 时,调试器会避免探测或初始化其他从核,从而减少错误干扰,便于集中完成主核的启动和初始化。

  2. 执行其他操作

    这些操作通常包括:

    • 通过主核访问芯片内部的电源管理寄存器调试授权寄存器,为从核的调试接口供电或解除锁定;
    • 读取芯片 ROM 表,手动定位 CoreSight 组件地址;
    • 配置必要的 JTAG 链参数(如 IRPRE / IRPOST);
    • 加载并执行一段初始化代码,让主核主动唤醒从核。

    例如,某些芯片要求主核先通过 APB 或私有总线向从核的 "Debug Power Control" 寄存器写入特定值,否则从核的调试端口将保持复位或断电状态,导致多核连接时报错。

  3. SYStem.Mode Down

    断开调试器与目标的连接,清空当前会话的所有内核分配和状态。这是必需的,因为调试器内部的内核分配配置只能在 Down 状态下完全重置。

  4. CORE.ASSIGN 1. 2. 3. 4.

    重新声明所有参与 SMP 调试的内核。此时由于从核的调试端口已在上一阶段被主核"激活",调试器可以正常访问它们。

  5. 再次执行 SYStem.Up

    以完整的 SMP 模式建立连接,所有内核应能成功初始化。

2.3.2 为什么不一开始就使用 CORE.ASSIGN 1. 2. 3. 4.

调试器在执行 SYStem.Up 时会立即尝试初始化所有分配给 SMP 的内核 (包括读取调试寄存器、检查 ID 等)。若此时某个从核的调试接口尚未上电或处于复位锁定状态,则会立即报错(如您遇到的 Failed to initialize slave core)。

分阶段操作相当于先排除障碍,再让调试器进场

2.4 实际使用时的注意事项

  • 并非所有 SoC 都需此做法 :若芯片已获 Lauterbach 官方支持,或从核调试接口始终可访问,直接一次性 CORE.ASSIGN 所有内核即可。
  • "其他操作"的具体内容因芯片而异:需查阅芯片手册,确定如何通过主核启用从核的调试访问。常见方法包括写内存映射寄存器、通过调试接口发送特定序列等。
  • 也可在不 Down 的情况下动态添加内核 :TRACE32 较新版本支持在 Up 状态下使用 CORE.ASSIGN 动态加入内核(需先执行 CORE.SYNC),但部分旧版本或复杂 SoC 仍需断连后重建。

如何判断是否需要分阶段初始化?

可先直接尝试完整SMP连接(CORE.ASSIGN 1. 2. 3. 4.)。若报Failed to initialize slave core,且已正确配置CoreSight基址、关闭了CORERESET,则很可能需要分阶段初始化。