CANIF(CAN Interface)收发完整流程

CANIF(CAN Interface)收发完整流程 + 实战举例(AUTOSAR 标准)

CANIF 是 AUTOSAR 通信层核心模块 ,承上(PDUR/COM)启下(CAN Driver/CAN 控制器),核心做:上层 I-PDU ↔ 底层 CAN 报文 映射、路由、收发调度、确认、滤波

下面分 发送流程、接收流程 ,每一步配真实可落地的报文举例(含:上层发什么包、底层发什么包、总线上是什么、接收反向流程)。


一、前置基础(必须先懂)

1. 架构层级(从上到下)

COM → PDU Router(PDUR)→ CAN Interface(CANIF) → CAN Driver → CAN Controller → CAN Bus

2. 关键术语

  • I-PDU:上层(COM/PDUR)与 CANIF 交互的单元(只含:数据 + 长度)
  • CAN L-PDU:CANIF 与 CAN Driver 交互的单元(含:CAN ID、帧类型、DLC、数据)
  • HOH(Hardware Object Handle):CAN 控制器硬件收发邮箱/缓冲区(TxHOH 发、RxHOH 收)
  • TxConfirmation:发送完成回调(总线发成功后底层回传)
  • RxIndication:接收到达回调(总线上有报文上传)

二、CANIF 发送(Tx)完整流程 + 逐步骤举例

1. 发送场景举例(固定参数,全程用)

我们要发:ECU 内部应用 → 总线 标准帧报文

  • 上层 Tx I-PDU ID:TxPduId = 0x05
  • 目标 CAN 控制器:CanController = 0(CAN1)
  • 映射 TxHOH(发送硬件句柄):Hth = 1
  • CAN ID(标准 11bit):0x123
  • 数据长度 DLC:4
  • 发送数据:[0x11, 0x22, 0x33, 0x44]
  • 帧类型:标准帧(CAN_ID_STD)

2. 发送前关键配置(简化,实际由 ARXML 配置)

  1. Tx I-PDU 绑定 CAN ID、DLC、控制器
  2. Tx I-PDU 映射到 TxHOH(Hth=1)
  3. 使能发送确认回调

3. 完整发送流程(7 步,每步带实例)

步骤1:上层(PDUR/COM)调用 CANIF 发送 API

上层通过 CanIf_Transmit 下发 I-PDU(只有数据+长度,无 CAN ID)

c 复制代码
// 上层调用(伪代码)
PduInfoType TxPduInfo;
TxPduInfo.SduDataPtr = &DataBuffer[0]; // [0x11,0x22,0x33,0x44]
TxPduInfo.SduLength = 4;               // DLC=4

Std_ReturnType ret = CanIf_Transmit( TxPduId=0x05, &TxPduInfo );

上层发包格式(I-PDU)

  • PduId: 0x05
  • Length: 4
  • Data: [0x11, 0x22, 0x33, 0x44]
    (无 CAN ID、无帧类型,这些由 CANIF 配置决定)

步骤2:CANIF 校验 + 路由映射

CANIF 做:

  1. 校验 TxPduId 合法性
  2. 查表:TxPduId=0x05 → 对应 CanCtrl=0Hth=1CAN ID=0x123STD 帧
  3. 把 I-PDU 封装为 CAN L-PDU(补全 ID、帧类型、DLC)

步骤3:CANIF 调用 CAN Driver 底层发送 Can_Write

CANIF 向下调用驱动接口,传入 TxHOH + 完整 CAN 报文

c 复制代码
// CANIF 调用 Can_Write(伪代码)
Can_MsgType CanMsg;
CanMsg.CanId       = 0x123;          // 配置好的ID
CanMsg.CanIdType   = CAN_ID_STD;     // 标准帧
CanMsg.CanDlc      = 4;              // 长度
CanMsg.CanSduPtr   = [0x11,0x22,0x33,0x44];

Std_ReturnType ret = Can_Write( Hth=1, &CanMsg );

CANIF → CAN Driver 发包格式(CAN L-PDU)

  • Hth: 1
  • CanId: 0x123
  • Type: STD
  • DLC: 4
  • Data: [0x11,0x22,0x33,0x44]

步骤4:CAN Driver 配置控制器硬件发送

驱动将报文写入 TxHOH=1 对应硬件缓冲区,启动发送。


步骤5:CAN 控制器把报文发到总线上

总线上真实波形/报文(CANoe 可抓到):

复制代码
ID: 0x123  |  DLC:4  |  Data: 11 22 33 44  |  标准帧

步骤6:发送完成 → CAN Driver 回调 Can_TxConfirmation

控制器发送成功后,驱动向上回调,告知 哪个 TxHOH 发完

c 复制代码
// CAN Driver 回调 CANIF
void Can_TxConfirmation( Can_HwHandleType Hth=1, Std_ReturnType Result=E_OK );

步骤7:CANIF 转发确认 → 上层 PduR_TxConfirmation

CANIF 把 Hth=1 反向映射回 TxPduId=0x05,回调上层:

c 复制代码
// CANIF 回调 PDUR
void PduR_TxConfirmation( PduIdType TxPduId=0x05, Std_ReturnType Result );

至此 发送全流程结束


三、CANIF 接收(Rx)完整流程 + 逐步骤举例

1. 接收场景举例(固定参数,全程用)

总线上发来报文:

  • CAN ID(标准 11bit):0x456
  • DLC:3
  • 数据:[0xAA, 0xBB, 0xCC]
  • 帧类型:标准帧
  • 接收控制器:CanCtrl=0
  • 匹配 RxHOH(接收硬件句柄):Hrh=2
  • 上层 Rx I-PDU ID:RxPduId=0x0A

