みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

meta-raspberrypi mortyでcore-image-satoが起動できない時の対処 その2

先日の記事の続き。

vc4graphicsを有効化した状態でこれをcocopar 5 インチIPSハイビジョンLCD ディスプレイで動かそうとすると、画面が真っ黒になった。

調査したところ、cocoparのLCDのようにEDIDを取得できないデバイスの場合KMSの初期化で弾かれてしまい、画面が表示されなくなることがわかった。

このような場合は、EDIDをどうにかごまかしてカーネルに教えてやることによって、この状況を回避することができる。

800x480の解像度を設定するためのEDIDファイルをカーネルに指定して、core-image-satoを動作させることができるようにmeta-hdmi5inch-rpiを更新した。

ベース環境の取得

$ git clone git://git.yoctoproject.org/poky.git -b morty
$ cd poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi -b morty
$ git clone https://github.com/mickey-happygolucky/meta-hdmi5inch-rpi.git -b morty

今回はmortyブランチで作業する。

oe-init-build-envの読み込み

下記を実行する。

$ cd ~/rpi3
$ source poky/oe-init-build-env

これにより、クロスコンパイルに必要な環境変数が設定され、ビルドディレクトリに移動される。

meta-raspberrypiをビルド対象に追加

次のコマンドを実行する。

$ bitbake-layers add-layer ../poky/meta-raspberrypi
$ bitbake-layers add-layer ../poky/meta-hdmi5inch-rpi

local.confの修正

次の行をlocal.confの先頭の方に追加する。

MACHINE ?= "raspberrypi3"
MACHINE_FEATURES += "vc4graphics"
IMAGE_INSTALL_append = " xf86-input-evdev"
MACHINE_EXTRA_RRECOMMENDS += "linux-firmware-edid-800x480"

COCOPAR_5INCH_HDMI = "1"
KERNEL_DEVICETREE_append = "overlays/ads7846-overlay.dtb"

DL_DIR ?= "${HOME}/work/yocto/downloads"

DL_DIRの行は必要はないが、ダウンロードしたファイルを複数のビルドディレクトリから使いまわせるようにするために設定している。

COCOPAR_5INCH_HDMI = "1"LCDを有効化、overlays/ads7846-overlay.dtbでタッチパネルを有効化している。

xf86-input-evdevがないとマウス(タッチ)が反応しない。

動作確認

bitbakeの実行

$ bitbake core-image-sato

SDカードの作成

$ sudo dd if=./tmp/deploy/images/raspberrypi3/core-image-sato-raspberrypi3.rpi-sdimg of=/dev/sdb bs=40M

/dev/sdbはSDカードのデバイス。環境により変更が必要な場合がある。

実行

mortyのsatoが表示された。

f:id:mickey_happygolucky:20170208013857j:plain

yocto /lib/firmware以下へのファイルの追加

通常のレシピによるインストールではrootfsに反映されない

以前は、各レシピでdo_installFILES_%{PN}/lib/firmwareにファイルを追加すれば、 問題なくrootfsに反映されていたが、oe-coreにlinux-firmware_git.bbが導入されてから、状況は一変した。

linux-firmware以外のレシピからインストールされたファイルが、rootfsに反映されなくなった。

解決策

自分で作成したファームウェア/lib/firmware以下にインストールするにはlinux-firmware_git.bbappendを作成し次のようにPACKAGEを追加する。

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"

SRC_URI_append = " file://myfirm.bin"
PACKAGES =+ "${PN}-myfirm"

FILES_${PN}-myfirm = "  \
 /lib/firmware/myfirm.bin"

do_install_append() {
   install -d ${D}/lib/firmware
   install -m 0644 ${WORKDIR}/myfirm.bin ${D}/lib/firmware/myfirm.bin
}

追加したパッケージはlocal.confもしくはraspberrypi.confなどのconfファイルからMACHINE_EXTRA_RRECOMMENDSなどで追加する必要がある。 bbやbbappendからの追加はうまく行かない。

local.confへ次の行を追加する。

MACHINE_EXTRA_RRECOMMENDS += "linux-firmware-myfirm"

これで/lib/firmware/myfirm.binがインストールされる。

linux-firmwareについて

通常/lib/firmwareに配置されるファイルはプロプライエタリバイナリファイルであるため、オープンソースではないライセンスが付与されている。 yoctoprojectでは、これらを一元に管理するためにlinux-firmwareのレシピですべてを管理するようにしたと推測されるが、経緯は詳しく調べていない。

とはいえ、/lib/firmwareにファイルを追加する場合は、注意が必要である。

