CAN FD简介

CAN FD简介

1 CAN FD简介

  在汽车领域,随着人们对数据传输带宽要求的增长,传统的CAN总线因为带宽的限制难以知足这种增长的需求。此外为了缩小CAN网络(max. 1MBit/s)与FlexRay(max.10MBit/s)网络的带宽差距,BOSCH公司推出了CAN FD。
CAN FD(CAN with Flexible Data rate)继承了CAN总线的主要特性。CAN总线采用双线串行通信协议,基于非破坏性仲裁技术,分布式实时控制,可靠的错误处理和检测机制使CAN总线有很高的安全性,但CAN总线带宽和数据场长度却受到制约。CAN FD总线弥补了CAN总线带宽和数据场长度的制约,CAN FD总线与CAN总线的区别主要在如下两个方面:
  1. 可变速率:CAN FD采用了两种位速率。从控制场中的BRS位到ACK场以前(含CRC分界符)为可变速率,其他部分为原CAN总线用的速率。两种速率各有一套位时间定义寄存器,它们除了采用不一样的位时间单位TQ外,位时间各段的分配比例也可不一样;
  2. 新的数据场长度:CAN FD对数据场的长度做了很大的扩充,DLC最大支持64个字节,在DLC小于等于8时与原CAN总线是同样的,大于8时有一个非线性的增加,因此最大的数据场长度可达64字节。算法

1.1 CAN FD数据帧帧格式

  CAN FD数据帧在控制场新添加EDL位、BRS位、ESI位,采用了新的DLC编码方式、新的CRC算法(CRC场扩展到21位)。CAN FD数据帧格式以下图所示。
CAN FD数据帧格式安全

1.2 新添加位介绍

  • EDL位(Extended Data Length):原CAN数据帧中的保留位R。隐性表示CAN FD报文(采用新的DLC编码和CRC算法),显性表示CAN报文;
  • BRS位(Bit Rate Switch):该位隐性表示转换可变速率,显性表示不转换速率;
  • ESI位(Error State Indicator):该位隐性表示发送节点处于被动错误状态(Error Passive),显性表示发送节点处于主动错误状态(Error Active);
      EDL位能够表示CAN报文仍是CAN FD报文;BRS表示位速率转换,该位为隐性位时,从BRS位到CRC界定符使用转换速率传输,其余位场使用标准位速率,该位为显性时,以正常的CAN FD总线速率传输;经过添加ESI位,能够很方便的知道当前发送节点所处的状态。

1.3 新的CRC算法

  CAN总线因为位填充规则对CRC的干扰,形成错帧漏检率未达到设计意图。CAN FD对CRC算法作了改变,即CRC以含填充位的位流进行计算。在校验和部分为避免再有连续位超过6个,就肯定在第一位以及之后每4位添加一个填充位加以分割,这个填充位的值是上一位的反码,做为格式检查,若是填充位不是上一位的反码,就做出错处理。CAN FD的CRC场扩展到了21位。因为数据场长度有很大变化区间,因此要根据DLC大小应用不一样的CRC生成多项式,CRC_17,适合于帧长小于210位的帧,CRC_21,适适合于帧长小于1023位的帧。网络

1.4 新的DLC编码

  CAN FD数据帧采用了新的新的DLC编码方式,在数据场长度在0-8个字节时,采用线性规则,数据场长度为12-64个字节时,使用非线性编码。以下图所示。
DLC编码框架

2 SylixOS中CAN FD的实现

2.1 CAN驱动实现

  SylixOS的CAN驱动框架在原有CAN的基础上增长了对CAN FD的支持。对应于新的CAN帧格式,SylixOS增长了新的帧结构定义,以下所示。分布式

typedef struct {
    UINT32              CAN_uiId;                     /*  标识码                      */
    UINT32              CAN_uiChannel;               /*  通道号                      */
    BOOL                CAN_bExtId;                   /*  是不是扩展帧                */
    BOOL                CAN_bRtr;                     /*  是不是远程帧                */
    UINT32              CAN_uiCanFdFlags;            /*  CAN FD 相关设置             */
#define CAN_FD_FLAG_EDL     1
#define CAN_FD_FLAG_BRS     2
#define CAN_FD_FLAG_ESI     4
    UCHAR               CAN_ucLen;                    /*  数据长度                    */
UCHAR               CAN_ucData[CAN_FD_MAX_DATA];
                                                     /*  帧数据                      */
} CAN_FD_FRAME;
typedef CAN_FD_FRAME   *PCAN_FD_FRAME;              /*  CAN FD 帧指针类型           */

  为了同时兼容CAN与CAN FD,系统在建立CAN设备申请帧缓冲区时,以帧结构较大的CAN FD帧报文为单位进行申请。同时经过ioctl新增长的CAN_DEV_CAN_FD选项查看CAN设备驱动以及控制器是否支持CAN FD。这次查询决定了后续驱动对帧缓冲区进行读写时的帧报文格式,即标准CAN或CAN FD。所以CAN FD驱动的ioctl接口除了要实现标准CAN驱动的选项外,还要额外实现CAN_DEV_CAN_FD选项,以下所示。ui

case CAN_DEV_CAN_FD:
        *(UINT *)lArg = CAN_STD_CAN_FD;
        break;

2.2 应用层实现

  应用层须要收发CAN FD报文时,必须经过ioctl的CAN_FIO_CAN_FD选项对CAN FD进行设置,以下所示。this

CAN_FD_FRAME   canfdframe[10];
    ssize_t        size;
    ssize_t        frame_num;
    long            status;
     ...

    canfile = open("/dev/can0", O_RDWR);

    ioctl(canfile, CAN_DEV_SET_MODE, 1);
    ioctl(canfile, CAN_DEV_SET_BAUD, LW_OSIOD_LARG(*));
    /*
    *  must call this before read() write()
    */
    ioctl(canfile, CAN_FIO_CAN_FD, CAN_STD_CAN_FD);
    ioctl(canfile, CAN_DEV_STARTUP);

    size       = read(canfile, canfdframe, 10 * sizeof(CAN_FD_FRAME));
    frame_num = size / sizeof(CAN_FD_FRAME);

    if (frame_num <= 0) {
        ioctl(canfile, CAN_DEV_GET_BUS_STATE, &status);
        ...
        ioctl(canfile, CAN_DEV_REST_CONTROLLER);
    }

    ...
    size       = write(canfile, canfdframe, 10 * sizeof(CAN_FD_FRAME));
    frame_num = size / sizeof(CAN_FD_FRAME);

3 参考资料

  《CAN FD协议介绍》:http://www.cechina.cn/company/50633_156096/messagedetail.aspx编码

相关文章
相关标签/搜索