みつきんのメモ

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

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からブートされるようになる。

ConnectCore i.MX6UL スターターキット:ネットワーク越しにLinuxを起動する

前回の続き。

次のような構成でLinuxを起動する。

コンポーネント 読み込み方法
u-boot NANDフラッシュ(デフォルト)
linuxカーネル tftpサーバ
バイスツリー tftpサーバ
rootfs NFS

tftpサーバ

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

インストール

$ sudo apt-get install -y tftpd-hpa

起動

インストール直後は起動済みなので不要のはず。

$ sudo systemctl start tftpd-hpa

ファイルの格納

Ubuntuではデフォルトで/var/lib/tftpbootがtftpの公開ディレクトリに設定されているため、 ダウンロードしたいファイルはここにファイルを格納する。

ここではカーネルとデバイスツリーをコピーする。

$ sudo cp tmp/deploy/images/ccimx6ulstarter/zImage-ccimx6ulstarter.bin /var/lib/tftpboot
$ sudo cp tmp/deploy/images/ccimx6ulstarter/zImage-imx6ul-ccimx6ulstarter-id129.dtb /var/lib/tftpboot

nfsサーバ

インストール

$ sudo apt-get install -y nfs-kernel-server

公開ディレクトリの設定

tftpサーバとは異なり、デフォルトの公開ディレクトリは設定されていないため、この設定をおこなう。

/etc/exportsに下記の内容を追加する。

/exports 192.168.21.0/255.255.255.0(rw,no_root_squash,subtree_check)

/exportsを作成する。

$ sudo mkdir /exports

起動

$ sudo systemctl restart nfs-kernel-server

ファイルの展開

bitbakeで生成されたrootfsのイメージを/exportsに展開する。

$ sudo tar xvf ./tmp/deploy/images/ccimx6ulstarter/core-image-base-ccimx6ulstarter.tar.bz2 -C /exports/

u-bootの設定

以下のようにネットワークの設定を行う。

変数 説明 設定例
ipaddr ccimx6ulstarterのIPアドレス 192.168.21.100
serverip tftpサーバのIPアドレス 192.168.21.42
setenv ipaddr 192.168.21.100
setenv serverip 192.168.21.42

次にLinux起動のための設定を行う

setenv fdt_file zImage-imx6ul-ccimx6ulstarter-id129.dtb
setenv bootargs console=${console},${baudrate} ${bootargs_linux} ip=192.168.21.100 root=/dev/nfs nfsroot=192.168.21.42:/exports rw
setenv bootcmd 'tftp ${loadaddr} ${zimage};tftp ${fdt_addr} ${fdt_file}; bootz ${loadaddr} - ${fdt_addr}'
saveenv

saveenvで設定した内容がNANDフラッシュに設定される。

u-bootでは起動すると、最初にbootcmdの内容を実行しようとするため、次回起動時からはLinuxがネットワーク越しに起動されるようになる。

ConnectCore i.MX6UL スターターキットで遊ぶ

DIGIのConnectCore i.MX6UL スターターキットチップワンストップで購入した。

このボードはラズベリーパイシリーズの40ピンのGPIOヘッダと互換のピンヘッダを搭載している。 つまりハードウェアレベルではラズベリーパイのHATやLCDなどのデバイスが使用できるだろうということ。

カーネルやドライバなどをどうにかして、その手のデバイスを動かしてみるのも面白そうだと思い購入することにした。

ボード立ち上げの基本的な作業はここを参考にしている。

yoctoの入手

このボードは標準でYoctoProjectのBSPが提供されている。

$ mkdir -p ~/yocto/dey-2.0
$ cd ~/yocto/dey-2.0
$ repo init -u https://github.com/digi-embedded/dey-manifest.git -b refs/tags/2.0-r4
$ repo sync -j4 --no-repo-verify

プロジェクトの作成

$ source ./mkproject.sh -l
ccimx6sbc ccimx6ulsbc ccimx6ulstarter
$ mkdir build && cd build
$ source ../mkproject.sh -p ccimx6ulstarter

BitBake実行

