notes
Robotics

SocketCAN の通信診断手順 (ip -s link / candump / cansniffer)

CAN バスの異常を PC 側から切り分ける手順。リンク統計のエラーカウンタ、candump のフィルタ・ログ、cansniffer、canplayer による再生

要点: CAN の異常は「バス自体 (エラーカウンタ)」→「フレームの有無 (candump)」→「応答の欠落 (ID フィルタ + タイムスタンプ)」の順で切り分ける。全部 can-utils (apt) と ip で済み、ノード側のコード変更は不要。

ip -details -statistics link show can0

見る行:

項目正常値異常時の意味
state ERROR-ACTIVEERROR-ACTIVEERROR-WARNING / ERROR-PASSIVE / BUS-OFF はエラーカウンタ超過 (配線・終端・ビットレート不一致)
bus-errors0送受信でエラーフレームが出た回数
bus-off01 以上ならバスから切り離された。restart-ms 0 なら自動復帰しない
RX ... dropped0カーネル側受信キュー溢れ (アプリの読み出しが遅い)
TX ... errors0送信失敗
bitrate / dbitrate相手と一致不一致だと全フレームがエラーになる

CAN FD の場合は dbitrate (データ相) も確認する。sample-point は 0.75〜0.875 が典型値。

bus-off から復帰させる:

sudo ip link set can0 type can restart-ms 100   # 100 ms 後に自動復帰
sudo ip link set can0 down && sudo ip link set can0 up

2. フレームを見る: candump#

candump -t a -e can0                # 絶対時刻 (epoch 秒) + エラーフレーム
candump -t d can0                   # 前フレームからの差分時刻
candump can0,171:7FF,161:7FF        # ID 0x171 と 0x161 だけ (id:mask、mask 7FF は完全一致)
candump -l can0                     # candump-<日付>.log に保存 (canplayer で再生可)
candump -t a can0 > cap.log         # ファイル直書き (stdout はブロックバッファなので Ctrl-C まで遅れる)
timeout 10 candump -t a can0 > cap.log   # 10 秒で自動停止
  • -e: エラーフレーム (ERRORFRAME) も表示。bus-off や ACK エラーの瞬間がわかる
  • -t a はカーネルの受信タイムスタンプ (µs 精度)。ROS ログの epoch 秒と直接突き合わせできる
  • フィルタは id:mask を , で並べる。~ を付けると除外 (can0,~161:7FF)
  • 出力は (時刻) can0 ID [DLC] data...。CAN FD は [48] のように DLC が 8 を超える
  • candump は自分のソケットで受信するので、別プロセス (ROS ノード) が受け取れたかとは独立。「candump には見えるがノードがタイムアウトする」ならノード側 (ソケット溢れ・照合バグ)、「candump にも無い」ならデバイス側

3. 周期フレームの変化を見る: cansniffer#

cansniffer -c can0        # ID ごとに 1 行、変化したバイトを色付き表示

同じ ID が繰り返す (フィードバック等) 場合に、どのバイトが変わっているかを追うのに向く。単発の要求/応答は candump の方が向く。

4. 負荷: canbusload#

canbusload -r can0@500000              # 1 秒ごとに % 表示
canbusload -r -t can0@500000,4000000   # CAN FD (arbitration@data)

5. 送信: cansend / 再生: canplayer#

cansend can0 171#01              # ID 0x171, データ 1 byte (0x01)
cansend can0 171##1.0102         # CAN FD (## の後が flags、その後がデータ)
canplayer -I candump-2026-09-08.log   # 保存したログを同じ間隔で再送

応答欠落の切り分け手順#

  1. ip -s link で bus-off / bus-errors / dropped が 0 か
  2. candump -t a -e を別端末で回したままノードを起動
  3. 要求 ID (PC → 基板) と応答 ID (基板 → PC) でフィルタして、要求が n 回再送されたか、応答が返っているかを見る
  4. 応答が candump に無い → 基板 FW かバス。応答が有る → ノードのソケット受信 (RX 溢れ、コールバック登録の競合)

ノードのソケット溢れは ip -s link の dropped には出ない (ソケット単位)。ss -f netlink では見えないので、ノード側で SO_RXQ_OVFL を有効にするか、受信スレッドの遅れをログで確認する。

関連#

最終更新:

On this page