CANプロトコル
CANプロトコルの基本情報
CAN(Controller Area Network)は、ドイツのBOSCH社が自動車のために開発したシリアル通信プロトコルです
CAN通信は、そのシンプルさと、正確なデータ送信で世界中の自動車やロボットに採用されています
バージョン
いくつかありますが、本記事では、基礎となるCAN2.0Bについて解説します CANの通信規格は、国際標準化機構(ISO)で定義されている
後方互換性は一応あります
| 名称 | 規定 | 速度 | コメント |
|---|---|---|---|
| 低速CAN | ISO11898-3 | 500Kbps | Fault-Toleranceにリソースを振ったもの |
| CAN 2.0(高速CAN) | ISO11898-2 | 1Mbps | これがノーマルです |
| CAN FD | ISO11898-1 | 8Mbps | これはチョット速い |
| CAN XL | ISO11898-1 | 20Mbps | これはモット速い |
CANの特徴
- バス型+マルチマスター方式
- 半二重通信
- ノイズ耐性
- 通信速度1Mbps
バス型+マルチマスター方式
CANでは通信線のことを「バス」、繋ぐデバイスのことを「ノード」と呼びます
ノードは全部マスタみたいなものなので、ノード自体に優位性はありません
「バスはUSBハブ」、「ノードはUSBメモリ」のようなイメージで考えると分かりやすいかもしれません
しかし、複数のデバイスが双方向に通信を行うため、反射による通信エラーが発生する場合があります
よって、バスの終端には終端抵抗を挟む必要があり、値はケーブルの公称インピーダンスに一致する必要があります(120Ω程度)

半二重通信
送信と受信を同じ線を使って、交互に通信を行います
ノイズ耐性
ハードウェア
- 差動通信(2本線(ツイストペア)の各線に流れる電圧の差)のためノイズに強いです

ソフトウェア
- エラーを何度も発したら通信から隔離する
- もし1台のノードが受信に失敗したら、データを受信できた全ノードはそのデータを破棄し、全ノードが受信に成功するまでこれを繰り返す
- 送信エラーが発生した場合、永久に再送信する
- 2つのノードが同時に送信を行った場合、IDが大きいノードが、送信を取りやめ、受信モードに移行する。IDが小さいノードがメッセージを送信し終えた後にメッセージを再送する
通信速度1Mbps
最高で1秒間に1000000ビット送信可能
CANのプロトコル
OSI基本参照モデル
CANプロトコルはOSI基本参照モデルの、トランスポート層、データリンク層、物理層の各層で規定を設けています
| OSI基本参照モデル | ||
|---|---|---|
| ソフトウェア | 7 | アプリケ-ション層 |
| 6 | プレゼンテーション層 | |
| 5 | セッション層 | |
| 4 | トランスポート層 | |
| 3 | ネットワーク層 | |
| ハードウェア | 2 | データリンク層 |
| 1 | 物理層 |
トランスポート層の定義内容
トランスポート層では、再送制御のみを定義しています
これは、送信エラーが発生した場合に確実にデータを再送信する「永久リトライ」という機能にあたります
データリンク層の定義内容
データリンク層では、
- 理論リンクLLC(Logic Link Control)サブ層
- 媒体アクセス制御MAC(Medium Access Control)サブ層
細分化され、主に
- 電気的なパルス信号からフレームへの変換
- データ衝突時のアービトレーション
- データ送信時の確認を行うACK応答
- 各種エラー検出や通知
などが定義されています
物理層の内容定義
物理的な特性や仕様を定義する物理層では、
- ビットの同期・再同期やサンプリング・ポイントなどのビットタイミング
- トランシーバやバスの特性
について規定されていますが、コネクタやケーブルの形状について規格化されていません
アービトレーション(通信調停)
メッセージを送信するノードは通信バスの電圧を監視します(送信したデータが本当にバスに流れているかを1bitずつ確認)
2つのノードが同時に送信を行った場合、
- IDが大きいノードは、送信を取りやめ、受信モードに移行し
- IDが小さいノードは、メッセージを送信し終えた後にメッセージを再送します
この仕組みのことをアービトレーション(通信調停)といいます
ビットスタッフィング
CANは信号の立ち下がりを検出することで、他ノードとのタイミングを調整し同期を取ります
そのため1または0の信号がずっと続くとタイミングの調整ができません
この同期ずれを防ぐために、CAN通信では5連続した0または1を送信したら、その反転ビットを挿入しなければならないという仕様になっています
この仕様をビットスタッフィングといい、挿入されるビットをスタッフビットといいます

