CANの受信フィルタ

文書バージョン:1.2.0 対象GitHubバージョン:v1.2.0 文書ID:guide-can-receive-filter
文書状態:公開済み。mainへのpush時に検証後、GitHub Pagesを自動更新

更新履歴

文書バージョン 更新日 更新内容
1.2.0 2026-10-22 v1.2.0の対象タグ・文書版を確定。過去の測定基準と公開済み履歴を保持
1.1.1 2026-10-11 公開文書整合性監査の修正を反映し、文書PATCHを一つ上げ、対象タグをv1.1.4へ統一
1.1.0 2026-10-06 初版:ECU別の受信選択、送信成功との区別、1設定3条件の実測例を追加

目的:必要なセンサデータだけを受け取る

同じCANバスに温度センサa、状態通知b、表示ECU cがあると考えます。表示ECUが温度のIDだけを扱いたいとき、rxFilterを変えると、バス上で送信されたフレームをECU別に受け入れるか判定できます。

この実習では「送信は成功したのに、cでは受信が増えない」を再現します。通信失敗や送信キューの破棄と、アプリケーション側の選別を区別することが目的です。a・b・cの名称を用途に見立てていますが、サンプル自体は3つの汎用Controllerです。最初に初めてのCAN実行を実行してください。サイト内検索では短い語「フィルタ」でこのページを探せます。複合語で見つからない場合は語を短くするか、機能辞典と実験の目次を使ってください。

構成と責務

要素 この実習での責務
Main.a standard ID 256(16進表記0x100)、8byteのデータを1回送信
Main.b standard ID 512(0x200)、4byteのデータを1回送信
Main.c 他ECUからの受信を選択。同時にID 768(0x300)、2byteを1回送信
Main.bus 500kbpsのClassical CAN。同じ実習の調停・直列化を処理
rxFilter Controllerごとに、フレームの形式とIDを受信時に照合

NEDの接続は既存実習と同じです。各ControllerのtxはBusへ、Busの対応する出力はそのControllerのrxへ接続します。Wireの遅延、TX/RX処理遅延はいずれも0psのままです。送信者自身への受信行は作られません。

接続と処理フロー

  1. JSONの3要求を生成し、a・b・cの送信キューから調停します。
  2. EOFで送信要求はsuccessになります。送信者以外のControllerに受信側の記録を作ります。
  3. 各受信経路の伝搬遅延を経て、observed_psを記録します。
  4. その受信者のrxFilterと形式・IDが一致すれば、RX処理遅延後にreceivedとなりreceived_psを記録します。
  5. 一致しなければfilteredとなります。観測時刻は残り、受信完了時刻はnullです。

フィルタは、このモデルの送信者側の調停順・EOF・バス解放時刻を変えません。拒否した受信があることだけで、送信要求をdroppedにする処理ではありません。

最小実行例と設定

リポジトリのルートで実行します。実習入力ZIPにも、このページのINI2件と既存のNED・JSONを含めています。導入とバイナリの用意は入門の手順を参照してください。古いZIPを導入済みなら、追加のfilter-id.ini・filter-none.iniを含む最新版を別の作業場所へ展開します。

cargo run -- validate --config examples/guide/can/filter-id.ini
cargo run -- run --config examples/guide/can/filter-id.ini --output results-guide-filter-id
cargo run -- view --input results-guide-filter-id/results.json --output guide-filter-id-viewer.html

guide-filter-id-viewer.htmlをブラウザで開きます。出力済みの同名ディレクトリ・HTMLは上書きされないため、再実行には新しい名前を使ってください。

filter-id.iniはminimal.iniに次の1設定を追加したものです。NED、JSON、時間、bitrate、送信キュー容量は同じです。

Main.c.rxFilter = "std:0x100"
書き方 意味
"*" 全形式・全IDを受け入れる。サンプルのNED既定値
"none" アプリケーション受信を全て拒否
"std:0x100" standard ID 256だけを受け入れる
"std:0x100,std:0x200" standard ID 256または512を受け入れる
"ext:0x100" extended ID 256だけを受け入れる。standard ID 256とは別

stdのID範囲は0〜0x7ff、extは0〜0x1fffffffです。カンマ区切りで同じ形式・IDを重複できません。空白を含む式、10進表記のstd:256、マスクや範囲指定はこの構文に含まれません。入力ミスはvalidateで確認します。JSONのid: 256とフィルタの0x100は同じ数値です。

結果と実画面:bの送信成功とcの選別

Viewerで時刻を1000µsへ移動し、要求b:0を選択します。画面の要求状態は「送信成功」、受信者Main.cは「フィルタ拒否」です。保存JSONではそれぞれsuccessとfilteredになります。Main.aはreceivedのままです。

ID256だけを受け入れるcと、b要求の受信記録

この表は画面の省略表示ではなく、保存されたresults.jsonのsimulation.receiversを読み取った値です。

要求→受信者 観測時刻µs 受信完了µs 状態
a:0→Main.b 238 238 received
a:0→Main.c 238 238 received
b:0→Main.a 400 400 received
b:0→Main.c 400 —(null) filtered
c:0→Main.a 530 530 received
c:0→Main.b 530 530 received

3要求すべて送信成功、受信完了5件、選別1件です。cはbを拒否しますが、c自身の送信は成功し、a・bに受信されます。受信フィルタは送信の停止設定ではありません。

実験:1設定を変える — 全受入・ID指定・全拒否

同じ負荷を3条件で比較します。変更変数はMain.c.rxFilterだけです。minimal.iniではNED既定の*を使い、filter-id.iniではstd:0x100、filter-none.iniではnoneを指定します。

cargo run -- run --config examples/guide/can/minimal.ini --output results-guide-filter-all
cargo run -- run --config examples/guide/can/filter-none.ini --output results-guide-filter-none
cargo run -- view --input results-guide-filter-none/results.json --output guide-filter-none-viewer.html
c.rxFilter 全体の送信成功 全体のreceived 全体のfiltered cへのreceived
* 3 6 0 2
std:0x100 3 5 1 1
none 3 4 2 0

3条件ともaのSOF/EOF/解放は0/238/244µs、bは244/400/406µs、cは406/530/536µsでした。受信を絞っても今回のバス占有時間は短くなりません。送信数を減らす実験では、フィルタではなく負荷の生成設定を別途変える必要があります。

制約と関連機能

  • can.cc.ideal.v1ではactiveノードを前提とする理想ACKのモデルです。filteredをACK不在や実機の通信エラーとして解釈しません。
  • queueCapacityは送信待機容量です。この実習は受信FIFOの深さや受信バッファあふれをモデル化したものではありません。GatewayのRX保持容量は別の機能です。
  • rxProcessingDelayを増やすと、受入フレームの受信完了は遅れます。今回の3条件では0ps固定であり、CPU処理負荷や消費電力を実測した結果ではありません。
  • 終了時刻に受信イベントが未処理のまま残る場合があります。received_ps: nullだけでフィルタ拒否と決めず、必ず受信行のstatusを確認します。

調停順はCANの調停、要求と受信行の読み方はViewerで結果を読むを参照してください。モデル固有の構文と状態はv1.1.3のCAN機能仕様に基づきます。