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+数据」→ 上传应用。
相关推荐
汽车仪器仪表相关领域4 天前
动态诊断充电中枢:DCA-8000型动态诊断充电系统 4S店/维修连锁/新能源服务站/车队维保全场景实战全解
人工智能·车载系统·汽车·负载均衡·压力测试·可用性测试
杰克崔4 天前
android的lmkd的实现及代码分析
android·linux·运维·服务器·车载系统
进击的横打7 天前
【车载开发系列】入坑RH850芯片
c语言·车载系统
进击的横打7 天前
【车载开发系列】GPIO核心概念理解
车载系统
进击的横打9 天前
【车载开发系列】Renesas Flash Programmer (RFP) 反向读取功能
车载系统·编辑器·rfp
进击的横打10 天前
【车载开发系列】瑞萨RH850芯片基础介绍
车载系统
进击的横打12 天前
【车载开发系列】Renesas Flash Programmer (RFP) 使用教程
车载系统
进击的横打13 天前
【车载开发系列】浮点数与整型数的转换
c语言·车载系统
进击的横打14 天前
【车载开发系列】C语言浮点数入门
c语言·车载系统
王夏奇16 天前
自动泊车技术-入门理解
车载系统