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編碼

相關文章
相關標籤/搜索