CAN系列 — (3) Radar Object List 在 MCU 内部是如何被拼装、校验并最终被消费的?

本文统一使用 MCU(Microcontroller Unit) 表示雷达 CAN FD 报文的接收与处理节点。

在系统架构语境中,该 MCU 可能承担域控制器(DCU)的角色,但在本文讨论的 CAN 接收、AUTOSAR 链路与 Object List 拼装问题上,两者指代同一执行实体。


1. 从 CAN 报文进入 MCU 开始,问题才真正出现

在系统设计评审中,经常会看到一种"错觉":只要 CAN FD 带宽算够、报文能收到,雷达数据就算接进来了。

但在真实工程中,CAN 报文进入 MCU 只是物理层和驱动层的完成,离"可被感知算法使用"还隔着一整套软件语义重建过程。

一次完整的雷达 Object 更新周期,在 MCU 内部通常会经历如下路径:
CAN FD Rx ISR
CanIf
PduR
COM / Decode
Object List Assembler
Consistency Check
Validated Object Buffer
Perception / Fusion

这里存在一个非常重要但容易被忽略的事实:

CAN 报文是"帧级事件",
Radar Object List 是"周期级结果"。

MCU 的职责,不是"尽快处理每一帧 CAN 报文",

而是在正确的时间点,向上层提供一个完整、一致、可信的 Object List 快照。


2. MCU 为什么必须先知道"这一周期应该有多少 Object"

在 Object List 拼装逻辑中,expected_obj_num 是一个绕不开的变量。它的存在,解决的是一个问题:

MCU 如何判断"这一轮雷达数据是否已经收全"?

2.1 expected_obj_num 的来源

工程上的共识:

Object 数量只能由雷达声明,不能由 MCU 推测。

在主流量产设计中,雷达会在 Object List Header 报文中明确给出:

Header 字段 含义
Measurement Cycle Counter 本次感知周期编号
Object Count 本周期有效 Object 数
Timestamp 雷达时间基准
Alive Counter 功能安全
CRC 报文完整性

当 MCU 接收到 Header 后,会立即建立本周期的"期望模型":

c 复制代码
current_cycle_id   = header.cycle_counter;
expected_obj_num   = header.object_count;
received_obj_num   = 0;

从这一刻开始,MCU 不再是"被动接收 CAN 帧",

而是进入一种验证雷达声明是否成立的状态。


3. Object List 在 MCU 内部是如何被逐步拼装的

3.1 拼装的基本原则

MCU 内部的 Object List 拼装遵循三个非常工程化的原则:

  1. 以 Header 为周期起点
  2. 以 Object Count 作为完成条件
  3. 以周期一致性作为第一优先级

一个典型的拼装缓冲区如下:

c 复制代码
struct ObjectListBuffer {
    uint16_t cycle_id;
    uint8_t  expected_obj_num;
    uint8_t  received_obj_num;
    Object   objects[MAX_OBJ];
};

3.2 Object 数据如何进入缓冲区

每当 MCU 收到一帧 Object 数据 CAN FD 报文时,并不会立刻"处理 Object",而是:

  1. 校验该帧的 Cycle Counter 是否与当前周期一致
  2. 解析 Object Index / Slot
  3. 将 Object 数据写入对应位置
  4. 累加 received_obj_num

这一阶段的代码特征通常是:

  • 不做融合
  • 不做决策
  • 不触发算法

它的唯一目标是: 在 MCU 内部还原出雷达"本周期完整结果"的原始形态。


4. 一致性校验:为什么 MCU 宁可丢一个周期

received_obj_num == expected_obj_num 时,

很多新手会认为"Object List 已经完成了"。

但在工程上,这只是进入一致性校验的起点

4.1 常见校验项

校验项 工程意义
Cycle Counter 连续 防止周期交叉
Object Index 唯一 防止重复或覆盖
数量匹配 防止丢帧
周期超时 防止雷达或总线异常

4.2 为什么不能"部分使用"

假设雷达声明本周期有 20 个 Object,但 MCU 实际只收到了 18 个:

  • 这 2 个缺失目标,可能正好是前车或行人
  • 对 Fusion / Tracking 来说,这是语义错误,而不是精度下降

因此,量产系统中普遍采用的策略是:

只要 Object List 不完整,整个周期直接作废。

这是系统稳定性的底线,而不是保守设计。


5. Object List 是如何被 MCU 提供给上层消费的

当 Object List 通过一致性校验后,MCU 才会将其提交到"可消费区域"。
Fusion / Tracking Validated Buffer Assembler Fusion / Tracking Validated Buffer Assembler Commit Object List Read (周期触发) Stable Snapshot

这里有两个非常重要的工程设计选择:

5.1 消费是"周期驱动",而不是"CAN 驱动"

  • CAN 接收中断:高频、短路径
  • Object List 提交:低频、强语义

因此,MCU 通常会通过:

  • OS Task
  • Runnable
  • Event Flag

来触发上层算法,而不是在 CAN ISR 或 Rx 回调中直接调用

5.2 双缓冲几乎是标配

机制 目的
Double Buffer 避免读写冲突
Ring Buffer 支持延迟消费

这一步,决定了系统在高 CAN 负载和算法高耗时场景下是否还能稳定运行。


总结(工程视角)

可以用一句话总结整个流程:

CAN 帧只是进入 MCU 的数据碎片,
Object List 才是 MCU 向上层交付的"感知事实"。

雷达负责"声明世界",

MCU 负责"验证声明是否成立",

算法只面对稳定、完整、同一时刻的世界快照

相关推荐
Tfly__7 小时前
在PX4 gazebo仿真中加入Mid360(最新)
linux·人工智能·自动驾驶·ros·无人机·px4·mid360
深圳市九鼎创展科技7 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计7 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
小龙报9 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业9 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能9 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微
czwxkn9 小时前
4STM32(stdl)TIM定时器
stm32·单片机·嵌入式硬件
Love Song残响9 小时前
NVIDIA显卡终极优化指南
stm32·单片机·嵌入式硬件
qq_6725927510 小时前
电源芯片为什么发热
单片机·嵌入式硬件
天天爱吃肉821810 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车