项目:异构多核(A7 Linux + M4 RTOS)
AMP(Asymmetric Multiprocessing):一核跑 Linux,一核跑 RTOS。
一、概念
- 一个 SoC 内有不同架构核心
- 典型:i.MX 8M(Cortex-A53 + Cortex-M4)
- 或 STM32MP1(Cortex-A7 + Cortex-M4)
┌──────────────────────────┐
│ 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 端
- 实时控制循环(10kHz)
- ADC 采样电流、位置
- PWM 输出
- 通信仅用于参数更新
2. A7 端(Linux)
- 友好 HMI
- 网络遥测
- 日志与诊断
3. 通信数据
- 参数下传:KP、KI、KD、目标值
- 状态上传:电流、位置、错误码
五、共享内存(高性能)
// 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
- Linux 基金会的轻量 RTOS
- 支持 i.MX、STM32、NXP、Renesas、Intel
- 模块化设计
- POSIX 兼容 API
#include <zephyr.h>
void main(void)
{
while (1) {
// 实时任务
k_sleep(K_MSEC(1));
}
}
八、FreeRTOS
- 商业免费,普及度高
- 资源占用小(< 10KB)
- 大量示例
九、构建流程
# 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 + OpenOCD
- M4:J-Link / OpenOCD + gdb
# A7
gdb-multiarch vmlinux
# M4
arm-none-eabi-gdb m4_app.elf
(gdb) target extended-remote :3334
十一、典型应用
- 工业控制(电机 + HMI)
- 智能音箱(音频 + 网络)
- 机器人(运动控制 + 视觉)
- 汽车电子(仪表盘 + 信息娱乐)
- 边缘 AI(推理 + 控制)