meta-raspberrypi mortyでcore-image-satoが起動できない時の対処

素の状態でbitbake core-image-satoで作成したイメージを起動すると、 真っ黒い画面にマウスカーソルのみが表示されるという状態になる。

シリアルコンソールでログインし、/var/log/Xsession.logを表示したところ下記のようになっていた。

$cat Xsession.log 
...(省略)...

** (process:498): WARNING **: Failed to register client: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files
Error: No calibratable devices found.
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory

libGL.so.1が見つからないらしい。実際にファイルを確認して見ると存在しなかった。

libGL.so.1をどうにかしてみる

libGL.so.1はmesa-glの持ち物であるため、local.confに下記を追加し再度挑戦してみる。

IMAGE_INSTALL_append = " mesa-gl"

これでも/usr/lib/libGL.so.1はインストールされず。

bitbakeした結果を手動でrootfsへコピーしたところ、エラーの状態には変化があった。 しかし、状態は変わらず。

Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory

libxcb-glxはX11上でのOpenGLの実行に使用するライブラリなので、vc4graphicsが必須なのではなかろうか。

vc4graphicsを有効にしてみる

local.confに下記を追加。

MACHINE_FEATURES += "vc4graphics"

その後bitbake core-image-satoを実行。

ラズベリーパイ3を起動してみると、画面が表示された!

しかし、マウスカーソルが全く反応しない。

次のように、マウスとの接続に問題がないかを確認してみる。

# cat /dev/input/mouse0 
��H�%���
                 �
