Ethernetの仕組みとデバイスドライバ

本記事では、主に組み込み開発においてEthernetがどのようなハードウェアの構成になっていて、組み込み開発としてどのようにデバイスドライバに必要な情報を入手していくかをまとめたものです。

Ethernetの仕組みや組み込み開発デバイスドライバに関して興味がある方に呼んでいただけると幸いです。

## Ethernetとは

Ethernetは、Ethernetケーブルの規格を示します。ただ、昨今ではEthernetケーブルで接続したデバイス同士がIEEE802.3の規格に則って通信を行うような、有線LAN自体を指すことも多いです。
IEEE802.3とは、Ethernetに関する技術を標準化するための規格です。この規格に則ってハードウェアが作成されていれば、Ethernetケーブルを接続した異なるデバイス間で通信が可能になります。
一口にIEEE802.3と言っても、使用するケーブルや最大通信速度によって細かな種類の規格に分かれており、例を挙げると下記のようなものがあります。

- 100 Base-TX(IEEE802.3u)
- 1000 Base-T(IEEE802.3ab)

上記の例で言えば、先頭の「100」「1000」というのは最大通信速度を示します。「BASE」は伝送方式を示し、「TX」「T」はケーブルの種類が示されています。
デバイスドライバ開発としては全て知っているに越したことはありませんが、先頭の数値が最大通信速度ということだけでも頭に入れておくとよいでしょう。


## Ethernetのハードウェア構成

Ethernetにおける物理層は、伝送距離や通信速度によって使用するケーブルが分かれております。そのため、このケーブルの違いをソフトウェアが意識せずに通信できるようになっています。ハードウェアの構成は下記の図のようになっております。

![ハードウェア構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/8f85c0d0-455e-759f-3eea-4a81fbf6f534.png)


上記の図の「Ethernet PHY」は物理層のことを指します。Ethernetケーブルで使用するアナログ信号とCPUで使用するデジタル信号を相互変換する機能を持ちます。ここが、伝送距離・通信速度によってハードウェアが変わります。そして、このハードウェアの違いをソフトウェアで意識させないようにするのがMII(Media Independent Interface)です。こちらは後述します。
Ethernetのデバイスドライバでは、上記の図のEthernet PHYの設定・管理と、データ通信に関する設定・管理を主に行います。
ちなみに、Ethernet PHYは各社マイコンメーカが販売している評価ボードに搭載されているものの、マイコンメーカが製造したものではないことも多いです。よって、Ethernet PHYの設定のためには、評価ボードなどのハードウェアの仕様書や回路図からEthernet PHYの型番を調べ、仕様書を探すこともしばしばあります。

### MII(Media Independent Interface)

MII(Media Independent Interface)は物理層となるEthernet PHYとCPUでの通信を行うための規格です。この規格に対応していれば、CPUはEthernet PHYの仕様に依存せずにMIIに沿った通信を行うことができます。
また、MIIにもいくつか種類があるのでそれを説明しておきます。余談ですが、組み込み開発で扱われる評価ボードだと、RMIIやRGMIIが使われていることが多いです。

#### MII(Media Independent Interface)

10/100 Mbpsに対応する規格です。クロックと4bit幅のデータパスによって通信を行います。
必要な信号は下記になります。Ethernetのデバイスドライバを作成する場合、下記の信号と対応するピンの設定を行う必要があります。

- 送信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| TX_CLK |  送信クロック  | PHY→CPU(MAC) |
| TXD0～TXD3 |  送信データビット0～3 | CPU(MAC)→PHY |
| TX_EN |  送信中はハイが保持され、アイドル状態ではローとなる  | CPU(MAC)→PHY |
| TX_ER | 送信エラーを検知する。オプションの信号のため、設定が必要ない場合はローで固定する  | CPU(MAC)→PHY |

