CANの活用

8.1. CANとは

CANは「Controller Area Network」の略で、主に自動車や船舶で機器間の通信に用いられる通信方式です。

一般的な接続方法を下図に示します。 この図ではバスの終端回路は省略しています。 なお、Armadillo-640は、CANでほかのノードと通信できます。

images/bus_structures/can_2node.svg

図8.1 CANの接続方法


images/bus_structures/can_3node.svg

図8.2 3つ以上のノードの接続方法


CANの主な特徴を以下に示します。

  • 各ノードは対等
  • 3つ以上のノードを接続可能
  • 差動電圧方式による高いノイズ耐性
  • エラー処理等が規定されており、高信頼性
  • 最高125kbps(ISO11898-2)
  • 最高1Mbps(ISO1159-2)

CANの規格は、通信速度が125kbpsまでの低速CAN(ISO1159-2)、通信速度1Mbpsまでの高速CAN(ISO11898-2)が代表的です。

一般的にCANのノードは、SoCの外部のCANトランシーバ[16]を通してバスに接続します。

CANの信号はCAN+とCAN-の電位差で表します。 ISO11898-2では、信号線の電位差がある状態(CAN+ > CAN-)がドミナント、ない状態がリセッシブとなります。 ドミナントを論理0、リセッシブを論理1として扱うことが一般的です。

CANはクロックを用いないため、あらかじめ全ノードに同じボーレート[17]を設定しなければいけません。

データの転送は、フレームという単位でおこないます。 フレームには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)とします。

CANプロトコル(データフレーム)

図8.3 CANプロトコル(データフレーム)


アービトレーションフィールドは、標準フォーマットか拡張フォーマットかに よって異なります。標準フォーマットの場合、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は、リモートフレー ムへの返信として帰ってくるデータフレームのデータ長と同一にします。

CANプロトコル(リモートフレーム)

図8.4 CANプロトコル(リモートフレーム)


メッセージフレームのアービトレーションフィールドという名前は、このフィー ルド送信中にバスの調停をおこなうことに由来します。同時に複数のノードが メッセージの送信を開始した場合、バスの衝突が発生します。送信ノードは、 各ビットでバスの状態を確認し、もし自身がリセッシブを送信したにも関わら ず、バスがドミナントとなっていた場合、以後の送信を中止します。そのため、 より小さなIDが優先して送信されます。また、RTRにより、リモートフレームよ りもデータフレームが優先されます。

オーバーロードフレームとエラーフレームは、一般にCANコントローラによって 自動で処理されます。そのため、ここでは説明を割愛します。

[注記]同期とビット・スタッフィング・ルール

CANでは、ビットレートに従ってデータの送受信をおこなうため、ノードごとの クロックに誤差がある場合、タイミングが少しずつずれていきます。これを補 正するため、バスがリセッシブからドミナントへ変化するとき、タイミングの 同期をおこないます。

しかし、リセッシブやドミナントだけが続いた場合、この同期が行われないこ とになります。そこで、ビット・スタッフィング・ルールが適用されます。こ れは、同じ状態が5ビット連続した場合、反対の状態のビット(スタッフビット)を 一つ送信するルールです。このルールにより、一定期間内に必ず同期が行われ ることを保証しています。

なお、ビット・スタッフィング・ルールの処理はCANコントローラで自動で行わ れるため、ユーザー側は通常それを意識することはありません。

8.2. CANを使用する

Armadillo-640では、CON9をCANバスとして使用することができます。 ここでは、Armadillo-640同士をCANで接続する方法を紹介します。

Armadillo-640に、CANトランシーバー回路を接続したものを2つ用意します。

[警告]

USBシリアル変換アダプタ(SA-SCUSB-10)を使用する場合、使用ピンの重複があるため、「コンソールに使用するUARTを変更する」に従ってコンソールに使用するUARTを変更してください。

8.2.1. 接続方法

Armadillo-640とCANトランシーバーを接続する回路図を示します。 ArmadilloのCON9から出ているCAN2を使用します。 CANトランシーバーには、AMIS-42673を使用します。 5V電源が必要となりますが、ArmadilloのCON9には5V電源が配線されていません。 そのため、TPS60130を用いて昇圧します。

CANトランシーバー回路図

図8.5 CANトランシーバー回路図


Armadillo-640同士をCANで接続するので、同じ回路をもう1つ用意する必要があります。接続は次の通りです。

CAN接続図

図8.6 CAN接続図


8.2.2. 対応カーネルイメージの作成

