SocketCANのエラー通知フレーム

SocketCANとは?

SocketCANは、Linuxのソケット通信のAPIの拡張であり、ソケット通信と同様にCAN通信をおこなうことができる。 そのためLinuxでは、CAN通信のプログラムはソケットを使ったネットワークプログラムと同じように記述できる。

エラー通知フレームとは?

SocketCANでは、アプリケーションはエラーメッセージを、通常のCAN フレームと同じように、エラー通知フレームとして受け取ることができる。

CAN_ERR_FLAGビット

受信したフレームの CAN ID の CAN_ERR_FLAGビット (= 0x20000000U) が立っていたらエラーメッセージフレームである。
定数CAN_ERR_FLAG は linux/can.h で定義されている。

エラー種別

エラー通知フレームの CAN ID の 下位10ビットがエラー種別を示す。
そのビットマスクの定数は linux/can/error.h で定義されている。
詳細情報については後述する。

ビットマスク定数 ビットマスク値 エラー種別 詳細情報
CAN_ERR_TX_TIMEOUT 0x00000001U 送信タイムアウト(by デバイスドライバ) -
CAN_ERR_LOSTARB 0x00000002U 調停をロスト data[0]
CAN_ERR_CRTL 0x00000004U コントローラの問題 data[1]
CAN_ERR_PROT 0x00000008U プロトコル違反 data[2..3]
CAN_ERR_TRX 0x00000010U トランシーバ状態 data[4]
CAN_ERR_ACK 0x00000020U ACKが受信されない -
CAN_ERR_BUSOFF 0x00000040U バスがオフ -
CAN_ERR_BUSERROR 0x00000080U バスエラー(フレーム殺到か) -
CAN_ERR_RESTARTED 0x00000100U コントローラ再起動 -
CAN_ERR_CNT 0x00000200U 送信エラーカウンタ
受信エラーカウンタ
data[6]
data[7]

詳細情報

エラー通知フレームのデータ部(8バイト)にエラーの詳細情報が格納される。
そのビットマスクの定数は linux/can/error.h で定義されている。

data[0] : 調停ロスト

何番目のビットで調停をロストしたか。
CAN_ERR_LOSTARB_UNSPEC (=0x00) の場合は特定できず。

data[1] : CANコントローラのエラー状態
ビットマスク定数 ビットマスク値 説明
CAN_ERR_CRTL_UNSPEC 0x00 特定できず
CAN_ERR_CRTL_RX_OVERFLOW 0x01 受信バッファあふれ
CAN_ERR_CRTL_TX_OVERFLOW 0x02 送信バッファあふれ
CAN_ERR_CRTL_RX_WARNING 0x04 受信エラーの警告レベルに達した
CAN_ERR_CRTL_TX_WARNING 0x08 送信エラーの警告レベルに達した
CAN_ERR_CRTL_RX_PASSIVE 0x10 受信エラーパッシブ状態に達した
CAN_ERR_CRTL_TX_PASSIVE 0x20 送信エラーパッシブ状態に達した
CAN_ERR_CRTL_ACTIVE 0x40 エラーアクティブ状態に回復
data[2] : CANプロトコルのエラー種別
ビットマスク定数 ビットマスク値 説明
CAN_ERR_PROT_UNSPEC 0x00 特定できず
CAN_ERR_PROT_BIT 0x01 単一ビットエラー
CAN_ERR_PROT_FORM 0x02 フレームフォーマットエラー
CAN_ERR_PROT_STUFF 0x04 ビットスタッフィングエラー
CAN_ERR_PROT_BIT0 0x08 ドミナントビットを送信できず
CAN_ERR_PROT_BIT1 0x10 レセッシブビットを送信できず
CAN_ERR_PROT_OVERLOAD 0x20 バスオーバーロード
CAN_ERR_PROT_ACTIVE 0x40 アクティブエラー告知
CAN_ERR_PROT_TX 0x80 送信中にエラー発生
data[3] : CANプロトコルのエラー位置
ビットマスク定数 ビットマスク値 説明
CAN_ERR_PROT_LOC_UNSPEC 0x00 特定できず
CAN_ERR_PROT_LOC_SOF 0x03 フレーム先頭
CAN_ERR_PROT_LOC_ID28_21 0x02 IDビット 28 - 21 (SFF: 10 - 3)
CAN_ERR_PROT_LOC_ID20_18 0x06 IDビット 20 - 18 (SFF: 2 - 0 )
CAN_ERR_PROT_LOC_SRTR 0x04 RTR (SFF: RTR)
CAN_ERR_PROT_LOC_IDE 0x05 ID拡張
CAN_ERR_PROT_LOC_ID17_13 0x07 IDビット 17-13
CAN_ERR_PROT_LOC_ID12_05 0x0F IDビット 12-5
CAN_ERR_PROT_LOC_ID04_00 0x0E IDビット 4-0
CAN_ERR_PROT_LOC_RTR 0x0C RTR
CAN_ERR_PROT_LOC_RES1 0x0D 予約ビット 1
CAN_ERR_PROT_LOC_RES0 0x09 予約ビット 0
CAN_ERR_PROT_LOC_DLC 0x0B データ長コード
CAN_ERR_PROT_LOC_DATA 0x0A データ部
CAN_ERR_PROT_LOC_CRC_SEQ 0x08 CRC
CAN_ERR_PROT_LOC_CRC_DEL 0x18 CRCデリミタ
CAN_ERR_PROT_LOC_ACK 0x19 ACKスロット
CAN_ERR_PROT_LOC_ACK_DEL 0x1B ACKデリミタ
CAN_ERR_PROT_LOC_EOF 0x1A フレーム末尾
CAN_ERR_PROT_LOC_INTERM 0x12 休止中
data[4] : CANトランシーバのエラー状態
ビットマスク定数 ビットマスク値 説明
CAN_ERR_TRX_UNSPEC 0x00 特定できず
CAN_ERR_TRX_CANH_NO_WIRE 0x04 CANHが未接続
CAN_ERR_TRX_CANH_SHORT_TO_BAT 0x05 CANHがBATと短絡
CAN_ERR_TRX_CANH_SHORT_TO_VCC 0x06 CANHがVCCと短絡
CAN_ERR_TRX_CANH_SHORT_TO_GND 0x07 CANHがGNDと短絡
CAN_ERR_TRX_CANL_NO_WIRE 0x40 CANLが未接続
CAN_ERR_TRX_CANL_SHORT_TO_BAT 0x50 CANLがBATと短絡
CAN_ERR_TRX_CANL_SHORT_TO_VCC 0x60 CANLがVCCと短絡
CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 CANLがGNDと短絡
CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 CANLがCANHと短絡
data[5] : 送信エラーカウンタ

送信エラーの回数

data[6] : 受信エラーカウンタ

受信エラーの回数

エラー通知フレームを有効にする設定 (抜粋)

    int m_socket;
    if ((m_socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
        // エラー処理
    }
    ...(中略)...
    // エラー通知フレームを有効
    can_err_mask_t err_mask = 0x1FF; // 全てのエラー
    //can_err_mask_t err_mask = ( CAN_ERR_CRTL | CAN_ERR_ACK );
    if (setsockopt(m_socket, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask)) < 0) {
        // エラー処理    
    }

参考