- 受信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| RX_CLK |  受信クロック  | PHY→CPU(MAC) |
| RXD0～RXD3 |  受信データビット0~3 | PHY→CPU(MAC) |
| RX_DV |  受信中はハイが保持され、アイドル状態ではローとなる  | PHY→CPU(MAC) |
| RX_ER | 受信エラーを検知する。TX_ERと違い、こちらは必須  | PHY→CPU(MAC) |
| CRS | キャリア検知(半二重通信のみ)。パケット送受信中または他機器が通信中で伝送路が使えない場合にハイとなる。 | PHY→CPU(MAC) |
| COL | 衝突検出(半二重通信のみ)。パケット衝突検出や衝突継続中にハイにする。 | PHY→CPU(MAC) |

- 管理用信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| MDIO |  管理データレジスタ(MDIOレジスタ)設定・レジスタ値取得 | 双方向 |
| MDC |  管理データ用クロック| CPU(MAC)→PHY |

#### RMII(Reduced Media-Independent Interface)

10/100 Mbpsに対応する規格で、MIIで使用する信号を減らすために作られた規格です。
必要な信号は下記になります。クロックの周波数を上げることで信号数を減らしています。

- 送受信における共通信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| REF_CLK |  50MHzクロック | CPU(MAC)→PHY or 外部クロックソース→CPU(MAC)・PHY |

- 送信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| TXD0～TXD1 |  送信データビット0～1 | CPU(MAC)→PHY |
| TX_EN |  送信中はハイが保持され、アイドル状態ではローとなる  | CPU(MAC)→PHY |

- 受信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| RXD0～RXD1 |  受信データビット0～1 | PHY→CPU(MAC) |
| RX_DV |  受信中はハイが保持され、アイドル状態ではローとなる  | PHY→CPU(MAC) |
| RX_ER | 受信エラーを検知する。TX_ERと違い、こちらは必須  | PHY→CPU(MAC) |
| CRS_DV | CRSとRX_DVの信号を交互に出力 | PHY→CPU(MAC) |

- 管理信号

MIIと同じのため省略

#### GMII(Gigabit Media-Independent Interface)

1000Mbpsに対応する規格で、MIIから信号数を増やし、クロックの周波数を上げることで1000Mbpsに対応しています。必要な信号は下記になります。

- 送信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| GTXCLK |  1Gbps用送信クロック(125MHz)  | CPU(MAC)→PHY |
| TXCLK |  10/100Mbps用送信クロック(2.5/25MHz)  | PHY→CPU(MAC) |
| TXD0～TXD7 |  送信データビット0～7 | CPU(MAC)→PHY |
| TX_EN |  送信中はハイが保持され、アイドル状態ではローとなる  | CPU(MAC)→PHY |
| TX_ER | 送信エラーを検知する。オプションの信号のため、設定が必要ない場合はローで固定する  | CPU(MAC)→PHY |

- 受信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| RX_CLK |  受信クロック  | PHY→CPU(MAC) |
| RXD0～RXD7 |  受信データビット0~7 | PHY→CPU(MAC) |
| RX_DV |  受信中はハイが保持され、アイドル状態ではローとなる  | PHY→CPU(MAC) |
| RX_ER | 受信エラーを検知する。TX_ERと違い、こちらは必須  | PHY→CPU(MAC) |
| CRS | キャリア検知(半二重通信のみ)。パケット送受信中または他機器が通信中で伝送路が使えない場合にハイとなる。 | PHY→CPU(MAC) |
| COL | 衝突検出(半二重通信のみ)。パケット衝突検出や衝突継続中にハイにする。 | PHY→CPU(MAC) |

- 管理信号

MIIと同じのため省略

#### RGMII(Reduced Gigabit Media-Independent Interface)

1000Mbpsに対応する規格で、GMIIで使用する信号を減らすために作られた規格です。
必要な信号は下記になります。クロックの立ち上がりエッジと立下りエッジで送受信することにより、必要な信号数を減らしています。

- 送信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| TXC |  送信クロック  | CPU(MAC)→PHY |
| TXD0～TXD3 |  送信データビット0～3 | CPU(MAC)→PHY |
| TX_CTL | TX_ENとTX_ERの双方の信号 | CPU(MAC)→PHY |

