本章では、Armadillo-640を例として、ハードウェア機能をカスタマイズするために必要なDeviceTreeの記述方法と、カーネルへのデバイスドライバの有効化方法について述べます。
Linuxカーネルに含まれているデバイスドライバの一覧は付録A Linux カーネルサポートデバイス情報をご覧ください。
次章からは、いくつかのデバイスを例に、具体的なデバイスの追加方法を示します。
使用するソフトウェアのバージョンは以下のとおりです。
-
ブートローダー: U-Boot 2018.03-at4 以降
-
Linuxカーネル: linux-4.14-at9 以降
-
ユーザーランド: Debian GNU/Linux 9(stretch)v20181128 以降
Device Treeとは、ハードウェア情報を記述したデータ構造体です。ハードウェアの差分をDevice Treeに記述することによって、1つのLinuxカーネルイメージを複数のハードウェアで利用することができるようになります。
Device Treeに対応しているメリットの1つは、ハードウェアの変更に対するソフトウェアの変更が容易になることです。例えば、CON9(拡張インターフェース)に接続する拡張基板を作成した場合、主にC言語で記述されたLinuxカーネルのソースコードを変更する必要はなく、やりたいことをより直感的に記述できるDTS(Device Tree Source)の変更で対応できます。
ただし、Device Treeは「データ構造体」であるため、ハードウェアの制御方法などの「処理」を記述することができない点に注意してください。Device Treeには、CPUアーキテクチャ、RAMの容量、各種デバイスのベースアドレスや割り込み番号などのハードウェアの構成情報のみが記述されます。
Device Treeのより詳細な情報については、Linuxカーネルのソースコードに含まれているドキュメント(Documentation/devicetree/
)、devicetree.orgで公開されている「Device Tree Specification」を参照してください。
Linuxカーネルのソースコードに含まれている初期出荷状態でのDTS、及び関連するファイルを次に示します。
-
初期出荷状態でのDTS、及び関連するファイル
-
arch/arm/boot/dts/armadillo-640.dts
-
arch/arm/boot/dts/imx6ull.dtsi
-
arch/arm/boot/dts/imx6ul.dtsi
-
armadillo-640-default-console.dtsi
-
armadillo-640-uart5.dtsi
-
armadillo-640-lcd70ext-l00.dtsi
ここではI2Cを使用するための設定を例に説明します。
新規に作成するファイルは".armadillo-640-i2c4.dtsi"とし、次の3つのノードを作成します。
-
iomuxcノード
-
I2Cバスノード
-
I2Cスレーブデバイスノード
iomuxcノードの記述
I2C4のSCLを例に、iomuxcの記述方法を説明します。
AAA
と BBB
の部分はピンのマルチプレクサ(接続先を切り替える機能)の設定です。
-
「マルチプレクス表」を参照し、I2C4のSCLで使用できるピンを調べます。
列「I2C4」を見ると、CON14-3とCON11-16が使用できることがわかります。
今回はCON14-3を使用することにします。
CON14-3の行の「ピン名」を見ると UART2_TX_DATA
と書かれています。これが AAA
の部分に入ります。
_(アンダースコア)を二つ挟み、列「マルチプレクス機能-I2C4」の I2C4_SCL
が BBB
の部分に入ります。
AAA
と BBB
の記述により、下図のように入出力のMUXが選択され、太線部分が接続されます。
CCC
の部分はPAD(各ピンの入出力特性等の設定)の設定値です。
PADの内部は下図のようになっています。
出力バッファーの設定は、信号の周波数等にあわせて調整できます。
入力バッファーのヒステリシス(シュミットトリガー)や、内部プルアップ等の設定も可能です。
I2Cの場合は下記の点を考慮します。
-
最高400kHz程度と低速 → ノイズ低減のため、低速な設定を選択
-
ピンは双方向で使用 → 入力バッファーを強制的に有効化
-
オープンドレイン出力 → オープンドレインを選択
-
遅い信号の立ち上がり → ヒステリシス有りを選択
32ビットで表される値のフォーマットは図3.5「PAD設定値のフォーマット」のようになっており、
各ビットの動作は表3.1「PAD設定値の詳細」のようになります。
よって、下表で *
が付いている設定にします。
表3.1 PAD設定値の詳細
設定 | 値 | 動作 |
---|
NO_PAD_CTL
PAD設定の要否 | 0 * | PAD設定を行う |
1 | PAD設定を行わない |
SION
入力バッファーを強制的に有効化
| 0 | 出力ピンの場合は入力バッファー無効 |
1 * | 強制的に有効 |
HYS
入力バッファーのヒステリシス設定
| 0 | ヒステリシス無し |
1 * | ヒステリシス有り |
PUS
プルダウン / プルアップ選択 | 00 * | プルダウン 100KΩ |
01 | プルアップ 47KΩ |
10 | プルアップ 100KΩ |
11 | プルアップ 22KΩ |
PUE
キーパー / プル選択 | 0 * | キーパー |
1 | プル |
PKE
キーパー / プル設定 | 0 * | キーパー/プル無効 |
1 | キーパー/プル有効 |
ODE
出力バッファーのオープンドレイン選択 | 0 | プッシュプル |
1 * | オープンドレイン |
SPEED
出力電流設定
-
高周波設定にすると出力電流を増加
-
低周波設定にするとスイッチングノイズを低減
| 00 * | 最高出力周波数50MHz |
01 | 最高出力周波数100MHz |
10 | 最高出力周波数100MHz |
11 | 最高出力周波数200MHz |
DSE
ドライブストレングス調整
-
出力インピーダンスを上げるとオーバーシュート小
-
出力インピーダンスを下げると立ち上がり・立ち下がりが高速
| 000 | 出力バッファーがオフ |
001 * | 出力インピーダンス最大 |
010 | |
011 | |
100 | |
101 | |
110 | |
111 | 出力インピーダンス最小 |
SRE
スルーレート設定
| 0 * | 低速 |
1 | 高速 |
SDAも同様に UART2_TX_DATA
が AAA
に、 I2C4_SDA
が BBB
に入り、CCC
は同じ値を設定します。
詳しくは以下の資料をご覧ください。
カーネルのソースコードにも関連するドキュメントが付属しています。
-
Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
-
Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
I2Cバスノードの記述
次章以降や、 arch/arm/boot/dts/
にある .dtsi
.dts
ファイルが参考になります。
関連するドキュメントは Documentation/devicetree/bindings/
以下にあります。
I2Cの場合は、次に示すファイルとなります。
-
Documentation/devicetree/bindings/i2c/i2c.txt
-
Documentation/devicetree/bindings/i2c/i2c-imx.txt
100kHzの設定で記述した場合、次のようになります。
このノードの中に、スレーブデバイスのノードも書きます。
I2Cスレーブデバイスノードの記述
ここではPCF8591を例に説明します。
記述方法はデバイスによって異なります。
3つのノードを合わせると以下のようになります。
これを"arch/arm/boot/dts/armadillo-640-i2c4.dtsi"として保存します(「サンプルソースコード」のページからダウンロードできます)。
さきほどのファイルへのincludeを"arch/arm/boot/dts/armadillo-640.dts"に追加します。
このように、新たにデバイス等を追加する場合は、dtsiファイルを追加する形式にすると管理しやすいでしょう。
menuconfigを使用してカーネルコンフィギュレーションを変更します。
なお、すでにカスタマイズしたソースコードを元に行う場合、手順5から行います。
Linuxカーネルのソースコードアーカイブを準備
カレントディレクトリにソースコードアーカイブがあることを確認します。
[ATDE ~]$ ls
initramfs_a600-[version].cpio.gz linux-v4.14-at[version].tar.gz
Linuxカーネルのソースコードアーカイブを展開
[ATDE ~]$ tar xf linux-v4.14-at[version].tar.gz
[ATDE ~]$ ls
initramfs_a600-[version].cpio.gz linux-v4.14-at[version] linux-v4.14-at[version].tar.gz
initramfs アーカイブへのシンボリックリンク作成
[ATDE ~]$ cd linux-v4.14-at[version]
[ATDE ~/linux-v4.14-at[version]]$ \
> ln -s ../initramfs_a600-[version].cpio.gz initramfs_a600.cpio.gz
コンフィギュレーションの初期化
[ATDE ~/linux-v4.14-at[version]]$ make ARCH=arm armadillo-640_defconfig
menuconfigの実行
[ATDE ~/linux-v4.14-at[version]]$ make ARCH=arm menuconfig
カーネルコンフィギュレーションを変更
変更後、"Exit"を選択して"Do you wish to save your new configuration? (Press <ESC><ESC> to continue kernel configuration.)"で"Yes"を選択し、カーネルコンフィギュレーションを確定します。
.config - Linux/arm 4.14-at11 Kernel Configuration
------------------------------------------------------------------------------
---------------- Linux/arm 4.14-at11 Kernel Configuration -----------------
Arrow keys navigate the menu. <Enter> selects submenus ---> (or empty
submenus ----). Highlighted letters are hotkeys. Pressing <Y>
includes, <N> excludes, <M> modularizes features. Press <Esc><Esc> to
exit, <?> for Help, </> for Search. Legend: [*] built-in [ ]
-----------------------------------------------------------------------
General setup --->
[ ] Enable loadable module support ----
[*] Enable the block layer --->
System Type --->
Bus support --->
Kernel Features --->
Boot options --->
CPU Power Management --->
Floating point emulation --->
Userspace binary formats --->
Power management options --->
[*] Networking support --->
Device Drivers --->
Firmware Drivers --->
File systems --->
Kernel hacking --->
Security options --->
-*- Cryptographic API --->
Library routines --->
[ ] Virtualization ----
-----------------------------------------------------------------------
---------------------------------------------------------------------------
<Select> < Exit > < Help > < Save > < Load >
---------------------------------------------------------------------------
| |
---|
Linux Kernel Configurationメニューで"/"キーを押下すると、カーネルコンフィギュレーションの検索を行うことができます。カーネルコンフィギュレーションのシンボル名(の一部)を入力して"Ok"を選択すると、部分一致するシンボル名を持つカーネルコンフィギュレーションの情報が一覧されます。 |
ビルド
[ATDE ~/linux-v4.14-at[version]]$ \
> make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOADADDR=0x82000000 uImage
[ATDE ~/linux-v4.14-at[version]]$ \
> make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
イメージファイルの生成確認
ビルドが終了すると、arch/arm/boot/ディレクトリと、arch/arm/boot/dts/以下にイメージファイル(LinuxカーネルとDTB)が作成されています。
[ATDE ~/linux-v4.14-at[version]]$ ls arch/arm/boot/uImage
arch/arm/boot/uImage
[ATDE ~/linux-v4.14-at[version]]$ ls arch/arm/boot/dts/armadillo-640.dtb
arch/arm/boot/dts/armadillo-640.dtb