4. CAN通信栈驱动层配置
在ETAS工具链(ISOLAR-AB / RTA-CAR)中,CAN通信栈的驱动层配置是整条通信链路能否跑通的基础。这一层由三个模块构成:Can Driver(CAN驱动,直接操作CAN控制器)、CanIf(CAN Interface,向上屏蔽硬件差异、向下调度驱动)、CanTrcv(CAN Transceiver Driver,管理收发器工作模式)。三者通过标准AUTOSAR接口串联,配置顺序也遵循自下而上的依赖关系:先有Can Driver的硬件对象,再有CanIf的HTH/HRH映射,最后才是CanTrcv的模式控制。
一、Can Driver:控制器与硬件对象
Can Driver配置的核心是CanController和CanHardwareObject两类容器。CanController对应芯片上的一个CAN控制器实例(如TC3xx的CAN0、CAN1),需要配置的关键参数包括:
- CanControllerBaudRate:标称波特率,例如500 kbps;
- CanControllerPropSeg / Seg1 / Seg2:位时序分段,决定采样点位置;
- CanControllerSyncJumpWidth:同步跳转宽度,用于重同步;
- CanControllerActivation:控制器是否在初始化后立即激活;
- CanControllerRxProcessing / TxProcessing:中断或轮询处理方式。
以500 kbps、采样点80%为例,若CAN时钟为40 MHz,一个位时间含80个tq,则:SyncSeg=1 tq,PropSeg+Seg1=63 tq,Seg2=16 tq,SJW取4 tq。这些值必须与总线上其他节点一致,否则会出现位错误或采样点漂移导致的偶发丢帧。
CanHardwareObject是驱动层最关键的抽象,它把CAN控制器的报文RAM(Message RAM)划分为若干硬件对象,每个对象要么用于发送(HTH),要么用于接收(HRH)。配置时需要指定:
- CanObjectId:硬件对象编号,与芯片的Mailbox/FIFO索引对应;
- CanHandleType:BASIC(单报文)或FULL(FIFO/队列);
- CanHwObjectCount:FULL类型时的队列深度;
- CanIdType:STANDARD、EXTENDED或MIXED;
- CanIdValue / CanIdMask:接收对象的验收滤波条件。
例如,为接收0x100~0x10F的标准帧,可配置一个HRH,CanIdValue=0x100,CanIdMask=0x7F0,这样只有高7位匹配的报文才会被接收。发送对象则通常按报文粒度独立配置,每个HTH对应一个CanIf发送PDU。
二、CanIf:HTH/HRH映射与PDU路由
CanIf是驱动层与应用层之间的“路由表”。它不直接操作硬件,而是把上层的CanIfTxPdu和CanIfRxPdu绑定到Can Driver的硬件对象上。配置的核心是两张映射表:
- CanIfTxPdu → CanIfTxPduCanId → CanIfTxPduHthRef:发送PDU通过HTH引用找到对应的硬件发送对象;
- CanIfRxPdu → CanIfRxPduCanId → CanIfRxPduHrhRef:接收PDU通过HRH引用找到对应的硬件接收对象。
这里有一个容易出错的点:HTH/HRH是CanIf层的引用名,不是硬件对象编号本身。在ISOLAR-AB中,CanIfTxPduHthRef指向的是CanIf模块内定义的CanIfHth,而CanIfHth再通过CanIfHthCanObjectRef关联到Can Driver的CanHardwareObject。这条链路必须完整,否则编译能过、运行时报PDU无法发送。
接收侧还需要配置CanIfRxPduCanIdType和CanIfRxPduCanIdMask,用于软件层的二次过滤。如果硬件HRH已经做了滤波,软件层可以放宽;如果多个PDU共享一个HRH,则软件层必须用CanId和Mask区分。例如,HRH接收0x100~0x10F,CanIfRxPduA的CanId=0x100、Mask=0x7FF,CanIfRxPduB的CanId=0x101、Mask=0x7FF,这样两个PDU就能从同一个HRH中分流。
三、CanTrcv:收发器模式与唤醒
CanTrcv模块管理外部CAN收发器(如TJA1043、TJA1145)的工作模式。配置项包括:
- CanTrcvChannelId:收发器通道编号,与CanController对应;
- CanTrcvWakeUpSupport:是否支持总线唤醒;
- CanTrcvWakeUpByBusUsed:是否使用总线唤醒源;
- CanTrcvPinControl:STB、EN等控制引脚映射。
在工程中,CanTrcv通常与CanIf的CanIfTrcvWakeUp和EcuM的唤醒源配置联动。如果收发器支持唤醒,CanTrcv需要把唤醒事件上报给CanIf,再由CanIf通知EcuM。若配置遗漏,节点可能无法从睡眠中唤醒,或者唤醒后无法正确进入通信状态。
四、配置顺序与验证要点
推荐的配置顺序是:先建CanController和CanHardwareObject,再建CanIf的HTH/HRH和PDU,最后建CanTrcv并关联通道。验证时重点检查三件事:
- HTH/HRH引用链是否完整:CanIfTxPdu → CanIfHth → CanHardwareObject,逐级确认;
- CanId与Mask是否匹配:硬件滤波和软件滤波不能互相矛盾;
- 波特率与采样点是否一致:用CANoe或示波器测量实际位时间,确认采样点落在75%~80%区间。
上图把三层模块的引用关系画成了一条纵向链路:CanIf的Tx PDU通过HthRef找到CanIfHth,再通过CanObjectRef落到Can Driver的发送硬件对象;Rx PDU同理走HrhRef。CanTrcv则独立管理收发器通道和唤醒上报。实际配置时,只要沿着这条链路逐级检查引用是否为空、CanId和Mask是否一致,就能排除大部分“编译通过但通信失败”的问题。
最后给出一个可参考的配置检查表,用于在ISOLAR-AB中逐项核对:
| 检查项 | 所在模块 | 期望值/判断依据 |
|---|---|---|
| CanControllerBaudRate | Can Driver | 与总线其他节点一致,如500 kbps |
| 采样点位置 | Can Driver | 75%~80%,用示波器或CANoe测量 |
| CanHardwareObject方向 | Can Driver | HTH用于发送,HRH用于接收 |
| CanIfTxPduHthRef | CanIf | 非空,且指向正确的CanIfHth |
| CanIfRxPduHrhRef | CanIf | 非空,且指向正确的CanIfHrh |
| CanIfHthCanObjectRef | CanIf | 指向Can Driver的发送硬件对象 |
| CanIfHrhCanObjectRef | CanIf | 指向Can Driver的接收硬件对象 |
| CanId与Mask一致性 | CanIf / Can Driver | 硬件滤波范围覆盖软件滤波范围 |
| CanTrcvChannelId | CanTrcv | 与CanController通道对应 |
| 唤醒源关联 | CanTrcv / EcuM | CanIfTrcvWakeUp已配置并关联EcuM |
完成以上配置后,建议先用一个最小工程验证:只配置一个发送PDU和一个接收PDU,用CANoe发送0x100,观察CanIfRxPdu是否收到;再用节点发送0x200,观察总线上是否出现正确报文。确认链路通畅后,再逐步增加PDU和硬件对象。这样可以把配置错误定位在最小范围内,避免一次性引入过多变量导致排查困难。