$ bitbake core-image-base

u-boot

ccimx6ul starterは出荷時点でNANDフラッシュにu-bootが書き込まれており、 シリアルコンソールの設定を行って電源をいれると、それが起動するようになっている。

初期状態の環境変数

arch=arm
baudrate=115200
board=ccimx6ulstarter
board_id=129
board_name=ccimx6ulstarter
board_version=2
boot_fdt=yes
bootargs_linux=cma=96M 
bootargs_nand_linux=setenv bootargs console=${console},${baudrate} ${bootargs_linux} ${mtdparts} ubi.mtd=${mtdlinuxindex} ubi.mtd=${mtdrootfsindex} root=ubi1_0 rootfstype=ubifs rw ${bootargs_once} ${extra_bootargs}
bootargs_recovery=setenv bootargs console=${console},${baudrate} androidboot.hardware=ccimx6ulstarter androidboot.console=${console}${mtdparts} ${bootargs_once} ${extra_bootargs}
bootcmd=if run loadscript; then source ${loadaddr};fi;
bootdelay=1
bscantest=PASS
btaddr=00:40:9D:98:A0:51
console=ttymxc4
cpu=armv7
eth1addr=00:40:9D:98:A0:4F
ethact=FEC0
ethaddr=00:40:9D:98:A0:4E
ethprime=FEC
fdt_addr=0x83000000
fdt_file=zImage-imx6ul-ccimx6ulstarter.dtb
fdt_high=0xffffffff
initrd_addr=0x83800000
initrd_file=uramdisk.img
initrd_high=0xffffffff
install_linux_fw_sd=if load mmc 0 ${loadaddr} install_linux_fw_sd.scr;then source ${loadaddr};fi;
ipaddr=192.168.42.30
linux_file=core-image-base-ccimx6ulstarter.boot.ubifs
loadaddr=0x80800000
loadscript=if ubi part linux; then if ubifsmount ubi0:linux; then ubifsload ${loadaddr} ${script};fi;fi;
module_variant=0x02
mtddevname=bootloader
mtddevnum=0
mtdids=nand0=gpmi-nand
mtdlinuxindex=3
mtdparts=mtdparts=gpmi-nand:3m(bootloader),1m(environment),1m(safe),14m(linux),14m(recovery),128m(rootfs),-(update)
mtdrootfsindex=5
netmask=255.255.0.0
partition=nand0,0
recovery_file=recovery.img
recoverycmd=if ubi part recovery; thenif ubifsmount ubi0:recovery; thenubifsload ${loadaddr} ${zimage};ubifsload ${fdt_addr} ${fdt_file};ubifsload ${initrs_addr} ${initrd_file};run bootargs_recovery;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};fi;fi;
rootfs_file=core-image-base-ccimx6ulstarter.ubifs
rootpath=/exports/nfsroot-ccimx6ulstarter
script=boot.scr
serverip=192.168.42.1
soc=mx6
stderr=serial
stdin=serial
stdout=serial
uboot_file=u-boot.imx
vendor=digi
verifyaddr=88400000
wlanaddr=00:04:f3:ff:ff:fb
zimage=zImage-ccimx6ulstarter.bin

カーネルやデバイスツリーをロードするために使用するDDR上のアドレスやファイル名などもあらかじめ、次のように変数として定義してある。

変数 説明
loadaddr 0x80800000 カーネルのロードアドレス
zimage zImage-ccimx6ulstarter.bin カーネルのファイル名
fdt_addr 0x83000000 バイスツリーのロードアドレス
fdt_file zImage-imx6ul-ccimx6ulstarter.dtb バイスツリーのファイル名

初期状態へ戻す

下記のコマンドで初期状態へ戻すことができる。

env default -a

カーネル、rootfsの書き込み

Digiのi.MX6UL Starter kitのu-bootは高機能なため、rootfsやカーネルなどの書き込み手順を一本化したupdateコマンドが用意されている。

updateコマンドはtftpサーバからイメージを取得するようになっているため、予め下記の設定をしておく必要がある。