- 受信信号

|  信号  |    概要    | 通信方向 |
| ------------- |  -------------------- | -------------------- |
| RX_C |  受信クロック  | PHY→CPU(MAC) |
| RXD0～RXD3 |  受信データビット0~3 | PHY→CPU(MAC) |
| RX_CTL | RX_DVとRX_ERの双方の信号 | PHY→CPU(MAC) |

- 管理信号

MIIと同じのため省略

## Ethernetのデバイスドライバ開発

実際のEthernetのデバイスドライバ開発において、何が必要かを説明していきます。

### Ethernetドライバに必要なもの

まず、Ethernetのデバイスドライバに求められる機能を下記に挙げます。

- MDIOのレジスタ設定
- SoC(もしくはマイコン)のEthernetに関連するレジスタ設定
- 送受信に使用するバッファの管理・設定
- 割り込み設定

また、デバイスドライバの責務とは離れるのですが、Ethernetを動作させるうえで、下記の設定も必要です。

- 信号と対応するピン設定
- クロック供給

このあたりの情報について、STマイクロエレクトロニクス社製の評価ボード「NUCLEO-F429Zi」を例に、どの情報がどこに書かれているのかを示していきます。
また、この記事はあくまでSTマイクロエレクトロニクス社製の評価ボードにおけるデバイスドライバの開発を行う際の説明となります。他のメーカーになるとドキュメントの構成が違うこともあるので、ご注意ください。

### リファレンスマニュアル

Ethernetのデバイスドライバを開発するうえで、まず必要となるのは下記のドキュメントです。これらについて説明します。

- ハードウェア(評価ボード)のリファレンスマニュアル
- 評価ボードに搭載されているマイクロコントローラのリファレンスマニュアル
- 回路図
- 評価ボードに搭載されているEthernet PHYのリファレンスマニュアル(データシート)

#### ハードウェアのリファレンスマニュアル

ハードウェアのリファレンスマニュアルは、Ethernetがハードウェアとしてどのような構成となっているかを示します。「NUCLEO-F429Zi」の例を挙げると、下記のようにEthernetの説明があります。

![ハードウェアリファレンスマニュアル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/76351e98-09d4-54ac-b3ee-1c3f871817f1.png)


説明文からわかる通り、「NUCLEO-F429Zi」に搭載されているEthernetはRMIIが使われているようです。
そして、表にはEthernetのピン設定が書かれています。この表に沿って、前述した「信号と対応するピン設定」を行います。ピン設定の具体的な実装においては、マイクロコントローラのリファレンスマニュアルとサンプルソースコードなどを参考に行います。
「Note」には消費電力に関する記述もありますね。もし、スリープモードのような機能を作りたい場合はこれを参考にしてください。

