CAN使用指南
基本概述
- 最大可使用CAN controller数量:10。
- CAN最高传输速率:8M。(受限于transceiver的波特率限制,目前实验室只测试验证到5M波特率。)
- 一个controller的Ram内划分的Block个数:
- CAN0~CAN3:4 Block (可变payload);
- CAN4~CAN9:4 Block (可变payload)+ 4 Block(固定payload)。
- 一个controller支持的最大Mailbox个数为128。
- 一个controller支持一路RxFIFO,FIFO深度为:
- CAN0~CAN3:8 * 64 bytes;
- CAN4~CAN9:32 * 64 bytes。
- 不支持 TTController,即不支持TTCAN(一种基于CAN总线的高层协议)。
- CAN支持多核使用,可将不同的CAN控制器绑定在不同的核心上,但不支持多个核心同时使用同一个CAN控制器。
软件架构
S100芯片的CAN控制器位于MCU域,负责CAN数据收发。由于感知等应用位于Acore,因此部分CAN数据需要通过IPC核间通信机制转发到Acore。架构保证传输可靠性,转发机制实现数据正确性检测、丢包检测和传输超时检测等机制。此外,还需要规避MCU侧高频转发小数据块导致CPU占用率过高,造成MCU实时性降低等性能问题。
S100 CAN转发方案的核心流程如下:
- 首先通过MCU侧CAN2IPC模块将CAN通道映射到对应IPC通道,然后通过Acore侧CANHAL模块将IPC通道反映射为虚拟CAN设备通道。最后用户通过CANHAL提供的API接口获取虚拟CAN设备中的数据。其中,CAN2IPC模块为MCU侧服务,CANHAL模块为Acore 侧提供给应用程序的动态库。
- CAN2IPC模块周期性采集MCU侧CAN数据,按照指定传输协议进行打包,然后通过IPC核间通信转发到Acore。Ipc instance 0中的channel0~channel7默认分配给CAN转发使用。
- CANHAL模块获取来自MCU侧的IPC数据,按照指定的传输协议解析数据,并支持业务软件通过API获取原始CAN帧。
数据流如上图所示:
- 外设数据通过CAN的PHY和控制器器件被MCU域CAN驱动接收后,CAN驱动将数据上报并缓存在hobot CANIF模块。
- CAN2IPC Service周期性从CANIF模块取出CAN帧,按照可靠传输协议进行打包,然后通过IPC核间通信机制转发给Acore。
- CANHAL模块获取来自MCU侧的IPC数据,按照指定的传输协议解析数据,Acore 应用程序通过CANHAL Lib库提供的API获取CAN帧。
方案特性说明:
- 支持数据透传正确性校验。
- 支持数据透传丢包检测。
- 支持传输超时检测。MCU侧CAN2IPC转发数据时将数据包打上MCU侧的时间戳,Acore CANHAL接收到数据后会读取Acore的时间戳,如果传输超时会报警。注意,需要提前启动时间同步完成MCU RTC时间和Acore 网卡phc0的时间同步。
- 支持多个CAN通道并行传输。MCU侧多个CAN控制器的数据可同时被转发给Acore,Acore应用程序通过CANHAL从不同通道号读出CAN数据。
- 由于CANHAL底层通过ipc核间通信进行传输,而ipc目前不支持多个进程或者线程读写同一个通道,因此CANHAL也不支持该特性。
硬件连接说明
-
CAN物理层的形式主要分为闭环总线及开环总线网络两种,一个适合于高速通讯,一个适合于远距离通讯;S100的sample默认采用闭环总线网络架构。
-
CAN总线的引脚位于S100的MCU扩展板上,引出了5路CAN接口,连接器分别对应了5个绿色的螺丝式的3 PIN连接器。1 PIN(三角标志)为GND,中间PIN为CAN_L,剩下的为CAN_H。
- MCU小板通过2pin跳帽的形式来选择是否在CAN_H和CAN_L之间接入120欧姆电阻;当插入跳帽时,接入电阻,适用于闭环网络所需的终端匹配阻抗;移除跳帽则断开终端电阻,适用于开环网络或中继节点场景。
CAN闭环网络使用两个120欧姆电阻是CAN总线的标准配置,以下以S100举例,如何正确接入电阻:
提示
整体而言,开环网络配置不需要接入120欧姆电阻,而闭环网络配置总共需要插入两个120欧姆电阻;
- 在使用 开环网络时,确保CAN_H与CAN_L线路正确连接,所用到的CAN不要插入跳线帽(在网络中不接入120欧姆电阻);
- 若将S100的CAN5和CAN6连接组成双节点内部闭环网络,确保CAN_H与CAN_L线路正确连接,还需要在CAN5和CAN6接线端子后面的插针插入跳帽(在网络中插入两个120欧姆电阻);
- 若将S100的CAN5~CAN9连接组成多节点内部闭环网络,确保CAN_H与CAN_L线路正确连接,还需要插入两个跳线帽,任意选择两个,严禁插入超过2个跳线帽,以免出现不可预测的问题;
- 若将S100的CAN5~CAN9中的任意一个控制器和其它CAN设备组成外部闭环网络,确保CAN_H与CAN_L线路正确连接外,还需要在RDK的CAN控制器的接线端子后面的插针插入跳帽,并在网络中其它设备端接入一个120Ω电阻;
CAN Filter 配置
标准帧的filter最多可配置128个,扩展帧的filter最多可配置64个,可选择的filter类型如下:
- ONE_ID_FILTER:指定ID并可配置MASK来忽略ID中的哪些bit进行过滤,
- RANGE_ID_FILTER:按照ID范围进行过滤,
- TWO_ID_FILTER:指定两个ID进行过滤。
过滤器的识别
过滤器类型通过检查u32HwFilterCode的最高2位来确定:
- 0b00: ONE_ID_FILTER
- 0b01: RANGE_ID_FILTER
- 0b10: TWO_ID_FILTER
/**
* @struct Can_HwFilterType
* @brief Can Hardware Filter
* @NO{S01E03C01}
*/
typedef struct Can_HwFilterType
{
const uint32 u32HwFilterCode; /**< @brief Specifies (together with the filter mask) the identifiers range that passes the hardware filter. */
const uint32 u32HwFilterMask; /**< @brief Describes a mask for hardware-based filtering of CAN identifiers. */
}Can_HwFilterType;
- 配置举例:
- 这是CAN 7 的过滤器配置,拥有两个过滤器
- 过滤器0的第一个元素的高2位为01,属于范围过滤方式
- 过滤器0和过滤1为"或"关系,即如果至少有一个过滤元件满足匹配标准,则CAN消息内容将被传输到增强型RX FIFO存储器
// Config/McalCdd/gen_s100_sip_B_mcu1/Can/src/Can_PBcfg.c
static const Can_HwFilterType Can_aHwFilter_Object7[2U]=
{
{ // 接收id为0x0~0x7ff的消息
(uint32)0x400007ffU,
(uint32)0x00000000U
},
{ // 接收id为0x600~0x7ff的消息
(uint32)0x400007ffU,
(uint32)0x00000600U
}
};
ONE_ID_FILTER(单ID过滤方式)
这是最常见的过滤器类型,使用过滤器代码和掩码进行过滤,伪代码如下:
if ((Received_ID & Filter_Mask) == (Filter_Code & Filter_Mask))
// 接收该消息
else
// 丢弃该消
举例代码如下:
// Config/McalCdd/gen_s100_sip_B_mcu1/Can/src/Can_PBcfg.c
static const Can_HwFilterType Can_aHwFilter_Object7[2U]=
{
{
(uint32)0x00000400U, // 只接收id = 0x400&0x7ff = 0x400 消息
(uint32)0x000007ffU
},
{ // 范围过滤方式,支持混用
(uint32)0x400007ffU,
(uint32)0x00000600U
}
};