CANのドライバを有効にしたLinuxカーネルと、DTBを作成します。

標準状態のカーネルのソースコードを元に変更する手順は次の通りです。

  1. Device Treeの編集
  2. カーネルコンフィギュレーションでのCANの有効化
  3. カーネルとDTBをビルドしArmadilloに書き込み

はじめにDevice Treeを作成します。ファイル名は arch/arm/boot/dts/armadillo-640-can2.dtsiです(「サンプルソースコード」のページからダウンロードできます)。

&iomuxc {
        pinctrl_can2: can2grp {
                fsl,pins = <
                        MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x0b0b0
                        MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x0b0b0
                >;
        };
};

&can2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_can2>;
        status = "okay";
};

図8.7 armadillo-640-can2.dtsi


さきほどのファイルへのincludeをarch/arm/boot/dts/armadillo-640.dtsに追加してください。

#include "armadillo-640-lcd70ext-l00.dtsi"
#endif
#include "armadillo-640-can2.dtsi"        //追加行

/ {
        model = "Atmark Techno Armadillo-640";

図8.8 armadillo-640.dtsにincludeを追記


続いて「イメージをカスタマイズする」と同様にmenuconfigを使用してカーネルコンフィギュレーションを変更します。

[ATDE ~/linux-4.14-at[version]]$ make ARCH=arm menuconfig

図8.9 menuconfigの実行


[*] Networking support  --->
  [*]   CAN bus subsystem support  --->                 ← 有効にする
    CAN Device Drivers  --->
      [*] Platform CAN drivers with Netlink support
      [*]   Support for Freescale FLEXCAN based chips   ← 有効にする

図8.10 menuconfig


変更を加え、カーネルコンフィギュレーションを確定してください。

以上の変更後、「イメージをカスタマイズする」と同様にカーネルとDTBをビルドし、Armadilloに書き込んでください。

8.2.3. CAN通信プログラムの準備

CAN通信プログラムのサンプルとしてcan-utilsを使用します。 can-utilsには、一つのメッセージを送信する cansend、複数のメッセージを連続して送信する cangen、受信したメッセージを表示する candumpがあります。

can-utilsをインストールします。

[armadillo ~]# sudo apt install can-utils

図8.11 can-utilsのインストール


8.2.4. 使用例

実際に、CANバスを通じてArmadillo同士で通信をおこなう手順を説明します。

まず、通信速度を設定します。通信速度は送受信をおこなうノード全てで一致 している必要があるので、それぞれのArmadilloでおこなってください。

通信速度はipコマンドで設定します。以下の例では通信速度を125kbpsに設定しています。

[armadillo ~]# ip link set can0 type can bitrate 125000 loopback off

図8.12 CAN信速度設定


次に、CANインターフェースを有効にします。これも、それぞれのArmadilloで 実行します。

[armadillo ~]# ifconfig can0 up

図8.13 CANを有効化


CANメッセージを受信するArmadilloで、candumpを実行しておきます。

[armadillo ~]# candump can0

図8.14 candump実行開始


別のArmadilloでcansendを実行すると、一つのメッ セージを送信できます。下記の例では、ID=0x5a5、デー タ=0x01234567を送信しています。

[armadillo ~]# cansend can0 5a5#01234567

図8.15 cansendでのメッセージ送信


candumpを実行している受信側のArmadilloでは、 下記のような受信結果が得られます。

[armadillo ~]# candump can0
  can0  5a5   [4]  01 23 45 67

図8.16 candumpでのメッセージ受信結果


また、cangenを実行すると、連続したメッセージ を送信できます。オプションにCANインターフェース名だけを指定した場合、 cangenはアドレス、データ共にランダムな値を送 信します。

[armadillo ~]# cangen can0

図8.17 cangenでの連続メッセージ送信


candumpを実行している受信側のArmadilloでは、 下記のような受信結果が得られます。

[armadillo ~]# candump can0
  can0  567   [6]  69 98 3C 64 73 48
  can0  451   [8]  4A 94 E8 2A EC 58 55 62
  can0  729   [8]  BA 58 1B 3D AB D7 7E 50
  can0  1F2   [8]  E3 A9 E2 79 46 E1 45 75
  can0  07C   [2]  54 08
  :
  :
  :

図8.18 candumpでの連続メッセージ受信結果




[16] CANの差動信号と、SoC等が扱いやすいシングルエンド信号を相互に変換します。

[17] デジタルデータを変調・復調する速さ