また、「NUCLEO-F429Zi」におけるハードウェアのリファレンスマニュアル[ここ](https://www.st.com/ja/evaluation-tools/nucleo-f429zi.html#documentation )にあります。「ユーザ・マニュアル」の項目にある、「UM1974 STM32 Nucleo-144 boards (MB1137)」がハードウェアのリファレンスマニュアルです。

#### マイクロコントローラのリファレンスマニュアル

次に評価ボードに乗っているマイクロコントローラ、いわゆるマイコンのリファレンスマニュアルです。
このリファレンスマニュアルにはマイコンの説明だけでなく、Ethernetを含むハードウェアとして対応している機能の扱い方やレジスタ仕様が書かれています。デバイスドライバの開発など、低レイヤの開発をするうえで必ず必要になる資料です。

このマイコンのリファレンスマニュアルは、マイコンの型番から探します。「NUCLEO-F429Zi」においては、ハードウェアのリファレンスマニュアルに下記の画像のように型番が記されているので、この型番のマイコンのリファレンスマニュアルを探します。

![マイコン型番.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/b3aa47a2-090a-10ec-f477-fd732149e068.png)


Googleなどの検索サイトから検索したところ、[こちら](https://www.stmcu.jp/stm32/stm32f4/stm32f429439/12326/ )にあります。「リファレンスマニュアル(日本語)」の項目からダウンロードできます。

![マイコンリファレンスのありか.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/d7281edb-fa58-437e-7722-b8a4578c0961.png)


主にこのリファレンスマニュアルとサンプルソースコードを確認しながらデバイスドライバを開発していくことが多いです。
マイコンのリファレンスマニュアルで確認することが必要な項目は下記となります。

- 6 リセットおよびクロック制御（STM32F42xxx およびSTM32F43xxx 向け）（RCC）
  - クロック供給の設定の仕方を確認する
- 12 割り込みとイベント
  - Ethernetの割り込みの設定の仕方を確認する
- 33 Ethernet（ETH）：メディアアクセス制御（MAC）、DMA コントローラ付き
  - Ethernetのレジスタ設定方法と送受信に使用するバッファの管理・設定方法を確認する
- 8.3.2 I/O ピンマルチプレクサとマッピング
  - 信号の入力に関して確認する

#### 回路図

次に、開発ボードの回路図を確認します。「NUCLEO-F429Zi」においては、[こちら](https://www.st.com/ja/evaluation-tools/nucleo-f429zi.html#cad-resources )にありました。

回路図を確認する理由としては、Ethernet PHYの型番が他のリファレンスマニュアルに記載されていない場合や、Ethernetを動作するのにディップスイッチやジャンパなどを設定しなおす必要がある場合に使用します。
また、ハードウェア側に問題があってデバイスドライバが動作しない場合等の原因究明にも使用します(市販のボードであればこの用途は稀です。まずはソフトウェアに確実に間違いがないかを調べるのが先決です)。

「NUCLEO-F429Zi」においてはEthernet PHYがリファレンスマニュアルに記載されていないので、これを探します。見たところ、回路図に下記のような記載がありました。「LAN8742A-CZ-TR」がEthernet PHYの型番のようですね。

![回路図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266944/3ce8f4ff-e085-e200-7c41-35f448a22bd2.png)

#### 評価ボードに搭載されているEthernet PHYのリファレンスマニュアル(データシート)

回路図に記載のあった、「LAN8742A-CZ-TR」のリファレンスマニュアル(データシート)を探します。Googleで検索すると、[DigiKeyさんのサイト](https://www.digikey.jp/ja/products/detail/microchip-technology/LAN8742A-CZ-TR/4079931 )に「データシート」のリンクがありました。これを参照します。

また、EthernetPHYのアドレスが0x00~0x1Fのレジスタは、ハードウェアに関わらず共通レジスタとなっています。よって、EthernetPHYのレジスタ設定を確認する際は、0x1F以降のアドレスのレジスタ設定が必要かどうかに着目するとよいかと思います。

## デバイスドライバの実装例

デバイスドライバの実装例がどこにあるかを示しておきます。おそらく、上記で示したドキュメントを確認して、すぐにデバイスドライバが開発できる方は稀かと思います。
そこで、評価ボードの開発元であるメーカが公開しているサンプルとなるファームウェアのプロジェクトを使用します。
プロジェクトの作成方法の一例として、[こちら](https://qiita.com/tom_S/items/b152bfc8cf572c1a6f04 )に記載しています。デバイスドライバのソースコードとしては、下記のファイルの実装を参考にするとよいでしょう。

- stm32f4xx_hal_eth.c (Ethernetの初期設定と送受信)
- lan8742.c (Ethernet PHYの設定)

詳しい実装に関しては別の記事で説明しようかと思います。

## 参考資料

https://www.macnica.co.jp/business/semiconductor/articles/microchip/134946/
https://www.marubun.co.jp/technicalsquare/9334/
https://zenn.dev/masahiro_toba/articles/da6719d48a1141
https://www.st.com/ja/evaluation-tools/nucleo-f429zi
https://www.stmcu.jp/stm32/stm32f4/stm32f429439/12326/