2. 接收前关键配置

  1. 配置 Rx 滤波:精确匹配 ID=0x456
  2. 滤波通过 → 路由到 RxPduId=0x0A
  3. RxHOH=2 绑定控制器0、ID=0x456

3. 完整接收流程(6 步,每步带实例)

步骤1:CAN 控制器收到总线报文 → 硬件滤波匹配

总线报文:

复制代码
ID:0x456 | DLC:3 | Data:AA BB CC | STD

控制器滤波命中 → 存入 RxHOH=2。


步骤2:CAN Driver 读取报文 → 回调 Can_RxIndication

驱动从硬件读出报文,上传给 CANIF:

c 复制代码
// CAN Driver 回调 CANIF
void Can_RxIndication(
    Can_HwHandleType Hrh=2,          // 接收HOH
    const Can_MsgType* CanMsgPtr     // 完整CAN报文
);
// CanMsg 内容:ID=0x456, STD, DLC=3, Data=[0xAA,0xBB,0xCC]

底层上传包格式(CAN L-PDU)

  • Hrh:2
  • CanId:0x456
  • Type:STD
  • DLC:3
  • Data:[0xAA,0xBB,0xCC]

步骤3:CANIF 校验、ID 路由、映射为 Rx I-PDU

CANIF 做:

  1. 校验 DLC、控制器
  2. 查表:ID=0x456 + Ctrl=0RxPduId=0x0A
  3. 剥离底层硬件信息,只保留 数据+长度 形成 I-PDU

步骤4:CANIF 调用 PduR_RxIndication 上传上层

c 复制代码
// CANIF 回调 PDUR/COM
void PduR_RxIndication(
    PduIdType RxPduId=0x0A,
    const PduInfoType* PduInfoPtr
);
// PduInfo:Length=3, Data=[0xAA,0xBB,0xCC]

上层收到的包格式(I-PDU)

  • RxPduId:0x0A
  • Length:3
  • Data:[0xAA,0xBB,0xCC]
    (上层看不到 CAN ID、HOH、控制器,只关心业务数据)

四、收发报文格式对比(最直观总结)

方向 交互层级 报文类型 包含内容 实例值(发送) 实例值(接收)
发送(上→下) COM/PDUR ↔ CANIF I-PDU PduId + SduLength + SduData TxPduId=0x05, Len=4, [11,22,33,44] -
发送(下→底) CANIF ↔ CAN Driver CAN L-PDU Hth + CanId + Type + DLC + Data Hth=1, ID=0x123, DLC=4, 同上数据 -
接收(底→上) CAN Driver ↔ CANIF CAN L-PDU Hrh + CanId + Type + DLC + Data - Hrh=2, ID=0x456, DLC=3, [AA,BB,CC]
接收(上→应用) CANIF ↔ COM/PDUR I-PDU PduId + SduLength + SduData - RxPduId=0x0A, Len=3, 同上数据
总线实际报文 ECU ↔ 总线 CAN 帧 ID + IDE(标准/扩展) + DLC + Data + CRC ID=0x123, DLC=4, [11,22,33,44] ID=0x456, DLC=3, [AA,BB,CC]

五、核心关键点(开发必注意)

  1. 上层看不到 CAN ID:ID、HOH、控制器全由 CANIF 配置屏蔽,上层只认 PduId。
  2. DLC 必须匹配配置:发送时上层长度 ≠ 配置 DLC 会报错;接收时 DLC 不匹配会丢弃。
  3. 发送确认必须处理TxConfirmation 是总线真正发成功的标志,不是 CanIf_Transmit 返回成功就代表发完。
  4. 接收靠滤波:Rx 流程第一步是硬件/软件滤波,不匹配的 ID 直接丢弃,不上传。
  5. 标准帧 vs 扩展帧 :CANIF 会区分 CAN_ID_STD / CAN_ID_EXT,配置和路由必须一一对应。

六、极简一句话总结

  • 发送:上层给 CANIF 「PduId+数据」→ CANIF 查表补全「CAN ID+HOH」→ 驱动发总线 → 底层确认回调上层。
  • 接收:总线报文 → 控制器滤波 → 驱动上传「CAN ID+数据」→ CANIF 映射为「PduId+数据」→ 上传应用。
相关推荐
Coder个人博客16 小时前
Linux6.19-ARM64 mm mmu子模块深入分析
大数据·linux·车载系统·系统架构·系统安全·鸿蒙系统
Coder个人博客4 天前
Linux6.19-ARM64 mm init子模块深入分析
linux·安全·车载系统·系统架构·系统安全·鸿蒙系统·安全架构
Coder个人博客5 天前
Linux6.19-ARM64 mm ioremap子模块深入分析
linux·安全·车载系统·系统架构·系统安全·鸿蒙系统·安全架构
Coder个人博客5 天前
Linux6.19-ARM64 mm mmap子模块深入分析
大数据·linux·安全·车载系统·系统架构·系统安全·鸿蒙系统
Coder个人博客5 天前
Linux6.19-ARM64 mm hugetlbpage子模块深入分析
linux·安全·车载系统·系统架构·系统安全·鸿蒙系统·安全架构
idwangzhen7 天前
GEO优化系统哪个版本好
车载系统
码界奇点8 天前
基于Spring Boot和Activiti6的工作流OA系统设计与实现
java·spring boot·后端·车载系统·毕业设计·源代码管理
idwangzhen9 天前
GEO优化系统哪个操作简单
车载系统
wechat_Neal9 天前
车企跨界机器人
人工智能·车载系统·机器人·汽车·人机交互