Blog:
【三菱ディスプレイ】第4「Device Tree Overlays (DTO)」
この5回にわたるブログ記事連載では、LVDSディスプレイの基礎的な概念について説明します。前回の記事では、Linux Device TreeでLCDディスプレイを設定する方法について説明しました。今回は、Device Tree Overlaysについて説明し、これを利用して導入プロセスを促進する方法を見ていきます。
Device Tree Overlays(DTO)は、デバイスツリー全体を再コンパイルせずに全体的なデバイスツリーを変更する方法を提供します。オ-バーレイは、完全なデバイスツリーの小さく部分的な断片で、必要に応じて追加したり削除したりできます。多くの場合、システム内のハードウェアコンポーネントの有効化と無効化に利用されます。
周辺ハードウェア機器を説明する方法としてのオーバーレイの利点は、この柔軟な性質によるもので、システムへの追加およびシステムからの削除が簡単に行えます。また、デバイスツリー全体に追加する前に、既存ハードウェアのパラメータを調整する際にも便利です。
ここでは、既存のデバイスツリーの編集や新しいインクルードファイル(.dtsi)の作成を行う代わりに、動的な有効化・無効化が可能でシンプルなデバイスツリーオーバーレイに上記の変更を行う方法について説明します。
Toradexの開発者ガイド情報に加え、DTOに関してはこちらやこちらなどの優れたドキュメントがあります。上記のドキュメントがあることを踏まえ、ここではあまり立ち入った説明は控えることにします。
本稿での実装はTorizonで利用するので、DTOについて説明する前にTorizonの基礎について最低限の説明をしておく必要があります。(Yoctoに関する経験があまりない方は、Torizonを試してみることを強くお勧めします。)
開発PCでデバイスツリーのソースファイルをコンパイルし、U-Bootを介して変更を設定する標準的アプローチではなく、Torizonでは、モジュール内にデバイスツリーオーバーレイが直接組み込まれており、次回の起動実行の際に動的に有効にされます。
Torizonは、標準的なYoctoベースの組込みLinuxイメージとは少し異なっています。このToradexの取リ組みは、組込みデバイスへのアクセスと開発を容易にすることを目指しています。TorizonCoreと呼ばれるTorizonの基盤に加え、Dockerコンテナの利用も可能で、DTOおよびOTA機能にも対応します。
Torizonに関する完全な概要と開発者向けのドキュメントはToradexの開発者ページで入手可能です。また、あらゆる情報が掲載された入門ガイドもあり、設定手順から配布と更新を容易にするコンテナ作成方法まで、詳細が記されています。DTOの編集に手を付ける前に、Torizonについて確認し、少し触ってみることをお勧めします。Torizonの習得は、Yoctoプロジェクトイメージのカスタマイズよりも格段に簡単です。
Torizonは、Toradex Easy Installerを介して容易にインストールできます。確立されたイメージはありますが、CI(継続的インテグレーション)フィードを通じ、毎日更新される最新のコンピレーションにアクセスしてダウンロードすることも可能です。
以下のドキュメントは、CIサーバからのTorizon 2019/11/11ビルドを利用して実装および検証されたものです。CIサーバのイメージを選択するには、Toradex Easy Installerを起動し、「Feeds」タブでCIサーバを有効にしてください。イメ-ジが読み込まれたら、TorizonCoreの最新バージョンから1つを選択します(Dockerランタイムが有効、PREEMPT_RTパッチはあってもなくても可)。
つまり、Dockerランタイムがすでに利用できるようになっている新しいTorizonCoreのイメージをダウンロードすることになります。これにより、既製のコンテナを簡単に実装することができます。今回DTOを有効にするのにこれを使います。
デバイスツリーオーバーレイの手法には複数の利点がありますが、その1つはデバイス定義で細かい設定を容易に追加できることです。今回は、LVDSインターフェイス(これはすでにBSPに含まれています)と必要なタイミングを含むもう1つ(これは既存のものから新規作成します)を有効化する、簡単なデバイスツリーオーバーレイを利用します。
Torizonを走らせているSoMでLVDSサブシステムを有効化するには、まずログインし、DTOツール、torizon/arm32v7-debian-dev-toolsコンテナをダウンロードして起動します。
https://developer.toradex.com/knowledge-base/device-tree-overlays#The_Container
# docker pull torizon/arm32v7-debian-dev-tools # docker run -it --rm --privileged -v /dev:/dev -v /boot:/boot torizon/arm32v7-debian-dev-tools
ダウンロードして起動させたら、コンテナ内のdtconfツールを起動させ(##があるのはそのためです。Torizonの記述規則についての詳細はこちら)LVDSサブシステムを有効にします。
## dtconf activate enable_lvds_display_apalis_imx6.dts
初めてTorizonへ起動する場合、次のような表示になるはずです。シリアル出力がこのように見えるはずです。次のケースでは、既製品の10.1インチLVDSディスプレイのLVDSタイミングを有効にしました。
デフォルトでは、dev-toolsコンテナを読み込むと、自動的に複数のフォルダをマウントするため、デバイスツリーオーバーレイのフォルダに簡単にアクセスできます。
この前後では(またはコンテナシェルの外側と内側では)、ルートファイルシステムが少し変化していることに注目してください。
今後は、開発を容易にするために、SSHのセッションを2つ開くことをお勧めします。コンテナの外側でデバイスツリーを編集するセッションとコンテナを使うためのセッションです(このドキュメントを執筆した時点では、viはまだツーリングコンテナに追加されていませんでした)。これは個人的な好みで判断してください。
いずれにしろ、システムからツールコンテナの別のフォルダにアクセスするためには、ツールコンテナを終了する必要があります。
## exit # mkdir /home/torizon/dts && cd /home/torizon/dts
この例では、7インチのディスプレイ用のみに作成しますが、自由に他のディスプレイ用に適合するように作成してください。
編集に移る前に、もう1つ注意点を挙げておきます。標準のデバイスツリーでは、直接NXPのIMXにおけるldb記述を利用しましたが、ここでは標準的panel-lvds記述を利用します。事前に確認しておき、後で違いに驚くことのないようにしてください。
# vi /home/torizon/dts/apalis-imx6-mitsubishi-7.dts /dts-v1/; /plugin/; / { compatible = "toradex,apalis_imx6q"; fragment@0 { target-path="/panel-lvds"; __overlay__ { status = "okay"; data-mapping = "vesa-24"; width-mm = <193>; height-mm = <130>; panel-timing { clock-frequency = <30400000>; //30.4 MHZ hactive = <800>; vactive = <480>; hback-porch = <112>; hfront-porch = <32>; vback-porch = <3>; vfront-porch = <17>; hsync-len = <80>; vsync-len = <4>; hsync-active = <0>; vsync-active = <0>; pixelclk-active = <0>; }; }; }; }; # docker run -it --rm --privileged -v /dev:/dev -v /home/torizon/dts:/dts -v /boot:/boot torizon/arm32v7-debian-dev-tools
すでに言及しましたが、新規のdtsフォルダがコンテナの内側にもマウントされるようツールコンテナを再起動する必要があります。
「-v /home/torizon/dts:/dts」というコマンドがDockerに指示しているのは、コンテナ内にある最近作成されたフォルダを/dtsパスにマウントする、ということです。
## ls -l /dts -rw-r--r-- 1 torizon torizon 3207 Nov 12 07:02 apalis-imx6-mitsubishi-7.dts
さあ、これでDTSをビルドする準備ができました。--no-git-repo の記述に注意してください。これは、gitレポジトリの外側にありローカルで作成されたファイルであることをdtconfに指示するための記述です。
## dtconf activate --no-git-repo /dts/apalis-imx6-mitsubishi-7.dts Device is apalis imx6(0035) Building /dts/apalis-imx6-mitsubishi-7.dts Successfully built device tree Validating ./apalis-imx6-mitsubishi-7.dts.dtbo Overlay is valid.
activateの代わりに他のパラメータを利用することも可能です(例えば、DTSにはbuild、DTBOにはvalidateまたはenable)。けれども、activateはビルド、検証、DTS有効化を1つのコマンドで実行できるため、最も直接的な方法と言えます。
さて、dtconf statusを利用すれば、現在アクティブなDTOを確認できます。
## dtconf status Device is apalis imx6(0035) Currently active overlays: enable_lvds_display_apalis_imx6.dts.dtbo apalis-imx6-mitsubishi-7.dts.dtbo ...
モジュールのハードリセットを行い、変更されたことを検証してください。他の変更が必要な場合は、デバイスツリーを無効化してから適切な変更を加えます。再ビルドする必要があるので再度DTOを有効化します。開発機器でデバイスツリー全体をコンパイルしてDTBをモジュールに送信する、という以前の作業を実施するよりこちらの方が作業は速く終わります。
## dtconf disable apalis-imx6-mitsubishi-7.dts.dtbo Device is apalis imx6(0035) Mounting /mnt/part Overlay file apalis-imx6-mitsubishi-7.dts.dtbo has been disabled ## dtconf activate --no-git-repo /dts/apalis-imx6-mitsubishi-7.dts ...
先に紹介した技術詳細で言及したように、Apalis iMX6にはデュアルチャネルLDVS接続が可能です。これは、ニーズに応じて異なるシナリオで利用することができます。シングルチャネルで実現できるよりも高い解像度が必要な場合には、同一のディスプレイに両方のチャネルを利用することもできます。または、システムで複数のディスプレイを管理する必要がある場合には、費用効果のよいソリューションのために両方のディスプレイを個々に利用することもできます。
この手法の限界の1つに、VivanteのXドライバが最初のframebuffer /dev/fb0しか利用できないことがありますが、fbdev framebufferインターフェイスを介すれば他も利用可能です。
この手法は、Apalis iMX8ではまだ試していないのですが、うまく動作しないと思われる理由は1つもありません。しかし一点注意が必要なのは、NXPはi.MX8でWayland/Westonを優先し、X11のサポートを停止したことです。
&ldb { status = "okay"; /* We remove or comment-out the split-mode and dual-mode */ lvds-channel@0 { /* Use above changes*/ reg = <0>; fsl,data-mapping = "spwg"; /* "jeida"; */ fsl,data-width = <24>; //Selected by pin 19 of the LVDS connector crtc = "ipu2-di1"; primary; status = "okay"; native-mode = <&mitsubishi_7>; /* Mitsubishi 7", Wide - VGA (800x480)" */ /* AA070ME01ADA11 */ mitsubishi_7: 800x480 { clock-frequency = <30400000>; //30.4 MHZ hactive = <800>; vactive = <480>; hback-porch = <112>; hfront-porch = <32>; vback-porch = <3>; vfront-porch = <17>; hsync-len = <80>; vsync-len = <4>; hsync-active = <0>; vsync-active = <0>; pixelclk-active = <0>; }; }; lvds-channel@1 { reg = <1>; fsl,data-mapping = "spwg"; fsl,data-width = <24>; //Selected by pin 19 of the LVDS connector crtc = "ipu1-di0"; status = "okay"; display-timings { native-mode = <&mitsubishi_7_ch2>; /* Mitsubishi 7", WVGA" */ mitsubishi_7_ch2: 800x480 { clock-frequency = <30400000>; //30.4 MHZ hactive = <800>; vactive = <480>; hback-porch = <80>; hfront-porch = <80>; vback-porch = <24>; vfront-porch = <24>; hsync-len = <0>; vsync-len = <0>; hsync-active = <0>; vsync-active = <0>; pixelclk-active = <0>; }; }; }; };
さらに、2つ目のLVDSチャネル用にもう1つのframebufferへのアクセスを変更する必要があります。
mxcfb1: fb@0 { compatible = "fsl,mxc_sdc_fb"; disp_dev = "ldb,lvds-channel@0"; interface_pix_fmt = "RGB24"; default_bpp = <32>; int_clk = <0>; late_init = <0>; status = "disabled"; }; mxcfb2: fb@1 { compatible = "fsl,mxc_sdc_fb"; disp_dev = "ldb,lvds-channel@1"; interface_pix_fmt = "RGB24"; default_bpp = <32>; int_clk = <0>; late_init = <0>; status = "disabled"; };
最後に、Ubootのディスプレイ変数を使い、該当するframebufferを有効にする処理も必要です。
setenv vidargs 'video=mxcfb0:dev=ldb,lvds-channel@0 video=mxcfb1:dev=ldb,lvds-channel@1 video=mxcfb2:off video=mxcfb3:off fbmem=512M' saveenv
今回の記事では、Device Tree Overlaysについて説明しました。次回は、LCDディスプレイのハードウェアとケーブルに関して考慮すべき点について見ていきます。何かご質問などがありましたら、Toradexのコミュニティに投稿してください。Toradexの専門家が喜んで回答いたします。