��#            �  �
      
        (�(�(�(�(��(�(�8����������

マウスを動かすとゴミが表示されるので、デバイスは問題なく動作している。

X11がデータを解釈できていないということ。

なので、evdev関連のモジュールに不足がないかを確認。

local.confに下記を追加してみる。

IMAGE_INSTALL_append = " xf86-input-evdev"

これで、core-image-satoを作成しなおして、起動すると。。。

動いた!

まとめ

最近のmeta-raspberrypiでX11を動作する場合は、vc4graphicsの有効化が必須らしい。 というか、無効の場合はあまりデバッグされていないのではないか。

また、vc4graphics有効化状態でもxf86-input-evdevを明示的に追加しないとマウスが動かない。

しばらくしたら修正されそうだが。2017/2/2時点ではこのような状態。

ConnectCore i.MX6UL スターターキット: PiTFT3.5を動かす

ConnectCore i.MX6ULスターターキットの続き

その1 その2 その3 その4 その5

PiTFT3.5

PiTFT3.5をccimx6ul starterのラズベリーパイ互換ピンヘッダに実装して動かしてみる。

meta-pitft35-digiの使用

ccimx6ul starterでPiTFT3.5を使用できるようにするためにmeta-pitft35-digiを作成した。

環境の設定

次の要領でmeta-pitft35-digiをダウンロードし、ビルド対象に追加する。

$ cd ~/yocto/dey-2.0/sources
$ git clone https://github.com/mickey-happygolucky/meta-pitft35-digi.git
$ cd ~/yocto/dey-2.0/build
$ source dey-setup-environment
$ bitbake-layers add-layer ../sources/meta-pitft35-digi

bitbakeの実行

今回はGUIのイメージを作成する。

$ bitbake dey-image-qt

イメージのインストール

生成されたOSイメージのインストールはその2その3のいずれかの手順を実施する。

実行画面

電源を投入すると、次のような画面が表示される。

f:id:mickey_happygolucky:20170130022625j:plain

次に、satoのデスクトップが使用できるようになる。

f:id:mickey_happygolucky:20170130022632j:plain

バイスの構成

PiTFT3.5は主に2つの機能から構成されている。

機能 関連IC ドライバ 接続方式
TFT液晶 HX8357D drivers/staging/fbtft/fb_hx8357d.c SPI(SS0)
タッチパネル STMPE610 drivers/mfd/stmpe.c SPI(SS1)

i.MX6ULとの関係は次のようになっている。

f:id:mickey_happygolucky:20170130022723p:plain

タッチパネルを使用するためにはSS1(Slave Select/Chip Select)がRPiコネクタに接続される必要がある。 ラズベリーパイでは26ピン(GPIO7)がSPI0_CE1_Nに切り替えられるため、LCDとタッチパネルを同時に使用することができた。 しかし、ccimx6ul startterのRPiコネクタの26ピンはLCD_DATA9と接続されている。 このピンにはeCSI_SS1の機能は割り当てられていないため、SPIのChip SelectをGPIOで出力する方法がないかを確認する。

 imx6ul-ccimx6ul {
        pinctrl_ecspi3: ecspi3grp {
            fsl,pins = <
                MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b0
                MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI  0x10b0
                MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO  0x10b0
                MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x10b0 /* Chip Select */
            >;
        };

SS0のピンのPINMUXを設定しているのはMX6UL_PAD_UART2_TX_DATA__GPIO1_IO20となる。 しかし、このピンはGPIO1_IO20に設定されている。 つまりSS0の信号を出力するためにSS0のピンファンクションではなくGPIOを使用していることになる。

つまり、SS1の機能がないピンでSS1の出力ができる可能性がある。

HX8357Dドライバ

まずはLCDの部分を使用できるようにする。 ドライバをバックポートしたあとは、デバイスツリーを修正する。

 pitft: pitft@0{
                compatible = "himax,hx8357d";
                reg = <0>;
                pinctrl-names = "default";
                pinctrl-0 = <&pitft_pins>;
                
                spi-max-frequency = <32000000>;
                rotate = <90>;
                fps = <25>;
                bgr;
                buswidth = <8>;
                dc-gpios = <&gpio 25 0>;
                debug = <0>;
        };

dc-gpiosはD/C(Data/Command)ピンのこと。ラズベリーパイではGPIO_IO25(22ピン)に接続されている。 ccimx6ul startterのRPiコネクタの22ピンはLCD_DATA8と接続されている。 pinmuxの設定を下記のように追加して、GPIOとして使用できるようにする。

     pinctrl_pitft: pitftgrp {
            fsl,pins = <
                MX6UL_PAD_LCD_DATA08__GPIO3_IO13    0x10b0 /* D/C */
            >;
        };

LCD_DATA8のピンにははGPIO3_IO13が割り当てられている。そして、dc-gpiosにGPIO3_IO13を割り当てる。

                dc-gpios = <&gpio3 13 0>;

STMPE610

ドライバを有効化する。

CONFIG_STMPE_SPI=y
CONFIG_TOUCHSCREEN_STMPE=y

まずはSS1の接続を考える。 LCDの表示ができていることからSS0のGPIO出力は問題ない。

そこで、SS1が接続されているピン(LCD_DATA9)をGPIO(GPIO3_IO14)に割りあてる。

/* ECSPI3 (Raspberry PI Expansion header) */
&ecspi3 {
    fsl,spi-num-chipselects = <2>;
    cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW
            &gpio3 14 GPIO_ACTIVE_LOW>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi3>;
    status = "disabled";
};

...(snip)...

        pinctrl_ecspi3: ecspi3grp {
            fsl,pins = <
                MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b0
                MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI  0x10b0
                MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO  0x10b0
                MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x10b0 /* Chip Select0 */
                MX6UL_PAD_LCD_DATA09__GPIO3_IO14    0x10b0 /* Chip Select1 */
            >;
        };

また、STMPE620の割り込みには、ラズベリーパイの18ピン(GPIO24)が接続されているため、 ccimx6ul startterのRPiコネクタの18ピンをGPIO(GPIO3_IO12)に割り当てる。

まとめ

ラズベリーパイ互換ピンヘッダにラズベリーパイ用のデバイスを接続して使用できることがわかった。 SPIのChipEnableが1つしかピンに出せなかったが、LinuxのドライバがChipEnableをGPIOに割り振れるような作りになっていたため、 無事、タッチパネルまで動作することができた。

ConnectCore i.MX6UL スターターキット: connmanによるWifi設定

ConnectCore i.MX6ULスターターキットの続き

その1 その2 その3 その4

ここでは/etc/wpa_supplicant.conf/etc/network/interfacesを直接編集する方法が記載されているが、

YoctoProjectではconnmanが簡単に使用できるため、connmanを使用してWifiを設定する。

環境変数の設定

1度以上bitbakeを実行した状態で、新規にシェルを開いた場合の環境変数の設定は、 素のpokyであれば、source poky/oe-init-build-envのようにするが、 DigiのYocto BSP環境では次のようにする。

$ cd ~/yocto/dey-2.0/build
$ source dey-setup-environment

connmanパッケージの追加

conf/local.confに次の行を追加する。

IMAGE_INSTALL_append = " connman connman-client"

connman-clientを入れ忘れるとconnmanctlがインストールされないので注意。

bitbakeの実行

$ bitbake core-image-base

イメージのインストール

生成されたOSイメージのインストールはその2その3のいずれかの手順を実施する。

Wifiの設定

connmanctlをインタラクティブモードで起動し、必要な設定を行う。

ここ

$ connmanctl
connmanctl> enable wifi
connmanctl> scan wifi
connmanctl> services
*AO Buffalo-A-EFD8       wifi_0004f3fffffb_XXXXXXXX16c6f2d412d45464438_managed_psk
    Buffalo-G-EFD8       wifi_0004f3fffffb_XXXXXXXX16c6f2d472d45464438_managed_psk
    68942381C413         wifi_0004f3fffffb_XXXXXXXX233383143343133_managed_psk
    Buffalo-G-D275       wifi_0004f3fffffb_XXXXXXXX16c6f2d472d44323735_managed_psk
    001D73902CCE         wifi_0004f3fffffb_XXXXXXXX733393032434345_managed_psk
    001D73902CCE-1       wifi_0004f3fffffb_XXXXXXXX7333930324343452d31_managed_psk
    aterm-fbf152-g       wifi_0004f3fffffb_XXXXXXXXd2d6662663135322d67_managed_psk
    AirPort29437         wifi_0004f3fffffb_XXXXXXXXf72743239343337_managed_psk
    Buffalo-A-D275       wifi_0004f3fffffb_XXXXXXXX16c6f2d412d44323735_managed_psk
    aterm-fbf152-aw      wifi_0004f3fffffb_XXXXXXXXd2d6662663135322d6177_managed_wep
    aterm-fbf152-a       wifi_0004f3fffffb_XXXXXXXXd2d6662663135322d61_managed_psk
connmanctl> agent on
connmanctl> connect wifi_0004f3fffffb_XXXXXXXX16c6f2d412d45464438_managed_psk
Agent RequestInput wifi_0004f3fffffb_XXXXXXXX16c6f2d412d45464438_managed_psk
  Passphrase = [ Type=psk, Requirement=mandatory ]
  Passphrase?  

ここでアクセスキーのパスワードを入力すれば接続される。 PSKなど暗号化されているアクセスポイントに接続する場合にはagent onを実行する必要があるので注意。

ConnectCore i.MX6UL スターターキット:デバイスツリーについて

ConnectCore i.MX6ULスターターキットの続き

その1 その2 その3

bitbakeを実行すると、下記のデバイスツリーファイルが生成される。

  • zImage-imx6ul-ccimx6ulstarter.dtb
  • zImage-imx6ul-ccimx6ulstarter-wb.dtb
  • zImage-imx6ul-ccimx6ulstarter-id129.dtb

この内のどれを使用するのかはboot.scrによって次のように選択される。

f:id:mickey_happygolucky:20170122235503p:plain

今回のようにboot.scrを使用せずにLinuxを起動する場合も、このルールにはのっとる必要がある。

現時点ではboard_id=129と設定されているため、zImage-imx6ul-ccimx6ulstarter-id129.dtbを選択する。

違うデバイスツリーファイルを使用した場合、Linuxの起動自体は問題なく行えるが、wlanのドライバのロードが失敗するなど、デバイスの使用に問題が出る場合がある。

ConnectCore i.MX6UL スターターキット:マイクロSDカードからLinuxを起動する

ConnectCore i.MX6ULスターターキットの続き

その1 その2

パーティション作成

ツールでSDカードのメディアに次のようにパーティションを作成する。

ラベル サイズ フォーマット
boot 256M ext4
rootfs 残り全部 ext4

gpartedのインストール

Ubuntu16.04では次のようにする。

$ sudo apt-get install -y gparted

カーネルとデバイスツリーのコピー

$ sudo cp tmp/deploy/images/ccimx6ulstarter/zImage-ccimx6ulstarter.bin /media/${USER}/boot
$ sudo cp tmp/deploy/images/ccimx6ulstarter/zImage-imx6ul-ccimx6ulstarter-id129.dtb /media/${USER}/boot

ルートファイルシステムの展開

$ sudo tar xvf ./tmp/deploy/images/ccimx6ulstarter/core-image-base-ccimx6ulstarter.tar.bz2 -C /media/${USER}/rootfs

u-bootの設定

setenv bootargs console=${console},${baudrate} ${bootargs_linux}  root=/dev/mmcblk1p2 fstype=ext4
setenv load_kernel_mmc ext4load mmc 0 ${loadaddr} /zImage-ccimx6ulstarter.bin
setenv load_fdt_mmc ext4load mmc 0 ${fdt_addr} /zImage-imx6ul-ccimx6ulstarter-id129.dtb
setenv bootcmd 'mmc rescan; run load_kernel_mmc; run load_fdt_mmc; bootz ${loadaddr} - ${fdt_addr}'
saveenv

これでマイクロSDからブートされるようになる。