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) { // エラー処理 }
参考