フレーム
| フレーム | フレームの役割 |
|---|---|
| データフレーム | 送信ノードが受信ノードへメッセージを送る時に使用する |
| リモートフレーム | 受信ノードが特定の送信ノードへメッセージの送信を要求する時に使用する |
| エラーフレーム | エラーを検出した時に他ノードへ通知する時に使用する |
| オーバーロードフレーム | 受信ノードが受信準備未完了を通知する時に使用する |
| インターフレームスペース | データフレームおよびリモートフレームを前のフレームと分離させるために使用する |
データフレーム
標準フォーマット
ID部(Base ID)が11bit

拡張フォーマット
ID部(Base ID)が29bit

データ部
1パケット8byte
リモートフレーム
データフレームからデータ部を抜いたやつ
その他フレーム
今回は省きます
CANの配線長
CANのハブ間はある程度伸ばしても大丈夫ですが、速度で変わってきます

| バス速度 | バス長(L) | ケーブルスタブ長(l) | ノード間距離(d) |
|---|---|---|---|
| 1 Mbit/秒 | 40 m (131 feet) | 0.3 m(1 foot) | 40 m(131.2 feet) |
| 500 kbits/秒 | 100 m(328 feet) | 0.3 m(1 foot) | 100 m(328 feet) |
| 100 kbits/秒 | 500 m(1640 feet) | 0.3 m(1 foot) | 500 m(1640 feet) |
| 50 kbits/秒 | 1000 m(3280 feet) | 0.3 m(1 foot) | 1000 m(3280 feet) |
STM32のCAN
ここからSTの仕様について説明します
特にF3とF4のCANについて説明しますが、F3のCANはF4とほぼ同じであるため、基本的にF4について説明します
STのCANは他の通信と違って、DMAがないため割り込みで使用します
理由としては、
- 連続的に使用することを想定されていない
- 超高速通信ではない
- IDの優先度と競合する
などが考えられます
F4とF3の違い
F4にはCANが2つ搭載されていますが、F3には1つしかありません
それぞれ以下のCANを有します
F4
- CAN1: マスタCAN1個 + スレーブCAN1個
- CAN2: スレーブCAN1個
F3
- CAN1: マスタCAN1個 + スレーブCAN1個
マスタCAN = スレーブCAN + 受信フィルタ制御機能
なので、CAN2の受信フィルタ設定はCAN1のマスタCANが行う感じになっています
動作モード
- 初期化モード
- 通常モード
- スリープモード
- テストモード
- サイレントモード
- ループバックモード
- デバッグモード
があります
実際に遷移するモードは、初期化モード、通常モード、スリープモードのみであり、他はデバッグなどで使用される場合もあるかもしれないかもかもないかもしれません
送信
送信は以下の手順で行います
- 送りたい内容をメールボックスにいれる
- 送信レジスタの送信リクエストビットをセットし、保留中になる
- 最高優先順位になったら送信される
送信のメールボックスはスレーブCANごとに3つあり、3つ目以降のメッセージの処理は以下のどちらかを設定できます
- メールボックスをロックし、4つ目以降は消える
- 1つ目のメッセージを押し出し、4つ目を加える
メールボックスの優先順位は以下のどちらかを設定できます
- メッセージIDの小さいパケットが優先(IDが同じ場合はメールボックス番号の小さい方)
- メールボックスに早く入れた方が優先
また、以下のモードを使用することもできます
- 自動再送信禁止モード: 送信に失敗したメッセージも送信成功とみなし、一度しか送信しない
- タイムトリガ通信モード: ハードウェアでタイムスタンプを生成し、付与する
受信
受信は以下の手順で行われます
- CANバスのメッセージを見る
- 受信フィルタを見て、自分へのメッセージである場合は、フィルタで指定されるFIFO(バッファ)に入れる
- そのFIFOの受信割込み関数が呼ばれる
受信のFIFOはスレーブCANごとに2つあり、2×3で合計6つのメッセージを貯めておくことができます
STのCANの受信は、受信割込みを使用します
受信割込み関数の設定は、FIFOごとにします
また、3つ目以降のメッセージへの処理は以下のどちらかを設定できる
- FIFOをロックし、4つ目以降は消える
- 1つ目のメッセージを押し出し、4つ目を加える
受信で一番重要なのは、受信フィルタの設定です
そのため、別にまとめます
受信フィルタ
受信フィルタとは、ID(識別子)によって、
- 受信するか
- どのFIFOに入れるか
を制御する機能です
ハードウェアで制御されるため、無駄なパケットを受信して、割り込み関数が実行されるということを防ぐことができます
フィルタは28(0~27)個あり、マスタCANが制御します
CAN2がある場合は、CAN_FMRで 0~27 のどこからをCAN2に割り当てるか設定します
フィルタでは、マスクレジスタと識別子レジスタを一つずつ使用します
フィルタには以下の2つのモードがあります
- マスクモード: マスクレジスタで指定した部分が、識別子レジスタで指定した値の場合だけ通す(マスクで指定されていないビットはどんな値でもいい)
- リストモード: 完全にIDが一致したときのみ通す(マスクレジスタも識別子レジスタとしてみなすため、2倍(56個)の完全一致フィルタがある状態になる)
標準フォーマットと拡張フォーマットは、以下の図のIDEビットで識別できるため、一つのバスに混同可能です
ちなみに、RTRはデータフレームかリモートフレームかを示すビットです
また、32ビットと16ビットの2つから選択でき、以下の図のようになっています
細かいことを言うと、1つのIDが複数のフィルタを透過する場合があり、この時は以下の優先順位で分類されます
- 32ビットフィルタ > 16ビットフィルタ
- リストモード > マスクモード
- フィルタ番号 小 > 大