setenv ipaddr x.y.z.w
setenv serverip a.b.c.d
saveenv
変数 説明
ipaddr ccimx6ulstarterのIPアドレス
serverip tftpサーバのIPアドレス

書き込みは次のように実行する。

update linux tftp core-image-base-ccimx6ulstarter.boot.ubifs
update rootfs tftp core-image-base-ccimx6ulstarter.ubifs
boot

最後のbootで書き込んだlinuxを起動している。

u-bootのbootcmdなどを見ると、NANDフラッシュにカーネルやルートファイルシステムをインストールし使用することを前提としているように見えるが、 内蔵のフラッシュロムには書き込み回数の上限、つまり寿命があるため、マイクロSDやNFSなどを使用し、なるべく内蔵のフラッシュロムを使用しない方法を検討する。

mortyでPandaboard ES Rev.B3

今更のPandaBoard ESをmortyで試してみる。 手元にあるのは悪名高きRev.B3。

Rev.B3はElpidaDDRを搭載しており、タイミングなどの設定が他のリビジョンと異なるため、 Pandaboard ESの他のリビジョンで動作するOSイメージをそのまま使用することができない。

ここをベースにYocotProjectで動くようにしてみた。

morty環境の作成

pokyを取得

~/pandaで作業する。

$ mkdir ~/panda
$ cd ~/panda
$ git clone git://git.yoctoproject.org/poky.git -b morty

meta-tiを取得

meta-tiには現時点でmortyブランチがないためmasterを取得する。

$ cd poky
$ git clone http://git.yoctoproject.org/git/meta-ti

meta-panda-es-rev-b3

Rev.B3のイメージを作成するためにmeta-panda-es-rev-b3を取得する。

$ git clone https://github.com/mickey-happygolucky/meta-panda-es-rev-b3.git

環境変数の設定

bitbakeの実行に必要な環境変数を読み込む。

$ cd ../
$ source poky/oe-init-build-env

レイヤの設定

ビルド対象にmeta-tiとmeta-panda-es-rev-b3を追加する。

$ bitbake-layers add-layer ../poky/meta-ti
$ bitbake-layers add-layer ../poky/meta-panda-es-rev-b3

local.confの設定

MACHINEをpandaboradに設定するため、local.confの頭の方に次を追加する。

MACHINE ?= "panda-es-rev-b3"

bitbakeの実行

core-image-minimalを生成する。

$ bitbake core-image-minimal

SDカードの作成

Pandaboardを起動するためにはSDカードの決まった場所にブートローダ(MLO,u-boot)を書き込む必要がある。 作業手順が複雑なため、スクリプトを作成した。

このスクリプトを使用してSDカードを作成する。

スクリプトのダウンロード

まずはスクリプトを取得し実行権限をつける。

$ wget https://gist.githubusercontent.com/mickey-happygolucky/40385889e3d013f00e1f97eb5ae04f95/raw/df99f41c760dcbed29340075cea49c749f9f6934/mksd_panda.sh
$ chmod +x ./mksd_panda.sh

スクリプトの実行

PCにSDカードをマウントした状態でスクリプトを実行する。

引数にはbitbakeで作成されたイメージの.tar.gzファイルを指定する。

実際には.tar.gzと同じディレクトリにあるカーネルブートローダもSDカードに書き込むため、 .tar.gz単体を他のディレクトリに移動して使用することはできないので注意。

$ ./mksd_panda.sh ./tmp/deploy/images/panda-es-rev-b3/core-image-minimal-panda-es-rev-b3.tar.gz

Pandaboard起動

作成したSDカードを挿入し、電源を投入する。

Poky (Yocto Project Reference Distro) 2.2 panda-es-rev-b3 /dev/ttyS2
                                                                                
panda-es-rev-b3 login: root
root@panda-es-rev-b3:~# uname -a
Linux panda-es-rev-b3 4.9.0+ #1 SMP Wed Jan 11 21:07:22 JST 2017 armv7l GNU/Linux
root@panda-es-rev-b3:~# 

無事、起動した。 今回はRS-232CでPCと接続しシリアルコンソールでログインしている。