温故知新 IEEE802シリーズで EtherCAT を眺め直す

この記事は [EtherCATについて語る Advent Calendar 2019](https://adventar.org/calendars/4097)の2日目です。
昨日は[Yuta Kitagami](https://github.com/nonNoise)さんの [EtherCATについて（定型説明文）](https://github.com/nonNoise/EtherCAT_Advent_Calendar_2019/blob/master/2019_12_01.rst) でした。

# はじめに
EtherCAT の動作を知るとオールドタイマな方はなんだかデジャヴュな感じになることがあると思います。EtherCAT でのフレームの処理の仕方は独自ということはなく、トークンパッシングという古くからある考え方に基づいています。ここでは IEEE802 にあるトークンパッシング型の LAN技術を例に EtherCAT の動作との比較を行ってみます。

# IEEE802 について
[IEEE802](http://www.ieee802.org) は [IEEE](https://www.ieee.org/) が定める国際標準のなかで LAN (Local Area Network) の技術規格を定めるものです[^MANPAN]。この規格は、技術の内容によってさらに分類されています。よく知られているのは、有線LANのいわゆるEthernetを定義する [IEEE802.3](http://www.ieee802.org/3/) や、無線LANのいわゆるWiFiを定義する [IEEE802.11](http://www.ieee802.org/11/) です。EtherCAT に関係しそうな規格を以下に示します。

[^MANPAN]: LAN の他 MAN (Metropolitan Area Network) や PAN (Personal Area Network) の標準も定めています。

- [IEEE802.3](http://www.ieee802.org/3/): イーサネット (Ethernet)
- [IEEE802.4](https://standards.ieee.org/standard/802_4-1990.html): トークンバス (Token Bus)
- [IEEE802.5](http://www.ieee802.org/5/www8025org/): トークンリング (Token Ring)

物理的なトポロジーは、トークンバスが同軸ケーブルにいくつものノードを繋ぐ形でつまり一直線上にノードが並ぶような線形構造で、トークンリングが環状の構造です。イーサネットはもともとは同軸ケーブルを全てのノードで共有する 10BASE5 や 10BASE2 と言った線形の構造が原型です。1000BASE-X からはケーブル自体を3ノード以上で共有することはなくなり、1対1のノード接続をするか、HUB を中心とするスター状の構造を取るようになりました。

## IEEE802.5 トークンリング (Token Ring)
トークンリングもトークンバスもトークン (token) と呼ばれるデータを格納するためのコンテナをノード間でやりとりして情報を交換します。規格の番号とは逆になりますが、番号の大きいトークンリングから見ていきます。

ここでは簡単のために、MAU (Media Access Unit) と呼ばれるケーブル接続の装置に1つだけホストが接続している例で説明します。トークンリングは全体では図のような構成をとります。
![Ring_netwerk_topologie_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/cd8da14f-24cc-cf97-c785-8ca5e59bb881.png)

このなかで一つのトークンをやり取りします。

- ホストはつながってる片方のホストからトークンがやってきたら一旦受け取ります
- トークンの中に自分に関係する情報があるかを調べます
 - 自分宛ての情報があれば、それを受信バッファに取り込みます
 - 自分発の情報があれば、それを宛先ノードを付けてトークンに書き込みます
 - 特に自分に関係がなければトークンをそのままにしておきます
- つながっているもう一方のホストに向けてトークンを送信します

これを繰り返すとトークンがネットワーク全体をぐるぐる回ります。どのホストからも希望するホストに情報を渡すことができます。host A から host C に情報を渡す場合は次のように動作します。

![token-ring.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/5e7d572b-a200-f185-6dc5-e4e77b4f0c85.jpeg)

このようにトークンをぐるぐる回すことでノード間での情報交換をします。EtherCAT をご存知のみなさんはすでにビビビっと来ていることと思います。

<!--
トークンリングでは、隣のホストと接続ができているかを電気的に検出することができます。線が切れていれば隣と通信できません。これを検出した場合には、余っているもう1本を使ってリングが切れないようにすることができます。

この冗長性は FDDI や CDDI といったネットワーク技術でも用いられています。
-->

## IEEE802.4 トークンバス (Token Bus)
トークンリングの欠点は、ケーブルを物理的に環状に配置しないとならないことです。トークンバスは1本の同軸ケーブルでトークンをやりとりします。配線の面倒さはぐっと減ります。

![token-bus-0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/e0342bdd-7642-dc5d-b14d-3dfd29b57668.jpeg)

トークンバスでもトークンは各ホストを順番に巡回します。これはイーサネットと違うところです。ホストAからホストCに情報を渡すことを考えてみます。同軸ケーブルを想定してください。つまりデータを送信するホストの出力信号を、全部のホストが同時に受信して中身を見ているということです。

トークンバスの場合は以下のように情報を渡します。

- ホストAがトークンを送信する
 - バスにトークンを乗せるので全てのホストが受信可能である
- ホストBがトークンを受信する
 - ホストBが宛先の情報がなく、かつホストBは今送りたい情報がない
 - ホストCはホストAが送信しているのを知っているが自分の順番ではないので受信しないで無視する
 - ホストDとホストEもAからのトークンが自分宛てでないので無視する
- ホストBがトークンを送信する
- ホストCがトークンを受信する
 - 自分宛の情報があるのでそれを取り込む
- ホストCがトークンを送信する
- ...

![token-bus-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/1f0cbbf9-f27d-59e3-13b5-3709d610e7a5.jpeg)
![token-bus-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/4871493e-551a-61fc-6a76-f206715c5419.jpeg)
![token-bus-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/13148f5f-cf66-8ccd-dc07-ab892d032f7d.jpeg)
![token-bus-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/7436cd6f-1485-461a-6788-5b060ba754f9.jpeg)
![token-bus-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/592c87a7-866f-af45-723f-ca32bfee5db7.jpeg)

このように、通信媒体を全てのホストでシェアしていても、トークンを順番に回す動作をして情報をやりとりします。トークンを回す順番は必ずしも物理的な接続の場所と関係しないので、ホストに論理的な順番を決めておいて仮想リング (virtual ring) と呼ばれる構造を作り、そこをトークンが巡回するようにします。

## トークンパッシング方式の利点と欠点
トークンパッシングの利点の一つは通信時間に制約をつけられることです。基本的に一つのホストからトークンが発せられて一周して戻ってくるまでの時間が最大の通信時間になります。ですので基本的に産業用途に向いています。

しかしながらトークンリングの場合は環状に接続を行なわないとならないので配線の取り回しが簡単とは言えません。

また、トークンバスの場合は、どこかのホストがネットワークから外れてしまったことを検出できません。ここから私の想像が入りますが、このため障害を検出して仮想リングを再構成するのは特別な機構が必要となるでしょう。障害を検出したらただ折り返せば良いトークンリングと違ってトークンバスの方が全体として複雑な動作が必要になるかなと言う印象を受けます。

## 媒体共有型のイーサネット (Ethernet)
同軸ケーブルを共有するような媒体共有型 (shared media) のイーサネットの場合（同軸ケーブルを使う 10BASE5 や 10BASE2、さらにスイッチングHUBでないようなダムHUBを使ってる場合の 10BASE-T や 100BASE-TX が該当）は、同じトポロジーでも通信の動作は以下のようになります。

- ホストAがフレームを送信する
 - このとき宛先EthernetアドレスとしてノードCを指定しておく
 - 全てのホストはこのフレームを受信する
- ホストCが自分宛てと判断してフレームを受信する
 - 他のホストは宛先が自分ではないので無視する
![ethernet.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/721fe541-52c2-e81a-ffc8-7dd670d81fd2.jpeg)

このように1回の動作で目的のホストへの通信が完了します。トークンバスのように何度もホストを経由しないと届かないということはありません。しかしながら、トークンバスの場合は、複数のホストが同時にトークンを送出することがないので、トークンの衝突はありません。一方、イーサネットの場合は複数のホストが同時に送信を始める可能性があるので、CSMA/CD なる特別な工夫が必要です。

- 他のホストが通信をしてないかをあらかじめチェックする CS (Career Sense)
- 他に誰も通信していないならどのホストも通信を開始して良い MA (Multiple Access)
- 送信中に他のホストの送信とぶつかったら送信をやめる CD (Collusion Detection)
- 次に送信する際にはホストごとにランダムに待ち時間を取ってなるべくぶつからないようにする

## いまどきのイーサネット
CSMA/CD 方式は通信の衝突があることを前提にしており、このため一定時間内に必ず通信を完了するというような保証ができないことに注意してください。

イーサネットは伝送速度が1Gbpsの1000BASEの規格からは1対1のケーブリングとスイッチングHUBだけに限定することで、通信媒体を共有するような物理構造をとらなくなりました。そのため CSMA/CD を使うことはなくなりました。また、10BASE-T や 100BASE-TX をスイッチングHUBで接続する場合は、個々の区間では2つのノードのみが接続されてそれぞれ送受信が独立した線で行われますので、実質的には衝突が起こりません。

# EtherCAT の構造
ここまでトークンリング・トークンバス・イーサネットを見てきました。どれも一長一短があります。改めて要求をまとめると以下になります。

- 最悪の場合の通信遅延に制約を設けることができる
 - CSMA/CDを用いるイーサネットではできない
- 通信するノード数に制約がない
 - CSMA/CDを用いないイーサネットは基本的に2ホストの接続のみで、それを超える数の接続はHUB等の追加デバイスが必要になる
- 配線が線形にできる
 - トークンリングではできない
- ノードの接続や離脱が直ちに検出できる
 - トークンバスやCSMA/CDを用いるイーサネットではできない

これを全部可能にするのが EtherCAT です。

## トークンリングを潰してリンクをポイント-ポイントのEthernetにする

上で示した要求条件でトークンリングが満たせないのは「線形の構造を持つ」というところだけで後は満たしています。EtherCAT は私にはトークンリングを変形することで実現できたように思えるのです。以下がトークンリングを簡略化した図です。

![EtherCAT1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/d8d61001-b319-14ac-c843-9829f3469bc0.jpeg)

これをちょっと潰してホストも寄せてみます。
![EtherCAT2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/9a56914e-6776-bf54-c6c8-f62f0aa09a81.jpeg)

さらに潰して平たくします。
![EtherCAT3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/f8f75522-d576-eb17-f8bd-b107a27cbab7.jpeg)

ここまで来たら一直線にしてしまいましょう。
![EtherCAT4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/8bd25621-47df-fecb-6081-ac46a2ead97f.jpeg)

帰りのリンクが途中のホストを突っ切って通過することができるものとします。
![EtherCAT5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/5ec5f71e-56b7-855a-0d8a-be43e341c27f.jpeg)

ホスト間を往復する通信をポイント-ポイントの（衝突の起こらない）イーサネットにしてみましょう。ついでに一番左を Master と名付けて、のこりを Slave とし、一番右の Slave は自分の出力を Master に直接返すものとします。
![EtherCAT6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260320/11e58ac0-e358-eb9c-7ed9-757aad7e318f.jpeg)
はい、EtherCAT の出来上がり。

# まとめ
トークンパッシングとイーサネットの基本動作と利点欠点を見てみました。EtherCAT はトークンリングを変形した形状で、各ノード間を接続する通信媒体をイーサネットにしたかのような構成を持っています。EtherCAT はいくつかの産業用の要求事項をすべて満たします。


| LAN技術 | 遅延の制約 | トポロジー | ノード数限定 | 構成変化の検出 |
|:------:|:--------:|:---------:|:---------:|:---------:|
| EtherCAT | 可能 | 線形 | なし[^Ethercat] | 可能 |
| Token ring | 可能 | *環状* | なし[^Tokenpassing] | 可能 |
| Token bus | 可能 | 線形 | なし[^Tokenpassing] | *不能* |
| Ethernet[^csmacd] | *不能* | 線形 | なし[^ethernet] | *不能* |
| Ethernet[^p2p] | 可能 | 線形 | *2ノード*[^hub] | 可能 |

[^Ethercat]: 拡張しない形の EtherCAT では最大65535ノード。
[^Tokenpassing]: 調べた範囲で最大数の制約が見つけられなかった。
[^csmacd]: CSMA/CD を用いる場合。
[^ethernet]: 最大のケーブル長の制約とノード間の距離の制約による限界がある。
[^p2p]: CSMA/CD を用いない場合(1000BASE以上)か、もしくは2ノードに限定して衝突を起こさないような形態で(100BASE-TX等を)利用する場合。
[^hub]: 2ノード以上を同一LANとして接続するには、ノード以外に HUB が必要。

## さらなる温故知新：障害対応と冗長性について
トークンリング同様に環状で通信する規格には FDDI/CDDI という技術があります。これはリングを二重にしており、ノード間のどこかが障害で切れてしまっても、通信を維持するような工夫がしてあります。
EtherCAT で端にあるマスタと逆側の端にあるスレーブを、独立したEthernetケーブルで接続して環状にすることで、冗長性をもたせて耐障害性を上げることができます。
これも FDDI のリングを潰して平たくしたのと同等の構造を持ちます。興味のあるかたは調べてみてください。

明日の EtherCATについて語る Advent Calendar 2019 3日目の記事は、@nonNoise さんの[EtherCATスレーブに使える半導体 (1)](https://qiita.com/nonNoise/items/8caacbaae9d31ffd63e4) です。こちらもお楽しみに！

# 参考文献
[EtherCAT Techonlogy Group](https://www.ethercat.org/jp.htm)
[WikiPedia IEEE 802](https://en.wikipedia.org/wiki/IEEE_802)
[WikiPedia FDDI](https://en.wikipedia.org/wiki/Fiber_Distributed_Data_Interface)