F4のCANブロック図

ビットタイミング
データの最小単位は1ビットですが、CANはこの1ビットをさらに4つに分けています

端的に言うと、1ビットの長さを決定する機能です
主にCANの同期で使用されます
各セグメントのTq(TimeQuantum)を長くすると、遅延や誤差に対し強くなります
しかし、1ビットの長さが長くなってしまうため、転送速度が遅くなってしまいます
それぞれのセグメントの意味は以下の通りです
- SYNC_SEG: これでずれてるか判断する(1Tq固定)
- PROP_SEG: ここでネットワーク全体の信号遅延を補正する
- PHASE_SEG1: クロック誤差を補正
- PHASE_SEG2: クロック誤差を補正
また、修正にはSJW(1Tq~4Tq)という値を利用します
STでは3つに分けています(つまり、BS1 = PROP_SEG + PHASE_SEG1)

これは以下の図のように利用されます
早い場合は、BS1もといPROP_SEGを拡張し、同期させていることがわかります
遅い場合は、BS2もといPHASE_SEG2を縮小し、同期させていることがわかります

STでは以下の制約を満たすように値を決定します
- 目的の通信速度(50kbps~1Mbps)で動作可能 ()
- 目的のサンプルポイントあたり(50%以上)になるように調整
SYNC_SEGは1Tq (APBクロック×1~4)
BS1は1~16Tq
BS2は1~8Tq
→CANに供給するクロックと、SJWと、サンプルポイントの割合と、通信速度をkbps単位で入力すると、自動で計算してくれるサイトです