2. i.MX异构平台硬件基础

i.MX异构平台的核心价值,在于把“跑操作系统、做复杂应用”的 Cortex-A 核与“跑实时任务、做确定性控制”的 Cortex-M 核放进同一颗芯片,并让二者共享内存与外设资源。理解硬件基础,关键不是记住型号参数,而是看清三件事:两个子系统各自拥有什么、它们通过什么共享、外设和中断到底归谁管。这三件事决定了后续实时任务能否稳定运行、A/M 通信是否可靠、以及调试时该去哪个域找问题。

一、典型芯片的内部结构:从 i.MX8 到 i.MX8M 再到 i.MX9

i.MX8 系列是异构架构的典型代表。以 i.MX8QuadMax 为例,内部包含两个 Cortex-A72、四个 Cortex-A53 组成的应用域,以及两个 Cortex-M4F 实时域,此外还有独立的 GPU、VPU、显示控制器和 DDR 控制器。i.MX8M 系列则更偏向“单 A 核 + 单 M 核”的紧凑结构,例如 i.MX8M Mini 集成四核 Cortex-A53 与一颗 Cortex-M4F,适合成本敏感但仍需实时协处理的场景。i.MX9 系列进一步演进,采用 Cortex-A55 应用核搭配 Cortex-M33 实时核,M33 带 TrustZone 与更强的安全能力,适合工业控制与边缘计算。

无论哪一代,内部结构都可以抽象为三层:应用域(A 核集群 + 缓存 + MMU)、实时域(M 核 + 紧耦合存储 TCM + NVIC)、共享基础设施(DDR、外设总线、时钟复位、中断控制器)。A 核通过 MMU 管理虚拟内存,适合 Linux 等富操作系统;M 核通常无 MMU,直接访问物理地址,靠 TCM 和 NVIC 获得低延迟响应。二者不是主从关系,而是对等协作,各自有独立的启动流程和电源域。

二、Cortex-A 与 Cortex-M 子系统的分工

Cortex-A 子系统负责非实时任务:图形界面、网络协议栈、文件系统、AI 推理调度等。它拥有 L1/L2 缓存、MMU、GIC(通用中断控制器)接口,运行 Linux 或 Android。Cortex-M 子系统负责硬实时任务:电机换相、PWM 更新、编码器采样、安全联锁、传感器闭环等。它拥有 NVIC、TCM、MPU(可选),通常运行 FreeRTOS 或裸机程序,中断延迟可稳定在数十纳秒到微秒级。

实际项目中,常见的分工是:A 核跑 HMI 和云端通信,M 核跑 1 kHz 甚至 10 kHz 的控制环。A 核把目标值、参数、模式命令通过共享内存或 RPMsg 发给 M 核;M 核把实际位置、状态、故障码回传。这样既保留了 Linux 的生态优势,又保证了控制环的确定性。

三、内存映射:谁住在哪里

内存映射是异构开发最容易踩坑的地方。典型 i.MX8M Mini 的地址空间可粗略分为:DDR 区域(如 0x4000_0000 起,容量由板级配置决定)、A 核外设区、M 核专用 TCM 区、以及共享内存保留区。M 核的 TCM 通常位于芯片内部,例如 0x7E00_0000 附近,容量 128 KB 到 256 KB,访问延迟极低,适合放中断向量表、堆栈和关键代码。

共享内存一般从 DDR 中划出一段保留区,例如 0x4800_0000 起保留 1 MB,A 核在设备树中用 reserved-memory 节点声明,M 核在链接脚本中把该区域定义为 .shared 段。双方必须约定同一套数据结构,例如环形缓冲区加读写指针,并注意缓存一致性:A 核侧若使用 cache,需要 dma_alloc_coherent 或显式 flush/invalidate;M 核侧通常关闭该区域 cache 或使用非缓存映射。

四、外设分配与中断路由

外设分配的原则是“谁用谁管,避免双主”。例如 UART、I2C、SPI、CAN、PWM、ADC 等,在设备树中通过 status = "okay" 或 "disabled" 决定归属。若某路 UART 分配给 M 核,A 核的设备树必须将其禁用,否则两边同时初始化会导致引脚冲突和寄存器竞争。典型做法是:M 核负责实时串口和 CAN,A 核负责调试串口和网络。

中断路由是异构平台的关键机制。i.MX8/8M 使用 GIC 与 M 核 NVIC 协同:部分外设中断可以路由到 M 核,由 M 核直接响应,避免经过 Linux 中断线程化带来的抖动。配置时需要在 GIC 中设置中断目标、使能对应 IRQ,并在 M 核的启动代码中注册 ISR。A 核与 M 核之间的核间中断(IPI)则用于消息通知,例如 A 核写共享内存后触发 IPI,M 核在 ISR 中读取并处理。

i.MX 异构平台内部结构与资源分配示意 Cortex-A 应用域 A 核集群 + MMU L1/L2 Cache Linux / Android GIC 接口 Cortex-M 实时域 M 核 + NVIC TCM 紧耦合存储 FreeRTOS / 裸机 MPU 保护 共享内存保留区(DDR) 0x4800_0000 起 1 MB · 环形缓冲区 + 读写指针 · 非缓存映射 核间中断 IPI A 核触发 M 核响应 外设总线:UART · I2C · SPI · CAN · PWM · ADC · GPIO —— 按设备树 status 分配归属,避免双主竞争

五、一个可参考的配置片段

下面给出 A 核设备树中保留共享内存并禁用 M 核外设的示例,参数为教学假设值,实际应以芯片参考手册和板级设计为准:

reserved-memory {
    #address-cells = <2>;
    #size-cells = <2>;
    ranges;

    m7_shared: m7_shared@48000000 {
        reg = <0x0 0x48000000 0x0 0x100000>;
        no-map;
    };
};

&uart3 {
    status = "disabled";   /* 该路 UART 分配给 M 核 */
};

&can1 {
    status = "disabled";   /* 该路 CAN 分配给 M 核 */
};

M 核侧则在链接脚本中把共享区固定到同一地址,并确保该段不被 cache:

MEMORY
{
    TCM  (rwx) : ORIGIN = 0x7E000000, LENGTH = 128K
    SHARED (rw) : ORIGIN = 0x48000000, LENGTH = 1M
}

SECTIONS
{
    .shared : { *(.shared) } > SHARED
}

验证时,可在 A 核用 devmem2 0x48000000 读取共享区首字,在 M 核用调试器查看同一地址,确认双方看到的数据一致。若 A 核写入后 M 核读到旧值,优先检查 cache 属性和内存屏障;若 M 核中断不触发,检查 GIC 路由配置和 NVIC 使能位。把结构、内存、外设、中断四条线理清,异构平台的硬件基础就真正立住了。