Device Tree
Zephyr ドライバを使うサンプルアプリケーションを紹介する前に、まずデバイスツリーを説明しておくと役に立つと考えています。 これにより、ソースコードをより理解しやすくなります。
デバイスツリーとは
デバイスツリー は、もともと Open Firmware 仕様 (IEEE 1275) の一部として開発されたデータ構造であり、PowerPC ベースのワークステーションやサーバなどのシステムにおけるハードウェア構成を記述するために使われていました。 その後、この考え方は Linux カーネルに取り入れられて広く使われるようになり、特に ARM や PowerPC などのプラットフォームで、カーネルをハードウェアごとに別々にビルドしたり、ボード固有の初期化コードをハードコードしたりせずに、複数のハードウェア構成をサポートできるようになりました。
デバイスツリーは、システムの物理的な構成要素、たとえば CPU、メモリ、バス、周辺デバイス などを、構造化された階層形式で記述します。 このハードウェア記述は通常、人間が読みやすい Device Tree Source (DTS) ファイルとして記述され、Device Tree Compiler (DTC) によってバイナリ形式の Device Tree Blob (DTB) にコンパイルされます。 その後、DTB は起動時に Linux カーネルへ渡され、ハードウェア初期化の指針として使われます。
Zephyr におけるデバイスツリー
Zephyr では、多種多様な対応ボードや SoC に対して、拡張性とモジュール性を向上させるためにデバイスツリーモデルが採用されました。 Linux では DTB が実行時に読み込まれるのに対し、Zephyr ではビルド時に DTS を解析して静的な設定ヘッダを生成します。
これにより、デバイスツリーが持つ柔軟性と再利用性の恩恵を受けつつ、軽量で効率的なハードウェア抽象化が可能になります。
-
ハードウェア抽象化
-
アプリケーションコードの外でハードウェアを記述することで、C ファイル内のハードウェア依存ロジックを減らせます。
-
-
移植性
-
DTS ファイルを切り替えるだけで、単一のソースツリーから複数のハードウェアバリアントをサポートできます。
-
-
保守性
-
既存のドライバやコアロジックを変更せずに、新しいボードや SoC のサポートを追加しやすくなります。
-
-
拡張性
-
似ているが完全には同一でないハードウェア構成を持つデバイスファミリを管理しやすくなります。
-
Zephyr におけるデバイスツリーの一般的な用途
Zephyr では、デバイスツリーは次のような目的で使われます。
-
UART、I2C、SPI、GPIO、CAN などの周辺機能を定義および設定する
-
compatible 文字列に基づいて、ドライバをハードウェアへ自動的に結び付ける
-
DTS から生成されたマクロを通じて、ハードウェアパラメータ (たとえばベースアドレス、割り込み、ラベルなど) をアプリケーションへ渡す
-
オーバーレイを使って複数のボードバリアントを管理する
基本構造
デバイスツリーは、ノードとプロパティを持つファイルシステムのような構造になっています。
ノードはハードウェア部品を表します (例: /cpu, /memory, /soc/gpio@40020000)。
プロパティは、アドレス、割り込み、クロックなどの属性を記述するキーと値の組です。
この説明は入門としての位置付けです。 さらに理解を深めるには、 Zephyr 公式のデバイスツリードキュメントを参照してください。