CANは「Controller Area Network」の略で、主に自動車や船舶で機器間の通信に用いられる通信方式です。
一般的な接続方法を下図に示します。
この図ではバスの終端回路は省略しています。
なお、Armadillo-640は、CANでほかのノードと通信できます。
CANの主な特徴を以下に示します。
-
各ノードは対等
-
3つ以上のノードを接続可能
-
差動電圧方式による高いノイズ耐性
-
エラー処理等が規定されており、高信頼性
-
最高125kbps(ISO11898-2)
-
最高1Mbps(ISO1159-2)
CANの規格は、通信速度が125kbpsまでの低速CAN(ISO1159-2)、通信速度1Mbpsまでの高速CAN(ISO11898-2)が代表的です。
一般的にCANのノードは、SoCの外部のCANトランシーバ[]を通してバスに接続します。
CANの信号はCAN+とCAN-の電位差で表します。
ISO11898-2では、信号線の電位差がある状態(CAN+ > CAN-)がドミナント、ない状態がリセッシブとなります。
ドミナントを論理0、リセッシブを論理1として扱うことが一般的です。
CANはクロックを用いないため、あらかじめ全ノードに同じボーレート[]を設定しなければいけません。
データの転送は、フレームという単位でおこないます。
フレームには4つの種類があります。
表8.1 CANプロトコルフレーム
名称 | 機能 |
---|
データフレーム | データを送信する。 |
リモートフレーム | データフレームを要求する。 |
オーバーロードフレーム | 前回のフレーム処理が完了していないことを通知する。 |
エラーフレーム | エラーが発生したことを通知する。 |
データフレームとリモートフレームを合わせて、メッセージフレームといいま
す。CANでは、ノードごとのアドレスを持たず、メッセージが固有なID(識別子、Identifier)を持っています。
CANは全ノードが送信を開始できるため、複数のノードが同時に送信開始し、衝突が起こることがあります。
衝突した場合はドミナントが優先され、小さいメッセージIDのメッセージの送信が継続します。
大きいメッセージIDのメッセージを出力していたノードは送信エラーとなります。
受信ノードは、IDによって、自分が処理すべきメッセージかどうか判断します。
メッセージに含まれるIDの長さによって、メッセージフレームには標準フォーマット(11ビット長)と拡張フォーマット(29ビット長)の2種類の形式があります。
データフレームの形式を図8.3「CANプロトコル(データフレーム)」に示します。上の線
はリセッシブを、下の線はドミナントを意味します。データフレームは、デー
タを送信するノードがバスをドミナントにすることから始まります。これをス
タート・オブ・フレーム(SOF)と呼びます。SOFに続き、アービトレーション
フィールド(ARBI)、コントロールフィールド(CONT)、データフィールド(DATA)、
CRCフィールド(CRC)が順に送信されます。続いて、受信ノードはACKフィールド
(ACK)を送信します。最後に、7ビット以上リセッシブに保ちエンド・オブ・
フレーム(EOF)とします。
アービトレーションフィールドは、標準フォーマットか拡張フォーマットかに
よって異なります。標準フォーマットの場合、11ビットのIDを送信したあと、リモー
ト・トランスミッション・リクエスト・ビット(RTR)にドミナントを送信します。
拡張フォーマットの場合、11ビットのベースID(BASE ID)を送信したあと、代替リ
モート・リクエスト・ビット(SRR)、アイデンティファイヤ・エクステンション・
ビット(IDE)として、2ビット分バスをリセッシブに保ちます。続いて、18ビットの拡
張ID(Ext ID)を送信したあと、RTRにドミナントを送信します。
| CANプロトコルのバリエーション |
---|
CANプロトコルには、バージョン2.0Aと2.0Bの2つがあります。プロトコルバー
ジョン2.0Aでは、標準フォーマットしか扱うことができません。もし拡張フォー
マットのフレームを受信した場合、エラーフレームを送信します。プロトコル
バージョン2.0Bパッシブでは、拡張フォーマットの送信はできませんが、拡張
フォーマットを受信しても、無視します。プロトコルバージョン2.0Bアクティ
ブでは、拡張フォーマットの送受信が可能です。 Armadillo-640は、プロトコルバージョン2.0Bアクティブに対応してい
ます。 |
コントロールフィールドは、最初の2ビットが予約ビットとなっており、常にド
ミナントとします。続く4ビットのデータ長コード(DLC)に送信するデータのバイト
数を送信します。そのため、データフィールドは0~8バイト(64ビット)長となり
ます。
CRCフィールドのCRCシーケンス(CRC sequence)には、SOFからデータフィールド
までのCRC(Cyclic Redundancy Check)を送信します。CRCフィールドの区切りを
示すCRCデリミタとして、1ビット分リセッシブとします。
受信ノードは、受信したメッセージのCRCが一致した場合、ACKスロット(ACK
slot)でドミナントを送信します。ACKスロットでバスがドミナントとなること
で、送信ノードは少なくとも一つの受信ノードがデータフィールドを正常に受
信できたことを確認できます。ACKスロットに続いて、ACKフィールドの区切り
を示すACKデリミタ(ACK delimiter)として、1ビット分リセッシブとします。
リモートフレームは、データフレームの要求に使用されます。リモートフレー
ムを受信したノードは、リモートフレームで指定されたIDと同じIDのメッセー
ジを返信します。リモートフレームの形式を、
図8.4「CANプロトコル(リモートフレーム)」に示します。RTRをリセッシブにして、デー
タフィールドが無い以外、データフレームと同じです。DLCは、リモートフレー
ムへの返信として帰ってくるデータフレームのデータ長と同一にします。
メッセージフレームのアービトレーションフィールドという名前は、このフィー
ルド送信中にバスの調停をおこなうことに由来します。同時に複数のノードが
メッセージの送信を開始した場合、バスの衝突が発生します。送信ノードは、
各ビットでバスの状態を確認し、もし自身がリセッシブを送信したにも関わら
ず、バスがドミナントとなっていた場合、以後の送信を中止します。そのため、
より小さなIDが優先して送信されます。また、RTRにより、リモートフレームよ
りもデータフレームが優先されます。
オーバーロードフレームとエラーフレームは、一般にCANコントローラによって
自動で処理されます。そのため、ここでは説明を割愛します。
| 同期とビット・スタッフィング・ルール |
---|
CANでは、ビットレートに従ってデータの送受信をおこなうため、ノードごとの
クロックに誤差がある場合、タイミングが少しずつずれていきます。これを補
正するため、バスがリセッシブからドミナントへ変化するとき、タイミングの
同期をおこないます。 しかし、リセッシブやドミナントだけが続いた場合、この同期が行われないこ
とになります。そこで、ビット・スタッフィング・ルールが適用されます。こ
れは、同じ状態が5ビット連続した場合、反対の状態のビット(スタッフビット)を
一つ送信するルールです。このルールにより、一定期間内に必ず同期が行われ
ることを保証しています。 なお、ビット・スタッフィング・ルールの処理はCANコントローラで自動で行わ
れるため、ユーザー側は通常それを意識することはありません。 |
Armadillo-640では、CON9をCANバスとして使用することができます。
ここでは、Armadillo-640同士をCANで接続する方法を紹介します。
Armadillo-640に、CANトランシーバー回路を接続したものを2つ用意します。
Armadillo-640とCANトランシーバーを接続する回路図を示します。
ArmadilloのCON9から出ているCAN2を使用します。
CANトランシーバーには、AMIS-42673を使用します。
5V電源が必要となりますが、ArmadilloのCON9には5V電源が配線されていません。
そのため、TPS60130を用いて昇圧します。
Armadillo-640同士をCANで接続するので、同じ回路をもう1つ用意する必要があります。接続は次の通りです。
CANのドライバを有効にしたLinuxカーネルと、DTBを作成します。
標準状態のカーネルのソースコードを元に変更する手順は次の通りです。
-
Device Treeの編集
-
カーネルコンフィギュレーションでのCANの有効化
-
カーネルとDTBをビルドしArmadilloに書き込み
はじめにDevice Treeを作成します。ファイル名は arch/arm/boot/dts/armadillo-640-can2.dtsiです(「サンプルソースコード」のページからダウンロードできます)。
さきほどのファイルへのincludeをarch/arm/boot/dts/armadillo-640.dtsに追加してください。
続いて「イメージをカスタマイズする」と同様にmenuconfigを使用してカーネルコンフィギュレーションを変更します。
変更を加え、カーネルコンフィギュレーションを確定してください。
以上の変更後、「イメージをカスタマイズする」と同様にカーネルとDTBをビルドし、Armadilloに書き込んでください。
CAN通信プログラムのサンプルとしてcan-utilsを使用します。
can-utilsには、一つのメッセージを送信する
cansend、複数のメッセージを連続して送信する
cangen、受信したメッセージを表示する
candumpがあります。
can-utilsをインストールします。
実際に、CANバスを通じてArmadillo同士で通信をおこなう手順を説明します。
まず、通信速度を設定します。通信速度は送受信をおこなうノード全てで一致
している必要があるので、それぞれのArmadilloでおこなってください。
通信速度はipコマンドで設定します。以下の例では通信速度を125kbpsに設定しています。
次に、CANインターフェースを有効にします。これも、それぞれのArmadilloで
実行します。
CANメッセージを受信するArmadilloで、candumpを実行しておきます。
別のArmadilloでcansendを実行すると、一つのメッ
セージを送信できます。下記の例では、ID=0x5a5、デー
タ=0x01234567を送信しています。
candumpを実行している受信側のArmadilloでは、
下記のような受信結果が得られます。
また、cangenを実行すると、連続したメッセージ
を送信できます。オプションにCANインターフェース名だけを指定した場合、
cangenはアドレス、データ共にランダムな値を送
信します。
candumpを実行している受信側のArmadilloでは、
下記のような受信結果が得られます。