项目:异构多核(A7 Linux + M4 RTOS)

AMP(Asymmetric Multiprocessing):一核跑 Linux,一核跑 RTOS。

一、概念

┌──────────────────────────┐
│       Cortex-A (Linux)   │ 用户界面、网络、存储
├──────────────────────────┤
│   RPMsg / Shared Memory  │ 核间通信
├──────────────────────────┤
│       Cortex-M (RTOS)    │ 实时控制、低功耗
└──────────────────────────┘

二、Linux 端:加载 M4 固件

1. 设备树

&rpmsg {
    /*
     * 64-byte resource table at the start of M4 firmware
     */
    status = "okay";
};

m4_rproc: m4@0 {
    compatible = "fsl,imx7d-rproc-m4";
    reg = <0x00900000 0x10000>;       // M4 TCM
    ...
};

2. Remote Processor 框架

// Linux 加载 M4 固件
echo my_m4_firmware.elf > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state

3. RPMsg 通信

#include <imx_rpmsg.h>

// 创建 endpoint
struct rpmsg_endpoint *ept;
int cb(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv)
{
    printf("Got %zu bytes from M4: %s\n", len, (char*)data);
    return 0;
}

rpmsg_create_ept(&ept, "rpmsg-tty-channel", RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, cb, NULL);

// 发送
rpmsg_send(ept, "hello", 5);

三、M4 端:Zephyr / FreeRTOS

1. Zephyr 示例

#include <zephyr.h>
#include <drivers/ipm.h>

#define CHANNEL_ID 0
static struct rpmsg_endpoint ep;
static struct ipm ipm;
static struct device *ipmdev = DEVICE_GET_BINDING(my_ipm);

static void ipm_callback(void *context, uint32_t id, volatile void *data)
{
    rpmsg_recv(&ep, (void*)data, 32);
}

void rpmsg_service_unbind(struct rpmsg_endpoint *ep)
{
    printk("Endpoint destroyed\n");
}

void rpmsg_endpoint_cb(struct rpmsg_endpoint *ep, void *data, size_t len, uint32_t addr, void *priv)
{
    char buf[33];
    memcpy(buf, data, len);
    buf[len] = 0;
    printk("M4 received: %s\n", buf);

    // 回传
    rpmsg_send(&ep, "ack", 3);
}

int main(void)
{
    printk("M4 Hello!\n");

    // 初始化 IPM
    ipm_register_callback(ipmdev, ipm_callback, NULL);
    ipm_set_enabled(ipmdev, 1);

    // 注册 endpoint
    rpmsg_register_callback("rpmsg-tty-channel", rpmsg_endpoint_cb, rpmsg_service_unbind);

    while (1) {
        k_sleep(K_SECONDS(1));
    }
}

四、应用:电机控制

1. M4 端

2. A7 端(Linux)

3. 通信数据

五、共享内存(高性能)

// A7 写参数
struct control_param *p = ioremap(M4_SHARED_BASE, M4_SHARED_SIZE);
p->kp = 1.0f;
p->target_rpm = 3000;

// M4 读
uint32_t *shared = (uint32_t *)0x30000000;
float kp = *(float*)&shared[0];

六、资源分区

资源 Linux M4
应用 用户态 RTOS 任务
内存 小(256KB-2MB)
外设 复杂外设 实时外设
中断 软中断 硬件中断

明确分工:M4 不访问复杂外设(网络、显示),避免资源冲突。

七、Zephyr RTOS

#include <zephyr.h>

void main(void)
{
    while (1) {
        // 实时任务
        k_sleep(K_MSEC(1));
    }
}

八、FreeRTOS

九、构建流程

# 1. 编译 M4 固件
cd m4_app
make BOARD=frdm_k64f
# 输出 m4_app.elf

# 2. 把 M4 固件放到 rootfs
cp m4_app.elf /path/to/rootfs/lib/firmware/

# 3. A7 Linux 启动
modprobe imx_rproc
echo my_m4_app.elf > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state

十、调试

# A7
gdb-multiarch vmlinux

# M4
arm-none-eabi-gdb m4_app.elf
(gdb) target extended-remote :3334

十一、典型应用