1. 多核调试工程导入
多核调试与单核调试最大的区别,不在于“多插几个断点”,而在于调试对象从一条执行流变成了多条并发执行流。当 SoC 上同时运行 Cortex-A 应用核、Cortex-R 实时核、Cortex-M 控制核,甚至还有 DSP 与硬件加速器时,工程师面对的是:多个核各自有独立的 PC、栈、寄存器组,却又通过共享内存、Mailbox、中断和硬件信号量彼此耦合。Green Hills MULTI 的价值,正是在这一层提供统一的工程视图——它把异构多核的加载、运行控制、符号解析和时序观测收拢到同一个 IDE 与调试后端中。
MULTI 在多核开发中的定位
MULTI 是 Green Hills Software 的集成开发环境,底层由 MULTI IDE + 编译器套件 + 调试引擎 + 探针/仿真器 四层构成。在多核场景下,它并非简单地把多个单核调试会话并排摆放,而是通过 MULTI Debug Server(mdb) 统一管理目标连接,再由各核的调试代理分别控制。其关键能力包括:
- 多核同步运行控制:可对全部核执行 Run/Halt/Step,也可对单核独立控制,并支持“某核命中断点后按策略暂停其他核”,用于捕捉跨核竞态。
- 异构符号加载:每个核可加载各自的
.elf,符号表按核隔离,避免同名函数在不同核间混淆。 - 共享内存与全局对象观测:通过 Memory 视图与 Watch 窗口同时查看各核视角下的同一物理地址。
- 时序与事件追踪:配合 Green Hills 的 SuperTrace Probe 或片上 ETM/ETB,可做指令级 trace 与时间线分析。
需要明确的是:MULTI 的调试能力依赖目标连接方式。JTAG 探针只能提供运行控制与内存访问;若要做非侵入式指令追踪,则需要探针支持 trace 或目标芯片具备 ETB/ETM 并正确配置时钟与引脚复用。
典型多核调试工作流
一个可复现的多核调试流程通常包含以下环节,且顺序并非绝对,但每一步的输入输出必须清晰:
- 建立目标连接:在 MULTI 中新建 Connection,选择探针类型(如 Green Hills Probe、SuperTrace Probe 或第三方 JTAG),指定目标配置文件(
.cfg或板级初始化脚本),完成复位与时钟初始化。 - 创建多核工程:为每个核建立独立子工程,分别指定编译器(如
ccarm、ccrh850)、链接脚本与输出.elf。共享代码可抽为公共库,但符号需按核区分。 - 配置下载与启动顺序:多核系统通常有主核先启动、从核等待唤醒的约束。需在 Debug Configuration 中设置各核的下载顺序、复位行为与初始 PC。
- 设置断点与同步策略:在共享内存访问点、Mailbox 收发点、中断入口设置断点,并配置“命中后暂停全部核”或“仅暂停当前核”。
- 运行与观测:通过 Watch、Memory、Register、Call Stack 窗口观察各核状态;必要时启用 trace 记录跨核事件时间线。
- 问题定位与回归:将复现步骤、断点配置、trace 片段固化为可重复的调试脚本或工程配置,便于回归验证。
下面这张图展示了 MULTI 多核调试的信号与数据流关系:从 IDE 到调试服务器,再到探针与目标各核,以及共享内存与 trace 通路。它帮助理解“一次 Halt 全部核”的请求究竟经过哪些环节。
课程目标与能力地图
本课程围绕“能独立搭建并运行一个多核调试工程”展开,最终应达到以下可验证目标:
- 能根据目标芯片与探针型号,正确创建 MULTI Connection 并完成复位与时钟初始化。
- 能为异构多核分别建立子工程,配置编译选项、链接脚本与下载顺序。
- 能设置跨核断点与同步暂停策略,并解释“全停”与“单停”的适用场景。
- 能通过 Memory/Watch 窗口定位共享内存数据不一致问题,并结合 trace 判断时序竞态。
- 能把一次完整调试过程固化为可重复的工程配置与脚本。
实验环境搭建要点
实验环境建议采用“真实目标板 + 探针”或“MULTI 自带仿真器”两种路径。若使用真实硬件,需确认以下参数:
| 项目 | 示例值 | 说明 |
|---|---|---|
| 目标芯片 | 异构 SoC(A/R/M 三核) | 需确认各核调试接口是否独立 |
| 探针 | Green Hills Probe / SuperTrace | Trace 功能需探针与芯片同时支持 |
| JTAG 时钟 | 10 MHz(示例) | 过高会导致连接不稳定,需按板级实测调整 |
| 复位方式 | 系统复位 + 核独立复位 | 多核启动顺序依赖复位策略 |
| 共享内存基址 | 0x8000_0000(示例) | 需与链接脚本、MMU 配置一致 |
| Trace 缓冲 | ETB 32 KB(示例) | 容量决定可回溯的指令窗口 |
搭建完成后,建议先做一个最小验证:让三个核分别点亮各自的可观测标志(如 GPIO 或内存变量),在 MULTI 中同时 Watch 这三个变量,执行全停/全跑,确认每个核的符号都能正确解析、断点都能独立命中。这一步通过后,再进入跨核通信与竞态调试,才能避免把“环境问题”误判为“代码问题”。