Robotics
SocketCAN の通信診断手順 (ip -s link / candump / cansniffer)
CAN バスの異常を PC 側から切り分ける手順。リンク統計のエラーカウンタ、candump のフィルタ・ログ、cansniffer、canplayer による再生
要点: CAN の異常は「バス自体 (エラーカウンタ)」→「フレームの有無 (candump)」→「応答の欠落 (ID フィルタ + タイムスタンプ)」の順で切り分ける。全部 can-utils (apt) と ip で済み、ノード側のコード変更は不要。
1. バスの健全性: ip -details -statistics link show can0
ip -details -statistics link show can0見る行:
| 項目 | 正常値 | 異常時の意味 |
|---|---|---|
state ERROR-ACTIVE | ERROR-ACTIVE | ERROR-WARNING / ERROR-PASSIVE / BUS-OFF はエラーカウンタ超過 (配線・終端・ビットレート不一致) |
bus-errors | 0 | 送受信でエラーフレームが出た回数 |
bus-off | 0 | 1 以上ならバスから切り離された。restart-ms 0 なら自動復帰しない |
RX ... dropped | 0 | カーネル側受信キュー溢れ (アプリの読み出しが遅い) |
TX ... errors | 0 | 送信失敗 |
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 up2. フレームを見る: 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 # 保存したログを同じ間隔で再送応答欠落の切り分け手順
ip -s linkで bus-off / bus-errors / dropped が 0 かcandump -t a -eを別端末で回したままノードを起動- 要求 ID (PC → 基板) と応答 ID (基板 → PC) でフィルタして、要求が n 回再送されたか、応答が返っているかを見る
- 応答が candump に無い → 基板 FW かバス。応答が有る → ノードのソケット受信 (RX 溢れ、コールバック登録の競合)
ノードのソケット溢れは ip -s link の dropped には出ない (ソケット単位)。ss -f netlink では見えないので、ノード側で SO_RXQ_OVFL を有効にするか、受信スレッドの遅れをログで確認する。
関連
最終更新: