notes
ToolsFibril can

fibril_can ワイヤプロトコル (CAN ID + 設定/データプレーン)

Standard ID = Topic (動的割当)、Extended ID = 設定 + Service。boot_id で再起動検知、HEARTBEAT 受信で ID 衝突検出

要点: Standard ID (11bit) は Topic 専用で意味はマスターが動的に割り当てる。Extended ID (29bit) は固定レイアウトで設定と Service に使う。CAN 調停では Standard ID が Extended ID より優先されるので、高頻度な制御 feedback (Topic) が自然に優先される。

Extended ID のビットレイアウト#

[28:26] channel    0: config
                   1: service request  (M→S)
                   2: service response (S→M)
                   3-7: 予約
[25:19] node_id    7bit。0x7F はブロードキャスト宛
[18:11] index      service: service_index / config: command code
[10:3]  seq        service: call_id / config: シーケンス番号
[2]     seg        0: SINGLE / 1: SEGMENT
[1:0]   予約       0 固定

channel を最上位に置いてある調停優先順位は config < service request < service response。スレーブは HW アクセプタンスフィルタで channel ∈ {0, 1} かつ node_id ∈ {自分, 0x7F} に絞れる。

設定プレーンの主要コマンド (channel = 0)#

cmd方向用途
DISCOVER (0x01)M → allノード列挙要求。受信スレーブは frame table を wipe
ANNOUNCE (0x02)S → M自己紹介 (schema_hash, protocol_version, boot_id, blob_len, ブロック数, 実 instance 数)。起動時 1s 間隔で 3 回、以後は HEARTBEAT のみ
SCHEMA_READ (0x03)M → S未知の schema blob を要求
SCHEMA_DATA (0x04)S → Mblob 転送
FRAME_DEFINEM → STopic をどの std_id にどう詰めるかを通知
START / STOPM → Sデータプレーン開始 / 停止
HEARTBEAT (0x05)S → M既定 100ms 周期。boot_id / node_state / fault_summary。FAULT でも止まらない
MASTER_HEARTBEAT (0x07)M → all既定 100ms 周期。ACK なし、slave 側 master-lost watchdog をリフレッシュ

ACK / NAK ペアと NAK 理由コードは SPEC §5.1, §5.9。

データプレーン#

Topic (Standard ID)#

  • 配置単位は Topic ではなく field。同 Topic の field を異なる周期の frame に分配可、購読されない field は帯域ゼロ
  • エントリ列挙順 + field bitmask 昇順、パディングなしで詰める。CAN FD の DLC 量子化による末尾パディングは無視
  • サンプル一貫性は frame 単位のみ。timestamp なしなので frame 跨ぎの時刻整合なし。一緒に解釈すべき field は同一 frame に置く (master の責務)

Service (Extended ID)#

  • 要求 = channel 1 (M→S)、応答 = channel 2 (S→M)
  • call_id (8bit) は master 採番。応答は同 service_index + call_id でマッチ、順序は要求順序に無関係
  • 1 frame に収まらない要求/応答は自動分割 (SPEC §7.4)、SEGMENT ビット立てる。組立 timeout 100ms、total_len 上限 1024B
  • status (先頭 1B): OK / ACCEPTED / APP_ERROR / BUSY / UNAVAIL / BAD_INDEX / BAD_VALUE / BAD_LENGTH

boot_id と再起動検知#

  • スレーブは起動ごとに 32bit boot_id を変える。HEARTBEAT / ANNOUNCE に載る
  • master は node ごとに boot_id を記録、異なる boot_id を観測した瞬間に再起動と断定 → 自動で再プロビジョン
  • 再起動検知時点で当該 node 宛の in-flight Service は UNAVAIL 相当でアプリに返却、新規は再プロビジョン完了まで保留
  • スレーブ再起動時に master へ通知する操作は不要、電源投入だけで bridge が追従

ID 衝突検出 (T_listen)#

専用のアドレスクレームフレームは持たない。HEARTBEAT 受信そのものを衝突検出に使う。

  1. スレーブ起動直後、T_listen (既定 300ms + boot_id 由来ジッタ) の間受信専用、HEARTBEAT/ANNOUNCE も送らない
  2. ウィンドウ中に「自 node_id と同じ拡張 ID で、自 boot_id と異なる boot_id を載せた HEARTBEAT」を 1 つでも観測したら FAULT(ID_CONFLICT) 確定
  3. 以後 TX 全停止、復帰は電源再投入のみ

ジッタで同時起動の 2 ノードのどちらかが必ず先着 → 後発が観測 → FAULT に落ちる構造。T_listen 通過後も同じ検出ルール継続、後から同 node_id で投入した機体も新参側が落ちる。

ID_CONFLICT に陥ったスレーブは沈黙するので bridge に直接シグナルは無い。「期待 node_id が一定時間 ANNOUNCE してこない」を診断 topic で通知する。

MASTER_HEARTBEAT と master-lost#

  • master 側もチャネル 0 で MASTER_HEARTBEAT (0x07) を周期送出、ACK なし
  • リフレッシュは MASTER_HEARTBEAT に限らず、master 由来の任意トラフィック (自 node 宛/broadcast の config、service 要求、自 node に定義された M→S Topic frame) で発生。S→M は自ループバック対策で除外
  • fcan_config_t.master_lost_us を設定したスレーブは、閾値時間 master トラフィック無しで全 S→M Topic 送信を停止。HEARTBEAT / ANNOUNCE は継続。閾値 0 で無効

観測 (バスアナライザ / SocketCAN)#

  • 設定プレーン: Extended ID で上位 3bit が 0 のフレーム
  • Service: Extended ID で上位 3bit が 001 or 010
  • Topic: Standard ID 全空間。ID 配置は runtime で決まるので ~/communication_structure と突き合わせ

SocketCAN 簡易観測:

candump -ta -x vcan0,#FFFFFFFF     # 拡張フォーマット + 受信時刻、mask 1FFFFFFF

canplayer で再生、cangen で帯域試験も可。

SPEC.md 索引 (よく参照する節)#

§内容
§2.4ノード状態遷移
§3CAN ID 空間
§4.3DLC 量子化
§5.1〜5.11設定プレーン全般
§5.9NAK 理由コード
§6Topic
§7Service と分割転送
§8Parameter
§9スキーマ
§10スレーブランタイム (C99)
§11マスター (bridge)
§14既定値一覧

関連#

最終更新:

On this page