CAN通信のフレーム構造とプロトコル|どこまでがCANで、どこからが違う規格か
CANのフレームを調べると、SOF、ID、RTR、DLC、CRC、ACKと略語が並びます。ひととおり読んでも、自分が見ているものがCANのどの部分なのかは分からないままだったりします。
仕事で聞く「マルチフレーム」「NMフレーム」「DID」も同じです。CANの用語だと思って調べても、規格書には出てきません。それらはCANの上に載っている別の規格だからです。
- データフレームのどこが自分の担当で、どこがコントローラの担当かが分かる
- 標準と拡張、そしてCAN FDで何が変わるかを並べて見られる
- 「マルチフレーム」「NMフレーム」がCANではない理由が分かる
目次
CANプロトコルはOSI参照モデルのどこを決めているか
CANはOSI基本参照モデルでいう物理層とデータリンク層を決めています。規格も層ごとに分かれていて、ISO 11898-1がデータリンク層、ISO 11898-2が物理層です(キーエンス「CANプロトコル基礎」)。
データリンク層が決めているのは、電気的なパルスをフレームに組み立てること、送信が衝突したときの調停、受け取ったという応答、エラーの検出と通知です。
8バイトの中身が何を意味するかは、CANの規格には書いてありません。「このIDのByte 0は車速」といった取り決めは、各メーカーや各プロジェクトが自分で決めます。そのため同じCANバスでも、車種が違えば中身の意味は変わります。
CAN規格(ISO 11898)が決めていること、決めていないこと|電圧や配線は物理層
この「どこまでがCANか」は、最後の章でもう一度使います。積み上げて見ると、こうなります。
ここから下がCANの規格
上2つはCANの規格ではなく、CANの上に載る別の規格。この記事はティールの2層を扱う。
上2つはCANの規格ではありません。ここが混同されやすいところなので、中身を見たあとで改めて扱います。
車の中でCANが何をしているか、という全体像は車載組込みソフトとは?仕事内容を現役エンジニアが解説に書いています。
フレームは4種類ある|データ・リモート・エラー・オーバーロード
CANのフレームは4種類あります。ただしアプリのコードから扱うのは1種類だけです。
データを運ぶもの。実務で扱うのはほぼこれだけで、この記事の以降もこれを見ます。
データを持つノードへ「送ってくれ」と要求するもの。規格にはありますがほとんど使われていません。
エラーを検出したノードが流すもの。コントローラが自動で出すので、コードから送ることはありません。
受信側が待ってほしいときに流すもの。これもコントローラが自動で出します。
この中でリモートフレームだけ、もう少し説明が要ります。仕組みは規格にあるのに、実際にはほとんど使われていないからです。
私自身、リモートフレームもオーバーロードフレームも実務で使ったことがありません。データは要求して受け取るのではなく、送る側が周期的に流し続けるのが当たり前になっています。
資料でも同じことが書かれていて、使われなくなった理由が2つ挙げられています。ひとつはデータフレームの送信頻度が高くなると、リモートフレームによる帯域のロスが大きいこと。もうひとつはDLCの定義があいまいで互換性の問題が起きることです(日本システムクリエイト「車載ネットワーク(6)CAN 通信手順とフレーム構造」)。
いまは各ノードがデータフレームを定期的に送る方式が主流です。そのため以降はデータフレームだけを見ます。
データフレームの中身|ID・DLC・データ・CRC・ACK
標準フォーマットのデータフレームは、こう並んでいます。
自分のコードから触るコントローラが自動でやる
幅はビット数のおおよその比率。データフィールドの単位はビット(0〜8バイト)。
色を付けた3つが、アプリのコードから触る部分です。
IDはメッセージの名前であり、同時に優先度でもあります(誰が先に送るかはIDが決めるで扱います)。宛先ではありません。CANは宛先を指定せず、全ノードへ流して受け取る側が自分に必要なIDだけ拾います。
DLCとは|データが何バイト入っているかを伝える
DLCはデータが何バイト入っているかを受信側へ伝えるためのものです。CANはフレームごとにデータの長さが変わるので、受信側には何バイト読めばいいかを知る手がかりがありません。それを渡すのがDLCです。4ビットの値で、クラシカルCANでは0から8まで、値がそのままバイト数になります。
データが中身で、最大8バイトです。ここに何を詰めるかはCANの規格外なので、プロジェクトごとの取り決めになります。
残る6つはコントローラが埋めます。ただしどれも役割があって置かれています。何のためにあるのかだけ押さえておけば十分です。
- SOF(1ビット)
- フレームの始まりの合図。ただの合図ではなく、全ノードがここで時計を合わせます。CANにはクロックを配る線がないので、各ノードは自分の時計でビットを数えています。その基準点がSOFです(規格でも「すべてのノードはSOFが作るエッジに同期しなければならない」と定められています)。
- RTR(1ビット)
- データフレームかリモートフレームかの区別。データフレームでは0、リモートフレームでは1です。同じIDでこの2つがぶつかると0のほうが残るので、データフレームが勝ちます。
- 制御(2ビット)
- IDEビットと予約ビット。IDEは標準フォーマットか拡張フォーマットかの区別で、標準では0、拡張では1です。予約ビットは将来の拡張のために空けてあり、いまは0を送ります。
- CRC(16ビット)
- 中身が途中で化けていないかの検査。エラーはどうやって見つけているかで扱います。
- ACK(2ビット)
- 受け取ったノードがいるかの確認。これも同じ章で扱います。
- EOF(7ビット)
- フレームの終わり。7ビットすべてが1で形が固定されています。固定だからこそ、ここが崩れていれば異常だと判断できます。この「形の確認」も誤り検知の一部です。
フレームフォーマット|標準フォーマットと拡張フォーマットは何が違うか
拡張フォーマットはIDが29ビットになったものです。標準の11ビットの後ろに18ビットを継ぎ足す形になっていて、あいだにSRRとIDEという2ビットが入ります。この2ビットにも役割があります。IDEは「このフレームは拡張だ」と示す印。拡張では1、標準では0が入ります。SRRは標準フォーマットでRTRがあった位置を埋めるビットで、常に1です。標準のRTRは0なので、前の11ビットが同じ値の標準フレームと拡張フレームがぶつかると、必ず標準フレームが勝つようになっています。
自分のコードから触るコントローラが自動でやる
拡張フォーマットはベースIDと拡張IDを合わせて29ビットとして扱う。
使えるIDの数が変わります。11ビットなら2,048種類、29ビットなら約5億4千万種類です。
どちらを使うかは、その通信の取り決めで決まります。乗用車の車内ネットワークは11ビットが主流。一方、トラックやバスなど商用車で使われるSAE J1939は29ビット固定で、IDの中に送信元アドレスやパラメータ番号を埋め込む設計になっています。故障診断のOBD-II(ISO 15765-4)では、11ビットと29ビットの両方が規定されています。
11ビットで足りるなら11ビットを使います。IDが短いぶん1フレームの時間が短くなり、バスに載せられる本数が増えるからです。
アービトレーション|誰が先に送るかはIDが決める
CANには通信の主導権を持つ親機がいません。どのノードも好きなときに送り始められます。当然ぶつかりますが、ぶつかっても壊れません。
複数のノードが同時に送り始めると、各ノードは自分が出したビットとバス上の状態を1ビットずつ見比べます。違っていたら、自分より優先度の高い相手がいると分かるので、その場で送信をやめて受信側に回ります。勝ったノードはそのまま送り続けます。
比べているのはIDです。IDの値が小さいほうが優先されます。そのためIDは名前であると同時に優先度でもあります。
ここで大事なのは、負けたノードのフレームが壊れも消えもしないことです。送信をやめただけなので、バスが空いたら送り直します。衝突を検出してから再送するのではなく、衝突している最中に決着がつきます。
実際のビットの並びで見ると、こうなります。IDが 0x123 のノードAと 0x456 のノードBが、同時に送り始めた場合です。
ノードAが出したビットここでノードBが負けたバス上に残った値送信をやめた区間
11ビットのIDを左から順に送る。最初のビットでAが0、Bが1を出し、バスには0が残る。Bは自分の出した1と食い違うと分かった時点で降りる。
最初の1ビットで決着がついています。Bは自分が1を出したのにバスが0になっているので、より小さいIDの相手がいると分かり、そこで受信側に回ります。Aは何も気づかずに最後まで送り切ります。
CAN IDの設定は誰がどう決めるのか
なおIDに優先度の意味があるので、IDの割り当ては設計そのものになります。遅れては困るメッセージに小さいIDを振る、という判断が必要です。この割り当てはCANの規格ではなく、プロジェクトごとの取り決めです。
エラーフレーム|どうやって異常を見つけて知らせるか
ここから先は、アプリのコードに一度も出てきません。コントローラが自動でやるからです。ただし何のためにやっているかは知っておく価値があります。
車の中は電気的に静かな場所ではありません。モーターもリレーもイグニッションもノイズ源です。ノイズで1ビット化けたデータを、化けたまま使ってしまうのが最悪の結果です。車速が別の値になり、スイッチが押されていないのに押されたことになります。
そのためCANは、フレームを1本受け取るたびに壊れていないかを検査します。仕組みは1つではなく、5種類の検査を重ねています(Bosch「CAN Specification 2.0 Part A」6.1 Error Detection)。
見るのは全ノード。同じ値が6つ続いたらエラー。5つで必ず反対の値が入る決まりなので、6つ続くこと自体があり得ません。
見るのは受信側。中身から計算し直した値が、送られてきた値と合わなければエラーです。
見るのは全ノード。形が固定されている場所(CRCデリミタ・ACKデリミタ・EOF)が決まった値になっていなければエラーです。
見るのは送信側。誰も応答を返さなければエラー。受信ノードが1つもいないことに気づける唯一の検査です。
どれか1つでも引っかかったノードはエラーフレームを流し、そのフレームは全ノードで捨てられます。送信側は自動で送り直します。ここもアプリのコードは書きません。
規格には検出能力が数字で書かれています。ランダムに散らばった誤りは5個まで、連続して化けた場合は15ビット未満まで、そして奇数個の誤りはすべて検出できます。検査をすり抜けて通ってしまう確率は、メッセージ誤り率の 4.7×10⁻¹¹ 倍未満とされています(同規格 1. Introduction)。1980年代の規格がいまも車で使われている理由の1つがここです。
5つのうち帯の上に自分の区画を持っているのは、CRCとACKの2つだけです。スタッフビットは特定の場所ではなく帯の前半ぜんぶに掛かり、残る2つ(ビットエラー・フォームエラー)は送受信のあいだずっと見張っているので区画がありません。区画を持っている2つから、帯を出しながら見ていきます。
CRCエラー|化けた値をそのまま使わせない
帯でいうと、ここの話です。
この節で話しているところ
CRCの役割は中身が途中で化けていないかを受信側が確かめることです。データが1ビット化けても、値としては成立してしまうのが厄介なところです。
たとえば車速を0.1km/h単位で送る設計にしていて、62.0km/hを表す 620 を送ったとします。途中で1ビットだけ化けて 1644 になっても、受信側から見ればただの数字です。164.4km/hとして扱ってしまいます。届いた値が本物なのかノイズで化けたものなのかを見分ける手段が、受信側にはありません。その手段を持たせるのがCRCです。
仕組みは検算です。送信側が中身から計算した15ビットの値を付け、受信側が同じ計算をして突き合わせます。合わなければそのフレームを捨てます。計算の対象はSOFからデータフィールドまでです(日本システムクリエイト)。帯で16ビットになっているのは、この15ビットのうしろに区切りの1ビット(デリミタ)が付くためです。ACKの2ビットも同じで、応答の1ビットとデリミタ1ビットの合計です。
CANが使う15ビットの多項式はハミング距離6で、散らばった誤りなら5個まで、連続した誤りなら15ビットまで検出できます。ただしスタッフビットが入る影響で、特定のビットの並びではハミング距離が2まで落ちることも分かっています。それでも1ビットの誤りは必ず検出できます。複数ビットが同時に化けて気づかれない確率も非常に低い、というのが規格団体の説明です(CiA「Cyclic redundancy check in CAN frames」)。
ACKエラー|誰も受け取っていないことに気づく
帯でいうと、CRCのすぐ後ろです。
この節で話しているところ
ACKの役割は受け取ったノードが1つもいないことに、送信側が気づけるようにすることです。CRCは「届いたフレームが正しいか」を受信側で見る仕組みなので、そもそも誰も聞いていない状態は見つけられません。配線が外れている、相手のECUが起動していない、通信速度の設定が食い違っている。こうした障害を検出できる唯一の検査がACKです。
仕組みは塗りつぶしです。送信側はACKの区間を1のまま流し、正しく受け取ったノードがそこを0で塗りつぶす。CANでは同じタイミングで0と1が出たら0が残るので、この区間が0になっていれば、正しく受け取ったノードが少なくとも1つあると分かります。塗りつぶすのはCRCまで一致したノードだけなので、ACKが返ったことは「中身も正しく届いた」ことまで含んでいます。
裏を返すと、ACKは「誰かが受け取った」ことしか示しません。宛先が受け取ったという意味ではありません。そもそもCANに宛先の概念がないからです。
実用上はここで引っかかります。バスに自分しかいないと0を返す相手がおらず、送信が完了しません。送信側はACKエラーとして扱い、エラーを通知して再送を繰り返します(Kvaser「CANプロトコルとは?」)。1台だけで送信の実験をすると、ここで止まります。
ビットスタッフィングとスタッフエラー|受信側の時計を合わせ直す
これだけは1つのフィールドの話ではなく、帯の前半ぜんぶに掛かる決まりです。
スタッフビットが入る範囲入らない範囲
役割は受信側の時計合わせです。CANにはクロックを配る線がなく、しかも信号は値が続くかぎり変化しません(NRZ方式)。同じ値が延々と続くと受信側は自分の時計だけで数え続けることになり、少しずつサンプリング位置がずれていきます。そこで同じ値のビットが5つ続いたら、反対の値のビットを1つ差し込むと決めました。こうすれば必ず信号が変化する点が現れ、受信側はそこで時計を合わせ直せます(サニー技研「CANとは」)。
同時に誤り検知にもなっています。5つで必ず反転が入るので、6つ続くこと自体があり得ません。6つ続いて見えたらスタッフエラーです。適用範囲はSOF・アービトレーション・制御・データ・CRCシーケンスまでです。CRCデリミタから後ろ(ACK・EOF)は形が固定されているため対象外になります(Bosch「CAN Specification 2.0 Part A」5. Coding)。EOFの1が7つ続いてもエラーにならないのはこのためです。
0が5つ続いた区間元のデータ差し込まれたスタッフビット
0が5つ続いた直後に1が1つ入る。受信側はこの1を取り除いてから中身を組み立てるので、データは変わらない。
差し込まれたビットは受信側で取り除かれるので、データの中身は変わりません。ただし1フレームの長さは中身によって変わります。フレーム時間を見積もるときは、この分を考えておく必要があります。
現場でCANのログを見るときは、こうしたビットは表示されません。専用のツールがフレームとして組み立てたあとの姿を見ることになります。
CAN FDで変わるところ
CAN FDはCANの置き換えではありません。8バイトでは足りなくなった部分だけを拡張した規格です。フレームの形も、IDで優先度を決める仕組みも、ここまで見てきたものがそのまま残ります。
CAN FDは、対応したコントローラとトランシーバがないと動きません。よく使われるMCP2515とTJA1050はクラシカルCANのみの対応です。ここでは規格として何が変わるかを整理します。
CAN FDで大きく変わるのは2つです。どちらも8バイトでは足りなくなったことへの答えになっています。
ひとつはデータが最大64バイトまで伸びること。8バイトに収まらないデータは、これまで分割して送る仕組みに頼るしかありませんでした。64バイト入ればその出番が減りますし、1フレームのうちヘッダが占める割合も下がります。
もうひとつはデータ部分だけ通信速度を上げられることです。なぜ全部を速くしないのか。アービトレーションが速度の上限を決めているからです。複数のノードが同時に0を出しうる区間、つまりIDの調停とACK。ここではバスの端から端まで信号が伝わってからでないと勝敗が決まりません。ノード間のずれが1ビット時間の半分未満に収まっていることが条件で、これが通信速度とバス長の上限になっています。ところが勝敗が決まってからCRCが終わるまでは、0を出すノードは1台だけ。残りはその1台に合わせるだけなので、この制約が外れます。そこだけ速く走らせよう、というのがCAN FDの発想です(Bosch「Bit Time Requirements for CAN FD」)。
自分のコードから触るCAN FDで変わるところコントローラが自動でやる
FDFはこのフレームがCAN FDかどうか、BRSはデータ部を高速に切り替えるかどうか、ESIは送信元がエラーで弱っている状態かどうかを受信側へ知らせるビット。
実装で引っかかるのがDLCの意味が変わることです。DLCは4ビットのままなので、9から15までの値に飛び飛びのバイト数が割り当てられています。
| DLC | 0〜8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|
| データ長 | そのまま0〜8 | 12 | 16 | 20 | 24 | 32 | 48 | 64 |
DLCの値をそのままバイト数として使っているコードは、ここで壊れます。DLCと実際のバイト数は別物になるので、変換表を1つ挟むことになります。
12バイトの次が16バイト、その次が20バイトと飛ぶので、たとえば14バイト送りたいときは16バイトぶんを確保して余りを埋めることになります。
「マルチフレーム」「NMフレーム」「DID」はCANの外側の話
最初の章に戻ります。CANが決めているのは物理層とデータリンク層まででした。よく一緒に語られる言葉は、その上に載っている別の規格です。
マルチフレームはISO 15765-2、通称ISO-TPの用語です。CANのデータは1フレームで8バイトまでなので、それを超えるデータを送るには分割が要ります。ISO-TPがその分割と再組み立てを決めていて、OSIでいうネットワーク層とトランスポート層を担います。7バイト以下ならシングルフレーム、超えると最初のフレーム、連続フレーム、フロー制御の3種類を使い分け、最大4,095バイトまで運べます(ISO 15765-2)。
DIDはさらに上のUDS(ISO 14229)という診断の規格の用語で、読み書きするデータの識別子です(Unified Diagnostic Services)。整備工場の診断機が車から情報を読み出すときのやり取りに使われます。ISO-TPはこのUDSを運ぶ役目を担います。
NMフレームはネットワークマネジメントのことで、ノードの起動と停止を揃えるための仕組みです。これもCANの規格ではありません。AUTOSARが定めるモジュールとして規定されています。以前から使われているOSEKのNMもその中で扱われます(AUTOSAR「Network Management Interface」)。
最初に出した積み木に、それぞれの言葉を入れるとこうなります。
ここから下がCANの規格
NMフレームはAUTOSARが決めるもので、この積み木のさらに外側に付く。
ティールの2層がCANの規格の範囲です。調べていて話が噛み合わないと感じたら、その言葉がどの段にあるかを確かめてみてください。現場でもCANとダイアグ(診断)はひとまとめに語られることが多く、どの段の話をしているのかを先に揃えると噛み合うようになります。
なおAUTOSARやNMは製品や案件ごとに実装が違います。この記事では規格の位置づけまでにとどめます。
この記事の答え合わせ
同僚が「この車、診断で32バイトのデータを読んでるらしい」と言っています。CANのデータは最大8バイトのはずです。バスの上では何が起きているでしょうか。
答えを見る
流れているのは、8バイト以下のCANフレームが複数本です。「32バイトのCANフレーム」は存在しません。
CANの外側にあるISO 15765-2が、32バイトを最初のフレームと連続フレームに分割して送り、受信側が組み立て直しています。診断機の画面には32バイトのデータとして見えますが、バスの上ではあくまでCANのデータフレームが何本か流れているだけです。
なお、CAN FDなら1フレームで32バイト運べます。ただしそれには送受信の両側にCAN FD対応のコントローラとトランシーバが要ります。診断だからといって自動的にCAN FDになるわけではありません。
次に読む
CANのフレームは、自分が触るのはID、DLC、データの3つだけで、残りはコントローラが処理します。IDは名前であり優先度でもあり、その割り当ては規格ではなく設計です。そして「マルチフレーム」や「DID」はCANの上に載る別の規格の言葉でした。
ここまでが規格の話です。実際に動かしてみると、この形が手元のデータとして見えるようになります。
車の中でCANがどう使われているかを先に知りたい場合は、車載組込みソフトとは?仕事内容を現役エンジニアが解説をどうぞ。