Howto

目次

9.1. アプリケーションをコンテナで実行する
9.1.1. Podman - コンテナ仮想化ソフトウェア
9.1.2. コンテナを操作する
9.1.3. アットマークテクノが提供するイメージを使う
9.1.4. 入出力デバイスを扱う
9.1.5. 近距離通信を行う
9.1.6. ネットワークを扱う
9.1.7. サーバを構築する
9.1.8. セキュリティ
9.1.9. 画面表示を行う
9.1.10. パワーマネジメント機能を使う
9.1.11. コンテナからのpoweroffかreboot
9.1.12. 異常検知
9.1.13. NPU を扱う
9.2. コンテナの運用
9.2.1. コンテナの自動起動
9.2.2. podの作成
9.2.3. networkの作成
9.2.4. コンテナからのコンテナ管理
9.2.5. コンテナの配布
9.3. マルチメディアデータを扱う
9.3.1. GStreamer - マルチメディアフレームワーク
9.3.2. GStreamer 実行用コンテナを作成する
9.3.3. GStreamer パイプラインの実行例
9.3.4. 動画を再生する
9.3.5. ストリーミングデータを再生する
9.3.6. USB カメラからの映像を表示する
9.3.7. USBカメラからの映像を録画する
9.3.8. Video Processing Unit(VPU)
9.4. Armadilloのソフトウェアをビルドする
9.4.1. ブートローダーをビルドする
9.4.2. Linux カーネルをビルドする
9.4.3. Alpine Linux ルートファイルシステムをビルドする
9.5. SDブートの活用
9.5.1. ブートディスクの作成
9.5.2. SDブートの実行
9.6. Armadilloのソフトウェアの初期化
9.6.1. インストールディスクの作成
9.6.2. インストールディスクを使用した初期化
9.7. Armadilloのソフトウェアをアップデートする
9.7.1. SWUイメージとは?
9.7.2. SWUイメージの作成
9.7.3. イメージのインストール
9.7.4. hawkBitサーバーから複数のArmadilloに配信する
9.7.5. mkswu の desc ファイル
9.7.6. SWUpdate と暗号化について
9.8. Armadillo Base OS の操作
9.8.1. アップデート
9.8.2. overlayfs と persist_file について
9.8.3. ロールバック状態の確認
9.8.4. ボタンやキーを扱う
9.8.5. Armadillo Base OS 側の起動スクリプト
9.8.6. Network Time Protocol (NTP, ネットワーク・タイム・プロトコル)
9.9. Device Treeをカスタマイズする
9.9.1. at-dtweb のインストール
9.9.2. at-dtweb の起動
9.9.3. Device Tree をカスタマイズ
9.9.4. DTS overlays によるカスタマイズ
9.10. eMMC のデータリテンション
9.10.1. データリテンションの設定
9.10.2. より詳しくデータリテンションの統計情報を確認するには
9.10.3. 実装仕様に関する技術情報
9.11. デモアプリケーションを実行する
9.11.1. コンテナを作成する
9.11.2. weston を起動する
9.11.3. デモアプリケーションランチャを起動する
9.11.4. mediaplayer
9.11.5. video recoder
9.11.6. led switch tester
9.11.7. rtc tester
9.11.8. object detection demo
9.11.9. pose estimation demo
9.11.10. image segmentation demo
9.12. SMS を利用する
9.12.1. 初期設定
9.12.2. SMS を送信する
9.12.3. SMS を受信する
9.12.4. SMS 一覧を表示する
9.12.5. SMS の内容を表示する
9.12.6. SMS を削除する
9.12.7. SMS を他のストレージに移動する

9.1. アプリケーションをコンテナで実行する

9.1.1. Podman - コンテナ仮想化ソフトウェア

9.1.1.1. Podman - コンテナ仮想化ソフトウェアとは

コンテナとはホスト OS 上に展開される仮想的なユーザ空間のことです。 コンテナを使用することで複数の Armadillo-IoT ゲートウェイ G4 でも同一の環境がすぐに再現できます。 ゲスト OS を必要としない仮想化であるため、アプリケーションの起動が素早いという特徴があります。

Podman とはこのようなコンテナを管理するためのソフトウェアであり、使用方法は コンテナ管理ソフトウェアの 1 つである Docker と互換性があります。

9.1.2. コンテナを操作する

この章では、コンテナ仮想化ソフトウェアの 1 つである Podman の基本的な使い方について説明します。 Armadillo-IoT ゲートウェイ G4 で実行させたいアプリケーションとその実行環境自体を 1 つの Podman イメージとして扱うことで、 複数の Armadillo-IoT ゲートウェイ G4 がある場合でも、全てのボード上で同一の環境を再現させることが可能となります。

この章全体を通して、イメージの公開・共有サービスである Docker Hub から取得した、Alpine Linux のイメージを 使って説明します。

9.1.2.1. イメージからコンテナを作成する

イメージからコンテナを作成するためには、podman run コマンドを実行します。 イメージは Docker Hub から自動的に取得されます。 ここでは、簡単な例として "ls /" コマンドを実行するコンテナを作成します。

[armadillo ~]# podman run -it --name=my_container docker.io/alpine ls /
Trying to pull docker.io/library/alpine:latest...
Getting image source signatures
…
…
Writing manifest to image destination
Storing signatures
[ 3023.533900] IPv6: ADDRCONF(NETDEV_CHANGE): veth57ddda14: link becomes ready
[ 3023.541031] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 3023.547637] cni-podman0: port 1(veth57ddda14) entered blocking state
[ 3023.554026] cni-podman0: port 1(veth57ddda14) entered disabled state
[ 3023.560542] device veth57ddda14 entered promiscuous mode
[ 3023.565958] cni-podman0: port 1(veth57ddda14) entered blocking state
[ 3023.572318] cni-podman0: port 1(veth57ddda14) entered forwarding state
[ 3023.788098] cgroup: podman (1758) created nested cgroup for controller "memory" which has incomplete hierarchy suppo.
[ 3023.803249] cgroup: "memory" requires setting use_hierarchy to 1 on the root
[ 3023.812611] cgroup: cgroup: disabling cgroup2 socket matching due to net_prio or net_cls activation
[ 3023.837443] kmem.limit_in_bytes is deprecated and will be removed. Please report your usecase to linux-mm@kvack.org .
bin    etc    lib    mnt    proc   run    srv    tmp    var
dev    home   media  opt    root   sbin   sys    usr
armadillo:~# [ 3024.155747] cni-podman0: port 1(veth57ddda14) entered disabled state
[ 3024.162725] device veth57ddda14 left promiscuous mode
[ 3024.167819] cni-podman0: port 1(veth57ddda14) entered disabled state

図9.1 コンテナを作成する実行例


"ls /" を実行するだけの "my_container" という名前のコンテナが作成されました。 コンテナが作成されると同時に "ls /" が実行され、その結果が表示されています。 ここで表示されているのは、コンテナ内部の "/" ディレクトリのフォルダの一覧です。

podman run コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman run --help

図9.2 podman run --help の実行例


9.1.2.2. イメージ一覧を表示する

コンテナを作成するためのイメージは、イメージ一覧を表示する podman images コマンドで確認できます。

[armadillo ~]# podman images
REPOSITORY                TAG     IMAGE ID      CREATED      SIZE
docker.io/library/alpine  latest  9c74a18b2325  2 weeks ago  4.09 MB

図9.3 イメージ一覧の表示実行例


podman images コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman images --help

図9.4 podman images --help の実行例


9.1.2.3. コンテナ一覧を表示する

作成済みコンテナ一覧を表示するためには podman ps コマンドを実行します。

[armadillo ~]# podman ps -a
CONTAINER ID  IMAGE                            COMMAND    CREATED         STATUS                    PORTS    NAMES
d6de5881b5fb  docker.io/library/alpine:latest  ls /       12 minutes ago  Exited (0) 11 minutes ago          my_container

図9.5 コンテナ一覧の表示実行例


一覧表示により、コンテナ名やコンテナ ID を確認することができます。-a オプションを付けない場合は、動作中のコンテナのみ表示されます。 podman ps コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman ps --help

図9.6 podman ps --help の実行例


9.1.2.4. コンテナを起動する

作成済みのコンテナを起動するためには podman start コマンドを実行します。

[armadillo ~]# podman start my_container
podman start my_container
[ 3119.081068] IPv6: ADDRCONF(NETDEV_CHANGE): vethe172e161: link becomes ready
[ 3119.088214] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 3119.094812] cni-podman0: port 1(vethe172e161) entered blocking state
[ 3119.101231] cni-podman0: port 1(vethe172e161) entered disabled state
[ 3119.107745] device vethe172e161 entered promiscuous mode
[ 3119.113185] cni-podman0: port 1(vethe172e161) entered blocking state
[ 3119.119546] cni-podman0: port 1(vethe172e161) entered forwarding state
my_container
[ 3119.620731] cni-podman0: port 1(vethe172e161) entered disabled state
[ 3119.627696] device vethe172e161 left promiscuous mode
[ 3119.632762] cni-podman0: port 1(vethe172e161) entered disabled state

図9.7 コンテナを起動する実行例


-a オプションを与えると、コンテナ内で実行されたアプリケーションの出力を確認できます。

[armadillo ~]# podman start -a my_container
[ 3150.303962] IPv6: ADDRCONF(NETDEV_CHANGE): vetha9ef8f8e: link becomes ready
[ 3150.311106] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 3150.317703] cni-podman0: port 1(vetha9ef8f8e) entered blocking state
[ 3150.324139] cni-podman0: port 1(vetha9ef8f8e) entered disabled state
[ 3150.330687] device vetha9ef8f8e entered promiscuous mode
[ 3150.336085] cni-podman0: port 1(vetha9ef8f8e) entered blocking state
[ 3150.342443] cni-podman0: port 1(vetha9ef8f8e) entered forwarding state
bin    etc    lib    mnt    proc   run    srv    tmp    var
dev    home   media  opt    root   sbin   sys    usr
[ 3150.804164] cni-podman0: port 1(vetha9ef8f8e) entered disabled state
[ 3150.811249] device vetha9ef8f8e left promiscuous mode
[ 3150.816349] cni-podman0: port 1(vetha9ef8f8e) entered disabled state

図9.8 コンテナを起動する実行例(a オプション付与)


ここで起動している my_container は、起動時に "ls /" を実行するようになっているので、その結果が出力されます。 podman start コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman start --help

図9.9 podman start --help 実行例


9.1.2.5. コンテナを停止する

動作中のコンテナを停止するためには podman stop コマンドを実行します。

[armadillo ~]# podman stop my_container
my_container

図9.10 コンテナを停止する実行例


podman stop コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman stop --help

図9.11 podman stop --help 実行例


9.1.2.6. コンテナの変更を保存する

コンテナに対して変更が行われた状態で、そのままコンテナを停止してしまうと変更が失なわれてしまいます。

変更を保存するには podman commit コマンドを実行してください。

[armadillo ~]# podman commit my_container image_name:latest
Getting image source signatures
Copying blob f4ff586c6680 skipped: already exists
Copying blob 3ae0874b0177 skipped: already exists
Copying blob ea59ffe27343 done
Copying config 9ca3c55246 done
Writing manifest to image destination
Storing signatures
9ca3c55246eaac267a71731bad6bfe4b0124afcdd2b80c4f730c46aae17a88f3

図9.12 my_containerを保存する例


podman commitで保存する度に、変更が行なわれた差分が保存されます。繰り 返し差分を保存すると、イメージサイズが大きくなってしまいます。ストレー ジ容量が不足する場合は、ベースとなるOSのイメージから作り直してください。

9.1.2.7. コンテナの自動作成やアップデート

podman run, podman commitでコンテナを作成できますが、定期的にアップデートをする際には コンテナの作成やアップデートを自動化できると便利です。

これを実現するために、Dockerfileとpodman buildを使います。この手順はArmadilloで実行可能です。

  1. イメージを docker.io のイメージから作りなおします

    [armadillo ~/podman-build]# cat Dockerfile
    FROM docker.io/arm64v8/alpine:latest
    
    # update & install dependencies (example: usbutils)
    RUN apk update && apk upgrade && apk add usbutils && rm -f /var/cache/apk/*
    
    # copy our application and set it to run on start
    COPY my_application /my_application
    ENTRYPOINT /my_application
    
    [armadillo ~/podman-build]# podman build -t my_image:1 -t my_image:latest .
    STEP 1: FROM docker.io/arm64v8/alpine:latest
    STEP 2: RUN apk update && apk upgrade && apk add usbutils && rm -f /var/cache/apk/*
    --> 234bf79175e
    STEP 3: COPY my_application /my_application
    --> 05ab31bb278
    STEP 4: ENTRYPOINT /my_application
    STEP 5: COMMIT my_image:latest
    --> 590e3ba6d55
    Successfully tagged localhost/my_image:1
    Successfully tagged localhost/my_image:latest
    590e3ba6d55f3e29bdef158d7283e9c4f7515567b2d3f978cfab2510dc02376b
    
    [armadillo ~/podman-build]# podman save my_image:latest -o my_image_1.tar

    図9.13 podman buildの実行例


  2. イメージを前のバージョンからアップデートします

    [armadillo podman-build-update]# cat Dockerfile
    FROM localhost/my_image:latest
    
    # update OS packages
    RUN apk update && apk upgrade && rm -f /var/cache/apk/*
    
    # update application
    COPY my_application /my_application
    $ podman build -t my_image:2 -t my_image:latest .
    STEP 1: FROM localhost/my_image:latest
    STEP 2: RUN apk update && apk upgrade && rm -f /var/cache/apk/*
    --> cf1dc0d7296
    STEP 3: COPY my_application /my_application
    STEP 4: COMMIT my_image:latest
    --> 9e9d9366072
    Successfully tagged localhost/my_image:2
    Successfully tagged localhost/my_image:latest
    9e9d9366072751007b2e70544d76c46b95a7a5a02df658ef0fa3f7dcccf8850a
    
    [armadillo podman-build-update]# podman save -o my_image_2.tar my_image:2

    図9.14 podman buildでのアップデートの実行例


    この場合、 podman_partial_image コマンドを使って、差分だけをインストールすることもできます。

    [armadillo podman-build-update]# podman_partial_image -b my_image:1 \
            -o my_image_2_partial.tar my_image:2
    
    [armadillo podman-build-update]# ls -lh
    -rw-r--r-- 1 root root   88 Dec 21 15:24 Dockerfile
    -rw-r--r-- 1 root root 9.4M Dec 21 15:26 my_image_1.tar
    -rw-r--r-- 1 root root 9.4M Dec 21 15:26 my_image_2.tar
    -rw-r--r-- 1 root root  51K Dec 21 15:26 my_image_2_partial.tar

作成した .tar アーカイブは 「mkswu の desc ファイル」swdesc_embed_containerswdesc_usb_container で使えます。

9.1.2.8. コンテナを削除する

作成済みコンテナを削除する場合は podman rm コマンドを実行します。

[armadillo ~]# podman rm my_container
d6de5881b5fb973227b84d1d74abf269ac3183aad7e18b7a9d85208632641d94
[armadillo ~]# podman ps -a
CONTAINER ID  IMAGE                            COMMAND    CREATED         STATUS                    PORTS    NAMES

図9.15 コンテナを削除する実行例


podman ps コマンドの出力結果より、コンテナが削除されていることが確認できます。 podman rm コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman rm --help

図9.16 $ podman rm --help 実行例


9.1.2.9. イメージを削除する

podmanのイメージを削除するには podman rmi コマンドを実行します。 イメージを削除するためには、そのイメージから作成したコンテナを先に削除しておく必要があります。 podman rmi コマンドにはイメージ ID を指定する必要があるため、podman images コマンドで確認します。

[armadillo ~]# podman rm my_container
[armadillo ~]# podman images
REPOSITORY                TAG        IMAGE ID      CREATED      SIZE
docker.io/library/alpine  latest     02480aeb44d7  2 weeks ago  5.62 MB
[armadillo ~]# podman rmi 02480aeb44d7
Untagged: docker.io/library/alpine:latest
Deleted: 02480aeb44d78f1a44b8791af7edf7d6e1b18707397a1dfb3ff4f21c5ce4a44f
[armadillo ~]# podman images
REPOSITORY                TAG        IMAGE ID      CREATED      SIZE

図9.17 イメージを削除する実行例


podman images コマンドの出力結果より、コンテナが削除されていることが確認できます。 podman rmi コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman rmi --help

図9.18 podman rmi --help 実行例


[ティップ]

SWU で転送されたイメージは podman images で Read-Only として表示されますので、 podman rmi を実行するとエラーとなります。 その場合は abos-ctrl podman-rw rmi をご使用ください。 abos-ctrl podman-rw については 「イメージを eMMC に保存する方法」 を参照してください。

[armadillo ~]# podman images
REPOSITORY                TAG        IMAGE ID      CREATED      SIZE       R/O
docker.io/library/alpine  latest     02480aeb44d7  2 weeks ago  5.62 MB    true
[armadillo ~]# podman rmi docker.io/alpine
Error: cannot remove read-only image "02480aeb44d78f1a44b8791af7edf7d6e1b18707397a1dfb3ff4f21c5ce4a44f"
[armadillo ~]# abos-ctrl podman-rw rmi docker.io/alpine
Untagged: docker.io/library/alpine:latest
Deleted: 02480aeb44d78f1a44b8791af7edf7d6e1b18707397a1dfb3ff4f21c5ce4a44f
[armadillo ~]# podman images
REPOSITORY                TAG        IMAGE ID      CREATED      SIZE

図9.19 Read-Onlyのイメージを削除する実行例


9.1.2.10. 実行中のコンテナに接続する

実行中のコンテナに接続し、コンテナ内で指定したコマンドを実行するには podman exec コマンドを実行します。 podman exec コマンドでコンテナ内部のシェルを起動すると、コンテナ内部を操作できるようになります。ここでは、cat コマンドを 実行して入力を待ち続けるだけのコンテナを作成し、そのコンテナに対して podman exec コマンドでシェルを起動する例を示します。

[armadillo ~]# podman run -itd --name=cat_container docker.io/alpine cat
[ 3293.447517] IPv6: ADDRCONF(NETDEV_CHANGE): veth2a539346: link becomes ready
[ 3293.454645] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 3293.461201] cni-podman0: port 1(veth2a539346) entered blocking state
[ 3293.467619] cni-podman0: port 1(veth2a539346) entered disabled state
[ 3293.474139] device veth2a539346 entered promiscuous mode
[ 3293.479554] cni-podman0: port 1(veth2a539346) entered blocking state
[ 3293.485913] cni-podman0: port 1(veth2a539346) entered forwarding state
f62e7a666d7156d261905c8406c72fc271534fa29e69771c76f4f6660a2da41a
[armadillo ~]# podman exec -it cat_container /bin/sh
[container ~]# ps
PID   USER     TIME  COMMAND
    1 root      0:00 cat
    2 root      0:00 /bin/sh
    3 root      0:00 ps

図9.20 コンテナ内部のシェルを起動する実行例


podman run コマンドでコンテナを作成し、その後作成したコンテナ内で /bin/sh を実行しています。 /bin/sh を実行すると、コンテナ内のプロンプトが表示されコンテナ内部を操作できるようになります。 上記ではコンテナ内で、ps コマンドを実行しています。コンテナ作成時に実行した cat と podman exec で実行した /bin/sh がプロセスとして存在していることが確認できます。

コンテナ内のシェルから抜ける時は exit コマンドを実行します。

[container ~]# exit
[armadillo ~]#

図9.21 コンテナ内部のシェルから抜ける実行例


podman exec コマンドの詳細は --help オプションで確認できます。

[armadillo ~]# podman exec --help

図9.22 podman exec --help 実行例


9.1.2.11. コンテナ間で通信をする

複数のコンテナを実行している環境で、それらのコンテナ間で通信を行う方法を示します。 これにより、例えば SQL サーバを実行しているコンテナに対し別のコンテナから接続するといった 使い方ができます。

コンテナには作成した時点でローカル IP アドレスが割り当てられるので、その IP アドレスで通信を行うことができます。

準備として、2 つのコンテナを作成します。

[armadillo ~]# podman run -itd --name=my_container_1 docker.io/alpine /bin/sh
[ 3336.121730] IPv6: ADDRCONF(NETDEV_CHANGE): veth487e45d1: link becomes ready
[ 3336.128875] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 3336.135485] cni-podman0: port 2(veth487e45d1) entered blocking state
[ 3336.141877] cni-podman0: port 2(veth487e45d1) entered disabled state
[ 3336.148395] device veth487e45d1 entered promiscuous mode
[ 3336.153792] cni-podman0: port 2(veth487e45d1) entered blocking state
[ 3336.160151] cni-podman0: port 2(veth487e45d1) entered forwarding state
cbe0802f4e2d2fec88f4e300dabeba3b48865359dc02cbd99375b1b38c2c28eb
[armadillo ~]# podman run -itd --name=my_container_2 docker.io/alpine /bin/sh
podman run -itd --name=my_container_2 docker.io/alpine /bin/sh
[ 3351.593435] IPv6: ADDRCONF(NETDEV_CHANGE): vethad55f5c8: link becomes ready
[ 3351.600594] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 3351.607579] cni-podman0: port 3(vethad55f5c8) entered blocking state
[ 3351.613988] cni-podman0: port 3(vethad55f5c8) entered disabled state
[ 3351.620528] device vethad55f5c8 entered promiscuous mode
[ 3351.625896] cni-podman0: port 3(vethad55f5c8) entered blocking state
[ 3351.632257] cni-podman0: port 3(vethad55f5c8) entered forwarding state
5e645f5e40fc096ad0bea323a00bebebbda4bd825a5e8d12103f752d8868692e

図9.23 コンテナを作成する実行例


コンテナに割り当てられた IP アドレスを確認するには podman inspect コマンドを実行します。

[armadillo ~]# podman inspect --format='{{.NetworkSettings.IPAddress}}' my_container_1
10.88.0.108
[armadillo ~]# podman inspect --format='{{.NetworkSettings.IPAddress}}' my_container_2
10.88.0.109

図9.24 コンテナの IP アドレスを確認する実行例


これらの IP アドレスを使って、一方のコンテナからもう一方のコンテナへ対し ping コマンドで疎通確認を行うことができます。

[armadillo ~]# podman exec -it my_container_1 /bin/sh
[container ~]# ping -c 3 10.88.0.109
PING 10.88.0.109 (10.88.0.109): 56 data bytes
64 bytes from 10.88.0.109: seq=0 ttl=42 time=0.140 ms
64 bytes from 10.88.0.109: seq=1 ttl=42 time=0.138 ms
64 bytes from 10.88.0.109: seq=2 ttl=42 time=0.128 ms

--- 10.88.0.109 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.128/0.135/0.140 ms

図9.25 ping コマンドによるコンテナ間の疎通確認実行例


このように、my_container_1(10.88.0.108) から my_container_2(10.88.0.109) への通信が確認できます。

9.1.2.12. 開発時に有用な--privilegedオプション

コンテナに、全権限と全てのデバイスへのアクセスを許可するオプション --privileged があります。このオプションを利用すると、コンテナに与えるべき最小の権限を洗い出す必要が無いため、開発時に有用です。

実運用の際、このオプションを利用することはセキュリティー上問題がある為、開発時にのみご利用ください。コンテナに必要な最低限の権限を与えることをおすすめします。

9.1.3. アットマークテクノが提供するイメージを使う

アットマークテクノは、動作確認環境として使用できる Debian ベースのイメージを提供しています。 ここでは、Docker ファイルからイメージをビルドする方法と、すでにビルド済みのイメージを使う方法の 2 つについて説明します。

9.1.3.1. Docker ファイルからイメージをビルドする

Armadillo-IoT ゲートウェイ G4 コンテナ から 「Debian [VERSION] サンプル Dockerfile」 ファイル (at-debian-image-dockerfile-[VERSION].tar.gz) をダウンロードします。 その後 podman build コマンドを実行します。

[armadillo ~]# tar xzf at-debian-image-dockerfile-[VERSION].tar.gz
[armadillo ~]# cd at-debian-image-dockerfile-[VERSION]
[armadillo ~]# abos-ctrl podman-storage --disk
[armadillo ~]# podman build -t at-debian-image:latest .
:
: (省略)
:
[armadillo ~]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED             SIZE
localhost/at-debian-image  latest      c8e8d2d55456  About a minute ago  233 MB
docker.io/library/debian   bullseye    723b4a01cd2a  18 hours ago        123 MB

図9.26 Docker ファイルによるイメージのビルドの実行例


podman images コマンドにより at-debian-image がビルドされたことが確認できます。 library/debian イメージはベースとなっている Debian イメージです。

9.1.3.2. ビルド済みのイメージを使用する

Armadillo-IoT ゲートウェイ G4 コンテナ から 「Debian [VERSION] サンプルコンテナイメージ」 ファイル (at-debian-image-[VERSION].tar) をダウンロードします。 その後 podman load コマンドを実行します。

[armadillo ~]# podman load -i at-debian-image-[VERSION].tar
:
: (省略)
:
[armadillo ~]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED       SIZE
localhost/at-debian-image  [VERSION]   93a4ec873ac5  17 hours ago  233 MB
localhost/at-debian-image  latest      93a4ec873ac5  17 hours ago  233 MB

図9.27 ビルド済みイメージを load する実行例


podman images コマンドにより at-debian-image がビルドされたことが確認できます。

9.1.4. 入出力デバイスを扱う

この章では、コンテナ内で動作するアプリケーションから GPIO や I2C などの入出力デバイスを扱う方法について示します。 基本的に、コンテナ内のアプリケーションからホスト OS 側のデバイスへアクセスすることはできません。 このため、コンテナ内のアプリケーションからデバイスを扱うためには、コンテナ作成時に扱いたいデバイスを指定する必要があります。 ここで示す方法は、扱いたいデバイスに関するデバイスツリーファイルが適切に設定されていることを前提としています。 デバイスツリーファイルを設定していない場合は、適切に設定してください。

9.1.4.1. GPIO を扱う

コンテナ内で動作するアプリケーションから GPIO を扱うためには、Podman のイメージからコンテナを作成する際にホスト OS 側の デバイスファイル /dev/gpiochipN を渡す必要があります。以下は、/dev/gpiochip2 を渡して alpine イメージからコンテナを作成する例です。 /dev/gpiochipN を渡すと、GPION+1 を操作することができます。

[armadillo ~]# podman run -itd --name=gpio_example --device=/dev/gpiochip2 docker.io/alpine /bin/sh

図9.28 GPIO を扱うためのコンテナ作成例


コンテナ内に入ってコマンドで GPIO を操作する例を以下に示します。この例では GPIO3_IO21 を操作しています。

[armadillo ~]# podman exec -it gpio_example /bin/sh
[container ~]# apk update && apk upgrade
[container ~]# apk add libgpiod
[container ~]# gpioget gpiochip2 21 1
0 2
[container ~]# gpioset gpiochip2 21=1 3

図9.29 コンテナ内からコマンドで GPIO を操作する例


1

GPIO 番号 21 の値を取得します。

2

取得した値を表示します。

3

GPIO 番号 21 に 1(High) を設定します。

他にも、gpiodetect コマンドで認識している gpiochip をリスト表示できます。 以下の例では、コンテナを作成する際に渡した /dev/gpiochip2 が認識されていることが確認できます。

[container ~]# gpiodetect
gpiochip2 [30220000.gpio] (32 lines)

図9.30 gpiodetect コマンドの実行


gpioinfo コマンドでは、指定した gpiochip の詳細な情報を表示することができます。

[container ~]# gpioinfo gpiochip2
gpiochip2 - 32 lines:
        line   0:      unnamed          "?"  output  active-high [used]
        line   1:      unnamed       unused   input  active-High
        line   2:      unnamed       unused   input  active-high
        line   3:      unnamed       unused   input  active-high
        line   4:      unnamed       unused   input  active-high
        line   5:      unnamed       unused   input  active-high
        line   6:      unnamed       unused   input  active-high
        line   7:      unnamed       unused   input  active-high
        line   8:      unnamed       unused   input  active-high
        line   9:      unnamed       unused   input  active-high
        line  10:      unnamed       unused   input  active-high
        line  11:      unnamed       unused   input  active-high
        line  12:      unnamed       unused   input  active-high
        line  13:      unnamed       unused   input  active-high
        line  14:      unnamed       unused   input  active-high
        line  15:      unnamed       unused   input  active-high
        line  16:      unnamed       unused   input  active-high
        line  17:      unnamed       unused   input  active-high
        line  18:      unnamed       unused   input  active-high
        line  19:      unnamed       unused   input  active-high
        line  20:      unnamed       unused   input  active-high
        line  21:      unnamed       unused   input  active-high
        line  22:      unnamed       unused   input  active-high
        line  23:      unnamed       unused   input  active-high
        line  24:      unnamed       unused   input  active-high
        line  25:      unnamed       unused   input  active-high
        line  26:      unnamed       unused   input  active-high
        line  27:      unnamed       unused   input  active-high
        line  28:      unnamed       unused   input  active-high
        line  29:      unnamed       unused   input  active-high
        line  30:      unnamed       unused   input  active-high
        line  31:      unnamed       unused   input  active-high

図9.31 gpioinfo コマンドの実行


C 言語プログラムから操作する場合は、GPIO 操作ライブラリである libgpiod を使用することができます。

9.1.4.2. I2C を扱う

コンテナ内で動作するアプリケーションから I2C を扱うためには、Podman のイメージからコンテナを作成する際にホスト OS 側の デバイスファイル /dev/i2c-N を渡す必要があります。以下は、/dev/i2c-1 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=i2c_example --device=/dev/i2c-1 docker.io/alpine /bin/sh

図9.32 I2C を扱うためのコンテナ作成例


コンテナ内に入り、i2c-tools に含まれる i2cdetect コマンドを使ってスレーブアドレスを確認することができます。

[armadillo ~]# podman exec -it i2c_example /bin/sh
[container ~]# apk update && apk upgrade
[container ~]# apk add i2c-tools
[container ~]# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- UU -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- UU -- -- --
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- 72 -- -- -- -- --

図9.33 i2cdetect コマンドによる確認例


[ティップ]

自動起動の場合はdevicesの設定でi2c-1を渡すことができます。

[armadillo ~]# vi /etc/atmark/containers/i2c_example.conf
set_image localhost/i2c_example_image
add_devices "/dev/i2c-1"
set_command /root/do_something_with_i2c.sh

9.1.4.3. SPI を扱う

コンテナ内で動作するアプリケーションから SPI を扱うためには、Podman のイメージからコンテナを作成する際にホスト OS 側の デバイスファイル /dev/spidevN.N を渡す必要があります。以下は、/dev/spidev1.0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=spi_example --device=/dev/spidev1.0 docker.io/alpine /bin/sh

図9.34 SPI を扱うためのコンテナ作成例


コンテナ内に入り、spi-tools に含まれる spi-config コマンドを使って現在の設定を確認することができます。

[armadillo ~]# podman exec -it spi_example /bin/sh
[container ~]# apk update && apk upgrade
[container ~]# apk add spi-tools
[container ~]# spi-config --device=/dev/spidev1.0 -q
/dev/spidev1.0: mode=0, lsb=0, bits=8, speed=500000, spiready=0

図9.35 spi-config コマンドによる確認例


9.1.4.4. CAN を扱う

コンテナ内で動作するアプリケーションから CAN 通信を行うためには、 Podman のイメージからコンテナを作成する際に、コンテナを実行するネットワークとして host を、 権限として NET_ADMIN を指定する必要があります。 以下は、ネットワークとして host を、権限として NET_ADMIN を指定して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=can_example --net=host --cap-add=NET_ADMIN docker.io/alpine /bin/sh

図9.36 CAN を扱うためのコンテナ作成例


コンテナ内に入り、ip コマンドで CAN を有効にすることができます。 以下に、設定例を示します。

[armadillo ~]# podman exec -it can_example /bin/sh
[container ~]# apk update && apk upgrade
[container ~]# apk add iproute2 1
[container ~]# ip link set can0 type can bitrate 125000 2
[container ~]# ip link set can0 up 3
[container ~]# ip -s link show can0 4
4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT
group default qlen 10
    link/can
    RX: bytes  packets  errors  dropped missed  mcast
    0          0        0       0       0       0
    TX: bytes  packets  errors  dropped carrier collsns
    0          0        0       0       0       0

図9.37 CAN の設定例


1

CAN の設定のために必要な iproute2 をインストールします。すでにインストール済みの場合は不要です。

2

CAN の通信速度を 125000 kbps に設定します。

3

can0 インターフェースを起動します。

4

can0 インターフェースの現在の使用状況を表示します。

9.1.4.5. PWM を扱う

コンテナ内で動作するアプリケーションから PWM を扱うためには、 Podman のイメージからコンテナを作成する際にホスト OS 側の /sys ディレクトリを渡す必要があります。 以下は、/sys を渡して alpine イメージからコンテナを作成する例です。ここで渡された /sys ディレクトリは コンテナ内の /sys にマウントされます。

[armadillo ~]# podman run -itd --name=pwm_example --volume=/sys:/sys docker.io/alpine /bin/sh

図9.38 PWM を扱うためのコンテナ作成例


コンテナ内に入り、/sys/class/pwm/pwmchipN ディレクトリ内の export ファイルに 0 を書き込むことで扱えるようになります。 以下に、/sys/class/pwm/pwmchip2 を扱う場合の動作設定例を示します。

[armadillo ~]# podman exec -it pwm_example /bin/sh
[container ~]# echo 0 > /sys/class/pwm/pwmchip2/export 1
[container ~]# echo 1000000000 > /sys/class/pwm/pwmchip2/pwm0/period  2
[container ~]# echo 500000000 > /sys/class/pwm/pwmchip2/pwm0/duty_cycle 3
[container ~]# echo 1 > /sys/class/pwm/pwmchip2/pwm0/enable 4

図9.39 PWM の動作設定例


1

pwmchip2 を export します。

2

周期を 1 秒にします。単位はナノ秒です。

3

PWM の ON 時間 を 0.5 秒にします。

4

PWM 出力を有効にします。

9.1.4.6. シリアルインターフェースを扱う

コンテナ内で動作するアプリケーションから RS-232C や RS-485 などのシリアル通信を行うためには、 Podman のイメージからコンテナを作成する際にホスト OS 側のデバイスファイル /dev/ttymxcN を渡す必要があります。 以下は、/dev/ttymxc0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=serial_example --device=/dev/ttymxc0 docker.io/alpine /bin/sh

図9.40 シリアルインターフェースを扱うためのコンテナ作成例


コンテナ内に入り、setserial コマンドを使って現在の設定を確認することができます。

[armadillo ~]# podman exec -it serial_example /bin/sh
[container ~]# setserial -a /dev/ttymxc0
/dev/ttymxc0, Line 0, UART: undefined, Port: 0x0000, IRQ: 29
        Baud_base: 5000000, close_delay: 50, divisor: 0
        closing_wait: 3000
        Flags: spd_normal

図9.41 setserial コマンドによるシリアルインターフェイス設定の確認例


9.1.4.7. USB を扱う

コンテナ内で動作するアプリケーションから USB 接続のデバイスを扱うための方法について示します。

  • USB シリアルデバイスを扱う

USB シリアルデバイスをコンテナ内から扱う場合には、Podman のイメージからコンテナを作成する際に ホスト OS 側の /dev/ttyUSBN を渡す必要があります。 以下は、 /dev/ttyUSB0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=usb_example --device=/dev/ttyUSB0 docker.io/alpine /bin/sh

図9.42 USB シリアルデバイスを扱うためのコンテナ作成例


コンテナ内に入り、setserial コマンドを使って現在の設定を確認することができます。

[armadillo ~]# podman exec -it usb_example /bin/sh
[container ~]# setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
        Baud_base: 24000000, close_delay: 0, divisor: 0
        closing_wait: infinite
        Flags: spd_normal

図9.43 setserial コマンドによるUSBシリアルデバイス設定の確認例


  • USB カメラを扱う

USB カメラをコンテナ内から扱う場合には、Podman のイメージからコンテナを作成する際に ホスト OS 側の /dev/videoN を渡す必要があります。 以下は、 /dev/video3 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=usbcam_example --device=/dev/video3 docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it usbcam_example /bin/sh
[container ~]# ls /dev/video3
/dev/video3

図9.44 USB カメラを扱うためのコンテナ作成例


GStreamer などのマルチメディアフレームワークと組み合わせることで、USB カメラからの映像のキャプチャが可能となります。

  • USB メモリを扱う

ここでは、USB メモリを扱う方法について 2 つの例を示します。

  • ホスト OS 側でマウントした USB メモリをコンテナから扱う

あらかじめホスト OS 側でマウントしてある USB メモリをコンテナから扱う場合には、Podman のイメージから コンテナを作成する際にホスト OS 側で USB メモリをマウントしてるディレクトリを渡す必要があります。

[armadillo ~]# mount -t vfat /dev/sda1 /mnt
[armadillo ~]# echo test >> /mnt/sample.txt
[armadillo ~]# ls /mnt
sample.txt

図9.45 USB メモリをホスト OS 側でマウントする例


上記の例では、USB メモリを /mnt にマウントしました。以下は、 /mnt を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=usbmem_example --volume=/mnt:/mnt docker.io/alpine /bin/sh

図9.46 ホスト OS 側でマウント済みの USB メモリを扱うためのコンテナ作成例


ホスト OS 側の /mnt ディレクトリをコンテナ内の /mnt にマウントしています。 これにより、コンテナ内からも /mnt ディレクトリを通して USB メモリを扱うことができます。

[armadillo ~]# podman exec -it usbmem_example /bin/sh
[container ~]# ls /mnt
sample.txt
[container ~]# cat /mnt/sample.txt
test

図9.47 USB メモリに保存されているデータの確認例


  • USB メモリをコンテナ内からマウントする

USB メモリをコンテナ内からマウントして扱う場合には、Podman のイメージからコンテナを作成する際に ホスト OS 側の /dev ディレクトリを渡すと同時に、適切な権限も渡す必要があります。 以下は、 /dev を渡して alpine イメージからコンテナを作成する例です。権限として SYS_ADMIN と SYS_RAWIO も渡しています。

[armadillo ~]# podman run -itd --name=usbmem_example --cap-add=SYS_RAWIO --cap-add=SYS_ADMIN --device=/dev/sda --device=/dev/sda1 docker.io/alpine /bin/sh

図9.48 USB メモリをマウントするためのコンテナ作成例


コンテナ内に入り、mount コマンドで USB メモリを /mnt にマウントし、保存されているデータを確認することができます。

[armadillo ~]# podman exec -it usbmem_example /bin/sh
[container ~]# mount /dev/sda1 /mnt
[container ~]# ls /mnt
sample.txt
[container ~]# cat /mnt/sample.txt
test

図9.49 コンテナ内から USB メモリをマウントする例


  • USB デバイスのホットプラグに対応する

通常、コンテナ内から USB デバイスを扱うためには、あらかじめ Armadillo-IoT ゲートウェイ G4 本体に USB デバイスを接続した状態で、コンテナを起動する必要があります。 コンテナ起動後に USB デバイスを接続して認識させるためには、/dev を volume としてコンテナ内にマウントする必要があります。 以下は、 volume として /dev を渡して alpine イメージからコンテナを作成する例です。イベントの通知のために --net=host も渡す必要があります。

[armadillo ~]# podman run -itd --name=usbhotplug_example --volume=/dev:/dev --net=host docker.io/alpine /bin/sh

図9.50 USB デバイスのホットプラグに対応する例


9.1.4.8. RTC を扱う

コンテナ内から RTC を扱うためには、Podman のイメージからコンテナを作成する際にホスト OS 側の デバイスファイル /dev/rtcN を渡すと同時に、RTC への時刻の設定を行うための権限も渡す必要があります。 以下は、/dev/rtc0 を渡して alpine イメージからコンテナを作成する例です。権限として SYS_TIME も渡しています。

[armadillo ~]# podman run -itd --name=rtc_example --cap-add=SYS_TIME --device=/dev/rtc0 docker.io/alpine /bin/sh

図9.51 RTC を扱うためのコンテナ作成例


コンテナ内に入り、hwclock コマンドで RTC の時刻表示と設定ができます。

[armadillo ~]# podman exec -it rtc_example /bin/sh
[container ~]# hwclock 1
Thu Feb 18 05:14:37 2021  0.000000 seconds
[container ~]# date --set "2021-04-01 09:00:00" 2
Thu Apr  1 09:00:00 UTC 2021
[container ~]# hwclock --systohc 3
[container ~]# hwclock 4
Thu Apr  1 09:00:28 2021  0.000000 seconds

図9.52 hwclock コマンドによるRTCの時刻表示と設定例


1

RTC に設定されている現在時刻を表示します。

2

システム時刻を 2021 年 4 月 1 日 9 時 0 分 0 秒に設定します。

3

システム時刻を RTC に反映させます。

4

RTC に設定されている時刻が変更されていることを確認します。

9.1.4.9. 音声出力を行う

Armadillo-IoT ゲートウェイ G4 に接続したスピーカーなどの音声出力デバイスへコンテナ内から音声を出力するためには、 Podman のイメージからコンテナを作成する際にホスト OS 側のデバイスファイル /dev/snd を渡す必要があります。 以下は、/dev/snd を渡して debian イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=snd_example --device=/dev/snd docker.io/debian /bin/bash

図9.53 音声出力を行うためのコンテナ作成例


コンテナ内に入り、alsa-utils などのソフトウェアで音声出力を行えます。

[armadillo ~]# podman exec -it snd_example /bin/bash
[container ~]# apt update && apt upgrade
[container ~]# apt install alsa-utils 1
[container ~]# /etc/init.d/alsa-utils start 2
[container ~]# aplay -D hw:N,M [ファイル名] 3

図9.54 alsa-utils による音声出力を行う例


1

alsa-utils をインストールします。

2

alsa-utils を起動します。

3

指定したファイル名の音声ファイルを再生します。

aplay の引数にある、M は音声を出力したい CARD 番号、N はデバイス番号を表しています。 CARD 番号とデバイス番号は、aplay コマンドに -l オプションを与えることで確認できます。

9.1.4.10. ユーザースイッチのイベントを取得する

Armadillo-IoT ゲートウェイ G4 にはユーザースイッチが実装されています。これらのスイッチのプッシュ/リリースイベントを取得するためには、 Podman のイメージからコンテナを作成する際にホスト OS 側の /dev/input ディレクトリを渡す必要があります。 以下は、/dev/input を渡して alpine イメージからコンテナを作成する例です。ここで渡された /dev/input ディレクトリは コンテナ内の /dev/input にマウントされます。

[armadillo ~]# podman run -itd --name=sw_example --device=/dev/input docker.io/alpine /bin/sh

図9.55 ユーザースイッチのイベントを取得するためのコンテナ作成例


コンテナ内に入り、evtest コマンドでイベントを確認できます。

[armadillo ~]# podman exec -it sw_example /bin/sh
[container ~]# apk update && apk upgrade
[container ~]# apk add evtest
[container ~]# evtest /dev/input/event1
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "gpio-keys"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 28 (KEY_ENTER)
Properties:
Testing ... (interrupt to exit)
Event: time 1612849227.554456, type 1 (EV_KEY), code 28 (KEY_ENTER), value 1  1
Event: time 1612849227.554456, -------------- SYN_REPORT ------------
Event: time 1612849229.894444, type 1 (EV_KEY), code 28 (KEY_ENTER), value 0  2
Event: time 1612849229.894444, -------------- SYN_REPORT ------------

図9.56 evtest コマンドによる確認例


1

SW1のボタン プッシュ イベントを検出したときの表示

2

SW1のボタン リリース イベントを検出したときの表示

9.1.4.11. LED を扱う

Armadillo-IoT ゲートウェイ G4 には LED が実装されています。これらの LED を扱うためには、 Podman のイメージからコンテナを作成する際にホスト OS 側の /sys ディレクトリを渡す必要があります。 以下は、/sys を渡して alpine イメージからコンテナを作成する例です。ここで渡された /sys ディレクトリは コンテナ内の /sys にマウントされます。

[armadillo ~]# podman run -itd --name=led_example --volume=/sys:/sys docker.io/alpine /bin/sh

図9.57 LED を扱うためのコンテナ作成例


コンテナ内に入り、brightness ファイルに値を書き込むことで LED の点灯/消灯を行うことができます。 0 を書き込むと消灯、0 以外の値 (1〜255) を書き込むと点灯します。

[armadillo ~]# podman exec -it led_example /bin/sh
[container ~]# echo 0 > /sys/class/leds/led1/brightness
[container ~]# echo 1 > /sys/class/leds/led1/brightness

図9.58 LED の点灯/消灯の実行例


9.1.5. 近距離通信を行う

この章では、コンテナ内から近距離通信デバイスを扱う方法について示します。

9.1.5.1. Bluetooth デバイスを扱う

コンテナ内から Bluetooth デバイスを扱うためには、Podman のイメージからコンテナを作成する際にホスト OS 側の デバイスファイル /dev/ttymxcN を渡すと同時にネットワークとして host を、権限として NET_ADMIN を渡す必要があります。 /dev/ttymxcN は Bluetooth 通信で使用するように設定したシリアルデバイスを指定してください。 以下は、/dev/ttymxc0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=bt_example --net=host --device=/dev/ttymxc0 --cap-add=NET_ADMIN docker.io/alpine /bin/sh

図9.59 Bluetooth デバイスを扱うためのコンテナ作成例


コンテナ内で必要なソフトウェアをインストールして、Bluetooth を起動します。 btattach コマンドの引数にはコンテナ作成時に渡した ttymxc を設定してください。

[armadillo ~]# podman exec -it bt_example /bin/sh
[container ~]# apk update && apk upgrade
[container ~]# apk add bluez dbus
[container ~]# /usr/bin/dbus-daemon --system
[container ~]# /usr/lib/bluetooth/bluetoothd &
[container ~]# btattach -B /dev/ttymxc0 -S 115200 &

図9.60 Bluetooth を起動する実行例


これにより、bluetoothctl で Bluetooth 機器のスキャンやペアリングなどが行えるようになります。 以下に、bluetoothctl コマンドで周辺機器をスキャンしてペアリングを行う例を示します。

[container ~]# bluetoothctl
Agent registerd
[..CHG..] Controller XX:XX:XX:XX:XX:XX Pairable: yes
[bluetooth]# power on 1
Changing power on succeeded
[..CHG..] Controller XX:XX:XX:XX:XX:XX Powered: yes
[bluetooth]# scan on 2
Discovery started
[..CHG..] Controller XX:XX:XX:XX:XX:XX Discovering: yes
[..NEW..] Device AA:AA:AA:AA:AA:AA AA-AA-AA-AA-AA-AA
[..NEW..] Device BB:BB:BB:BB:BB:BB BB-BB-BB-BB-BB-BB
[..NEW..] Device CC:CC:CC:CC:CC:CC CC-CC-CC-CC-CC-CC
[..NEW..] Device DD:DD:DD:DD:DD:DD DD-DD-DD-DD-DD-DD
[..NEW..] Device EE:EE:EE:EE:EE:EE EE-EE-EE-EE-EE-EE
[bluetooth]# pair AA:AA:AA:AA:AA:AA 3
[bluetooth]# exit 4
[container ~]#

図9.61 bluetoothctl コマンドによるスキャンとペアリングの例


1

コントローラを起動します。

2

周辺機器をスキャンします。

3

ペアリングしたい機器の MAC アドレスを指定してペアリングします。

4

exit で bluetoothctl のプロンプトを終了します。

9.1.5.2. Wi-SUN デバイスを扱う

ここでは、Wi-SUN デバイスが UART で接続されている場合の例を示します。 この場合、コンテナ内で動作するアプリケーションから Wi-SUN デバイスで通信を行うためには、 Podman のイメージからコンテナを作成する際にホスト OS 側のデバイスファイル /dev/ttymxcN のうち、 Wi-SUN と対応するものを渡す必要があります。 以下は、/dev/ttymxc0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=wisun_example --device=/dev/ttymxc0 docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it wisun_example /bin/sh
[container ~]# ls /dev/ttymxc0
/dev/ttymxc0

図9.62 Wi-SUN デバイスを扱うためのコンテナ作成例


コンテナ内から、/dev/ttymxc0 を使って Wi-SUN データの送受信ができるようになります。

9.1.5.3. EnOcean デバイスを扱う

ここでは、EnOcean デバイスが UART で接続されている場合の例を示します。 この場合、コンテナ内で動作するアプリケーションから EnOcean デバイスで通信を行うためには、 Podman のイメージからコンテナを作成する際にホスト OS 側のデバイスファイル /dev/ttymxcN のうち、 EnOcean と対応するものを渡す必要があります。 以下は、/dev/ttymxc0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=enocean_example --device=/dev/ttymxc0 docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it enocean_example /bin/sh
[container ~]# ls /dev/ttymxc0
/dev/ttymxc0

図9.63 EnOcean デバイスを扱うためのコンテナ作成例


コンテナ内から、/dev/ttymxc0 を使って EnOcean データの送受信ができるようになります。

9.1.6. ネットワークを扱う

この章では、コンテナ内のネットワークを扱う方法について示します。

9.1.6.1. コンテナの IP アドレスを確認する

基本的にコンテナの IP アドレスは Podman イメージからコンテナを作成したときに自動的に割り振られます。 コンテナに割り振られている IP アドレスはホスト OS 側からは podman inspect コマンドを用いて、以下のように確認することができます。

[armadillo ~]# podman run -itd --name=net_example docker.io/alpine /bin/sh
[armadillo ~]# podman inspect --format '{{ .NetworkSettings.IPAddress }}' net_example
10.88.0.17

図9.64 コンテナの IP アドレス確認例


コンテナ内の ip コマンドを用いて確認することもできます。

[armadillo ~]# podman run -itd --name=net_example docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it net_example /sbin/ip addr show eth0
3: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 10.88.0.17/16 brd 10.88.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::40e5:98ff:feec:4b17/64 scope link
       valid_lft forever preferred_lft forever

図9.65 ip コマンドを用いたコンテナの IP アドレス確認例


9.1.6.2. コンテナに固定 IP アドレスを設定する

[警告]

podman はデフォルトで 10.88.0.0/16 を使います。

他に使用しているIPアドレスと被った場合等はコンテナに別のIPアドレスを設定してください。

コンテナに固定 IP アドレスを設定するためには、最初にユーザ定義のネットワークを作成する必要があります。 以下に 192.168.1.0/24 にユーザ定義のネットワークを作成する例を示します。

[armadillo ~]# podman network create --subnet=192.168.1.0/24 my_network

図9.66 ユーザ定義のネットワーク作成例


コンテナを作成する際に、上記で作成したネットワークと設定したい IP アドレスを渡すことで、 コンテナの IP アドレスを固定することができます。 以下の例では、IPアドレスを 192.168.1.10 に固定します。

[armadillo ~]# podman run -itd --name=network_example --net=my_network --ip=192.168.1.10 docker.io/alpine /bin/sh

図9.67 IP アドレス固定のコンテナ作成例


コンテナの IP アドレスが、192.168.1.10 に設定されていることが確認できます。

[armadillo ~]# podman inspect --format '{{ .NetworkSettings.Networks.my_network.IPAddress }}' network_example
192.168.1.10

図9.68 コンテナの IP アドレス確認例


[ティップ]

Armadillo-IoT ゲートウェイ G4 を再起動したときにネットワークの設定ファイルが消えてしまわないように、 /etc/atmark/containers に設定する必要があります

[armadillo ~]# vi /etc/atmark/containers/my_network.conf
set_type network
set_subnet 192.168.1.0/24
[armadillo ~]# persist_file /etc/atmark/containers/my_network.conf

persist_file コマンドに関する詳細は「overlayfs と persist_file について」を参照してください。

9.1.7. サーバを構築する

この章では、コンテナ内で様々なサーバを構築する方法について示します。 この章で取り上げているサーバは alpine の apk コマンドでインストールすることが可能です。

9.1.7.1. HTTP サーバを構築する

ここでは、HTTP サーバとして Apache と lighttpd の 2 種類を使用する場合について説明します。

  • Apache を使用する

alpine イメージからコンテナを作成し、そのコンテナ内に Apache をインストールします。 コンテナ作成の際に、ホスト OS の 8080 番ポートをコンテナ内の 80 番ポートに転送する指定を行っています。

[armadillo ~]# podman run -itd --name=apache_example --publish=8080:80 docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it apache_example /bin/sh
[container ~]# apk update && apk upgrade && apk add apache2
[container ~]# httpd
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.2. Set the 'ServerName' directive globally to suppress this message

図9.69 コンテナに Apache をインストールする例


他の PC などの Web ブラウザから、ホスト OS の IP アドレスの 8080 番ポートに接続すると、 動作確認用ページが表示されます。 デフォルトでは、/var/www/localhost/htdocs ディレクトリにファイルを置くことで Web ブラウザから閲覧できます。 Apache の詳細な設定は、/etc/apache2 ディレクトリにある設定ファイルを編集することで変更可能です。

  • lighttpd を使用する

alpine イメージからコンテナを作成し、そのコンテナ内に lighttpd をインストールします。 コンテナ作成の際に、ホスト OS の 8080 番ポートをコンテナ内の 80 番ポートに転送する指定を行っています。

[armadillo ~]# podman run -itd --name=lighttpd_example --publish=8080:80 docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it lighttpd_example /bin/sh
[container ~]# apk update && apk upgrade && apk add lighttpd
[container ~]# echo "<html><body>It works!</body></html>" > /var/www/localhost/htdocs/index.html
[container ~]# lighttpd -f /etc/lighttpd/lighttpd.conf

図9.70 コンテナに lighttpd をインストールする例


lighttpd はデフォルトでは動作確認用ページが用意されていないため、上記の手順では簡単なページを /var/www/localhost/htdocs ディレクトリの下に配置しています。 他の PC などの Web ブラウザから、ホスト OS の IP アドレスの 8080 番ポートに接続すると表示されます。 lighttpd の詳細な設定は、/etc/lighttpd ディレクトリにある設定ファイルを編集することで変更可能です。

9.1.7.2. FTP サーバを構築する

ここでは、FTP サーバとして vsftp を使用する場合について説明します。 alpine イメージからコンテナを作成し、そのコンテナ内に vsftpd をインストールします。 コンテナ作成の際に、FTP 通信で使用するポートについてホスト OS 側からコンテナ内のポートに転送する指定と、 コンテナ内の環境変数として PASV_ADDRESS にホスト OS 側の IP アドレスの指定を行っています。

[armadillo ~]# podman run -itd --name=ftp_example --publish=21:21 --publish=21100-21110:21100-21110 --env=PASV_ADDRESS=<ホストの IP アドレス> docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it ftp_example /bin/sh
[container ~]# apk update && apk upgrade && apk add vsftpd

図9.71 コンテナに vsftpd をインストールする例


コンテナ内にユーザアカウントを作成し、このユーザで ftp ログインできるようにします。

[container ~]# adduser atmark
Changing password for atmark
New password: (パスワードを入力)
Retype password: (パスワードを入力)
passwd: password for atmark changed by root

図9.72 ユーザを追加する例


作成したユーザで ftp ログインできるように、vsftpd の設定ファイルを編集します。

[container ~]# sed -i -e 's/anonymous_enable=YES/#anonymous_enable=YES/g' /etc/vsftpd/vsftpd.conf
[container ~]# sed -i -e 's/#local_enable=YES/local_enable=YES/g' /etc/vsftpd/vsftpd.conf
[container ~]# sed -i -e 's/#write_enable=YES/write_enable=YES/g' /etc/vsftpd/vsftpd.conf
[container ~]# echo "pasv_enable=YES" >> /etc/vsftpd/vsftpd.conf
[container ~]# echo "pasv_min_port=21100" >> /etc/vsftpd/vsftpd.conf
[container ~]# echo "pasv_max_port=21110" >> /etc/vsftpd/vsftpd.conf
[container ~]# echo "pasv_address=$PASV_ADDRESS" >> /etc/vsftpd/vsftpd.conf

図9.73 設定ファイルの編集例


編集した設定ファイルを指定して vftpd を起動することにより、ftp 接続可能となります。 ftp ログイン時のアカウントは前述の手順で作成したものを使用します。

[container ~]# vsftpd /etc/vsftpd/vsftpd.conf

図9.74 vsftpd の起動例


9.1.7.3. Samba サーバを構築する

ここでは、Samba サーバの構築方法について説明します。 alpine イメージからコンテナを作成し、そのコンテナ内に samba をインストールします。 コンテナ作成の際に、samba で使用するポートについてホスト OS 側からコンテナ内のポートに転送する指定を行っています。

[armadillo ~]# podman run -itd --name=smb_example --publish=139:139 --publish=445:445 docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it smb_example /bin/sh
[container ~]# apk update && apk upgrade && apk add samba

図9.75 コンテナに samba をインストールする例


コンテナ内にユーザアカウントを作成し、このユーザで samba にログインできるようにします。

[container ~]# adduser atmark
Changing password for atmark
New password: (パスワードを入力)
Retype password: (パスワードを入力)
passwd: password for atmark changed by root
[container ~]# pdbedit -a atmark
new password: (パスワードを入力)
retype new password: (パスワードを入力)

図9.76 ユーザを追加する例


samba を起動すると、前述の手順で作成したユーザアカウントで他の PC などからログインすることができます。

[container ~]# smbd

図9.77 samba の起動例


共有するディレクトリの指定などの詳細設定は /etc/samba/smb.conf ファイルを編集することで変更可能です。

9.1.7.4. SQL サーバを構築する

ここでは、RDMS として sqlite を使用する場合について説明します。 alpine イメージからコンテナを作成し、そのコンテナ内に sqlite をインストールします。

[armadillo ~]# podman run -itd --name=sqlite_example docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it sqlite_example /bin/sh
[container ~]# apk update && apk upgrade && apk add sqlite

図9.78 コンテナに sqlite をインストールする例


コンテナ内に入り、sqlite3 コマンドを実行すると sqlite のプロンプトが表示され データベースの操作ができるようになります。

[container ~]# sqlite3 mydb.sqlite
SQLite version 3.34.1 2021-01-20 14:10:07
Enter ".help" for usage hints.
sqlite>

図9.79 sqlite の実行例


9.1.8. セキュリティ

この章では、コンテナ内におけるセキュリティの確保の方法について示します。

9.1.8.1. iptables コマンドを使用する

コンテナ内から、iptables コマンドを使用してパケットフィルタリングを行うためには、 コンテナを作成する際に、権限として NET_ADMIN と NET_RAW を渡す必要があります。 以下は、権限を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=iptables_example --cap-add=NET_ADMIN --cap-add=NET_RAW docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it iptables_example /bin/sh
[container ~]# apk update && apk upgrade && apk add iptables

図9.80 iptables を使用するためのコンテナ作成例


以下に、iptables を使用した例を示します。

[container ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
[container ~]# iptables -I INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
[container ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http-alt

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

図9.81 iptables の動作確認例


9.1.9. 画面表示を行う

この章では、コンテナ内で動作するアプリケーションから Armadillo-IoT ゲートウェイ G4 に接続されたディスプレイに 出力を行う方法について示します。

9.1.9.1. Wayland を扱う

コンテナ内から、Wayland のコンポジタである weston を起動し画面表示を行う例を示します。 ここではアットマークテクノが提供するイメージからコンテナを作成します。 このイメージに関しては 「アットマークテクノが提供するイメージを使う」 を参照してください。 また、「VPU や NPU を使用する」 を実施済みであるとします。

[armadillo ~]# podman run -itd --name=wayland_example \
--env=XDG_RUNTIME_DIR=/tmp \ 1
--device=/dev/dri \ 2
--device=/dev/galcore \ 3
--device=/dev/input \ 4
--device=/dev/tty1 \ 5
--volume=/run/udev:/run/udev:ro \ 6
--volume=/opt/firmware:/opt/firmware:ro \ 7
--cap-add=SYS_TTY_CONFIG \ 8
localhost/at-debian-image:latest /bin/bash

図9.82 Wayland を扱うためのコンテナ作成例


1

weston の実行に必要な環境変数を設定します。

2

画面描画に必要なデバイスを設定します。

3

画面描画に必要なデバイスを設定します。

4

キーボードやマウスなどを使用可能にするためのデバイスを設定します。

5

weston に必要な tty を設定します。

6

ホスト OS 側の /run/udev をコンテナ内からマウントするように設定します。

7

ホスト OS 側の /opt/firmware をコンテナ内からマウントするように設定します。

8

tty を操作するための権限を設定します。

次に、以下のように weston を起動します。オプションである --tty に設定する値は、 コンテナ作成時に渡した tty の数字にします。

[armadillo ~]# podman attach wayland_example
[container ~]# weston --tty=1
Date: 2021-11-21 UTC
[23:46:52.823] weston 9.0.0
               https://wayland.freedesktop.org
               Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
               Build: lf-5.10.35-2.0.0-rc2-0-g230e9bc+
[23:46:52.825] Command line: weston --tty=1
[23:46:52.825] OS: Linux, 5.10.52-1-at, #2-Alpine SMP PREEMPT Thu Nov 18 09:10:13 UTC 2021, aarch64
[23:46:52.826] Using config file '/etc/xdg/weston/weston.ini'
[23:46:52.829] Output repaint window is 16 ms maximum.
[23:46:52.831] Loading module '/usr/lib/aarch64-linux-gnu/libweston-9/drm-backend.so'
[23:46:52.897] initializing drm backend
[23:46:52.897] logind: not running in a systemd session
[23:46:52.897] logind: cannot setup systemd-logind helper (-2), using legacy fallback
[23:46:52.902] using /dev/dri/card1
[23:46:52.902] DRM: supports atomic modesetting
[23:46:52.902] DRM: does not support GBM modifiers
[23:46:52.902] DRM: supports picture aspect ratio
[23:46:52.903] Loading module '/usr/lib/aarch64-linux-gnu/libweston-9/g2d-renderer.so'
[23:46:52.982] event1  - gpio-keys: is tagged by udev as: Keyboard
[23:46:52.983] event1  - gpio-keys: device is a keyboard
[23:46:52.986] event0  - audio-hdmi HDMI Jack: is tagged by udev as: Switch
[23:46:53.027] event0  - not using input device '/dev/input/event0'
[23:46:53.066] libinput: configuring device "gpio-keys".
[23:46:53.067] DRM: head 'LVDS-1' found, connector 39 is connected, EDID make 'unknown', model 'unknown', serial 'unknown'
[23:46:53.067] DRM: head 'HDMI-A-1' found, connector 40 is disconnected.
[23:46:53.067] Registered plugin API 'weston_drm_output_api_v1' of size 24
[23:46:53.067] Compositor capabilities:
               arbitrary surface rotation: yes
               screen capture uses y-flip: yes
               presentation clock: CLOCK_MONOTONIC, id 1
               presentation clock resolution: 0.000000001 s
[23:46:53.070] Loading module '/usr/lib/aarch64-linux-gnu/weston/desktop-shell.so'
[23:46:53.073] launching '/usr/libexec/weston-keyboard'
[23:46:53.079] Loading module '/usr/lib/aarch64-linux-gnu/libweston-9/xwayland.so'
[23:46:53.210] Registered plugin API 'weston_xwayland_v1' of size 32
[23:46:53.210] Registered plugin API 'weston_xwayland_surface_v1' of size 16
[23:46:53.210] xserver listening on display :0
[23:46:53.211] launching '/usr/libexec/weston-desktop-shell'

図9.83 コンテナ内で weston を起動する実行例


Armadillo-IoT ゲートウェイ G4 に接続しているディスプレイ上に、デスクトップ画面が表示されます。

  • weston の設定

アットマークテクノが提供するイメージでは、weston の設定ファイルは /etc/xdg/weston/weston.ini に配置してあります。

[container ~]# cat /etc/xdg/weston/weston.ini
[core]
idle-time=0
use-g2d=1
xwayland=true
repaint-window=16

[shell]
panel-position=none

[output]
name=HDMI-A-1
mode=1920x1080 1

[output]
name=LVDS-1
mode=off

図9.84 weston.ini


1

この行でHDMIモニタに出力する画像の解像度指定を行うことができます。初期値は1920x1080です。

[ティップ]

weston.ini で解像度を指定しない場合や、指定した解像度にモニタが対応していない場合は、モニタが対応している別な解像度に自動的に切り替わります。 その場合、意図しない解像度で描画されることがあります。 GUIアプリケーションの描画の乱れにつながる場合がありますので、予め使用するモニタに合わせて解像度を指定しておくことをお勧めします。

[ティップ]

設定ファイルを更新するにはコンテナイメージを新しく保存することもできますが、 ボリュームを使ってこのファイルだけを更新することができます。

podman run --volume/etc/atmark/containers/*.confvolumes 変数で設定してください。

  • weston の運用

コンテナの管理として、一つのコンテナで一つのアプリケーションを動かす事を推奨します。

一つのコンテナでwestonを起動して、 XDG_RUNTIME_DIRを共有することで別のコンテナでwestonを使用する アプリケーションを起動させることは以下のコンフィグで可能です。

[armadillo ~]# vi /etc/atmark/containers/weston.conf 1
set_image localhost/at-debian-image:latest
add_devices /dev/dri /dev/galcore /dev/input /dev/tty1
add_volumes /run/udev:/run/udev:ro /opt/firmware:/opt/firmware:ro
add_volumes /tmp/xdg_home:/run/xdg_home
add_args --env=XDG_RUNTIME_DIR=/run/xdg_home 2
add_args --cap-add=SYS_TTY_CONFIG
set_command weston --tty 1
[armadillo ~]# vi /etc/atmark/containers/detect_object.conf 3
set_image localhost/at-debian-image:latest
add_devices /dev/galcore /dev/video3
add_volumes /opt/firmware:/opt/firmware:ro /tmp/xdg_home:/run/xdg_home
set_restart always 4
add_args --env=XDG_RUNTIME_DIR=/run/xdg_home
set_command /root/start_detect_object.sh
[armadillo ~]# podman_start weston 5
[armadillo ~]# podman_start detect_object 6

1

westonの設定ファイルを作成します。

2

XDG_RUNTIME_DIR を volume で共有して、同じディレクトリを使います。

3

例としてdetect_objectという名前のクライアントの設定ファイルを作成します。ここでは任意の名前を設定できます。

4

アプリケーションによっては、westonが異常終了した時にエラーを出力しない場合があるため、set_restart always にします。

5 6

確認のためコンテナを手動で起動します。

  • ユーザを指定して weston を起動する

アットマークテクノが提供するイメージ at-debian-image にはデフォルトで atmark ユーザが存在しています。 at-weston-launch コマンドを使うと、 root ユーザではなく atmark ユーザで weston を起動することができます。

[armadillo ~]# vi /etc/atmark/containers/weston.conf 1
set_image localhost/at-debian-image:latest
add_devices /dev/dri /dev/galcore /dev/input /dev/tty7 2
add_volumes /run/udev:/run/udev:ro /opt/firmware:/opt/firmware:ro
add_volumes /tmp/xdg_home:/run/xdg_home
add_args --env=XDG_RUNTIME_DIR=/run/xdg_home
add_args --cap-add=SYS_TTY_CONFIG
set_command at-weston-launch --tty /dev/tty7 --user atmark 3
[armadillo ~]# podman_start weston 4

1

westonの設定ファイルを作成します。

2

使用する tty として /dev/tty7 を追加します。

3

at-weston-launch コマンドのオプションとして使用する tty とユーザ名を渡します。

4

確認のためコンテナを手動で起動します。

--tty と --user を指定しなかった場合は、デフォルトで /dev/tty7 と atmark ユーザが使われます。

  • スクリーンショットを保存する

weston を起動する際に、--debug オプションを渡すと weston-screenshooter コマンドでスクリーンショットを 保存することができます。

[armadillo ~]# vi /etc/atmark/containers/weston.conf 1
set_image localhost/at-debian-image:latest
add_devices /dev/dri /dev/galcore /dev/input /dev/tty1
add_volumes /run/udev:/run/udev:ro /opt/firmware:/opt/firmware:ro
add_volumes /tmp/xdg_home:/run/xdg_home
add_args --env=XDG_RUNTIME_DIR=/run/xdg_home
add_args --cap-add=SYS_TTY_CONFIG
set_command weston --tty 1 --debug 2
[armadillo ~]# podman_start weston 3
[armadillo ~]# podman exec -it weston /bin/bash 4
[container ~]# weston-screenshooter 5
[container ~]# ls
wayland-screenshot-[date].png 6

1

westonの設定ファイルを作成します。

2

--debug オプションを渡します。

3

確認のためコンテナを手動で起動します。

4

起動した weston コンテナ内で /bin/bash を起動してログインします。

5

weston-screenshooter コマンドを実行します。

6

カレントディレクトリ内に wayland-screenshot-[date].png というファイル名で保存されます。

[警告]

--debug オプションは開発時にのみ使用してください。正式運用時の使用は非推奨です。

[ティップ]

Armadillo-IoT ゲートウェイ G4 にキーボードを接続している場合は、--debug オプションを渡さなくても Windows キー + s を押下することによりスクリーンショットを保存することができます。 この場合、スクリーンショットはコンテナ内の /proc/[weston の PID]/cwd 下に保存されます。

9.1.9.2. X Window System を扱う

コンテナ内から、X Window System を起動し画面表示を行う例を示します。 ここではアットマークテクノが提供するイメージからコンテナを作成します。 このイメージに関しては 「アットマークテクノが提供するイメージを使う」 を参照してください。 また、「VPU や NPU を使用する」 を実施済みであるとします。

[armadillo ~]# podman run -itd --name=x_example \
--device=/dev/tty7 \ 1
--device=/dev/fb0 \ 2
--device=/dev/input \ 3
--volume=/run/udev:/run/udev:ro \ 4
--cap-add=SYS_ADMIN \ 5
localhost/at-debian-image:latest /bin/bash

図9.85 X Window System を扱うためのコンテナ起動例


1

X Window System に必要な tty を設定します。どこからも使われていない tty とします。

2

画面描画先となるフレームバッファを設定します。

3

キーボードやマウスなどを使用可能にするためのデバイスを設定します。

4

ホスト OS 側の /run/udev をコンテナ内からマウントするように設定します。

5

X Window System の動作に必要な権限を設定します。

次に、以下のように X Window System を起動します。 オプションである vt に設定する値は、コンテナ作成時に渡した tty の数字にします。

[armadillo ~]# podman attach x_example
[container ~]# apt install xorg
[container ~]# X vt7 -retro

X.Org X Server 1.20.11
X Protocol Version 11, Revision 0
Build Operating System: linux Debian
Current Operating System: Linux 25297ceb226c 5.10.52-1-at #2-Alpine SMP PREEMPT Thu Nov 18 09:10:13 UTC 2021 aarch64
Kernel command line: console=ttymxc1,115200 root=/dev/mmcblk2p1 rootwait ro
Build Date: 13 April 2021  04:07:31PM
xorg-server 2:1.20.11-1 (https://www.debian.org/support)
Current version of pixman: 0.40.0
        Before reporting problems, check http://wiki.x.org
        to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
        (++) from command line, (!!) notice, (II) informational,
        (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/Xorg.0.log", Time: Sun Nov 21 23:51:18 2021
(==) Using system config directory "/usr/share/X11/xorg.conf.d"

図9.86 コンテナ内で X Window System を起動する実行例


Armadillo-IoT ゲートウェイ G4 に接続しているディスプレイ上に、デスクトップ画面が表示されます。

9.1.9.3. フレームバッファに直接描画する

コンテナ内で動作するアプリケーションからフレームバッファに直接描画するためには、Podman のイメージからコンテナを作成する際にホスト OS 側の デバイスファイル /dev/fbN を渡す必要があります。以下は、/dev/fb0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=fb_example --device=/dev/fb0 docker.io/alpine /bin/sh

図9.87 フレームバッファに直接描画するためのコンテナ作成例


コンテナ内に入って、ランダムデータをフレームバッファに描画する例を以下に示します。 これにより、接続しているディスプレイ上の表示が変化します。

[armadillo ~]# podman exec -it fb_example /bin/sh
[container ~]# cat /dev/urandom > /dev/fb0
cat: write error: No space left on device

図9.88 フレームバッファに直接描画する実行例


9.1.9.4. タッチパネルを扱う

タッチパネルが組み込まれているディスプレイを接続している環境で、 コンテナ内からタッチイベントを取得するためには、Podman のイメージからコンテナを作成する際に ホスト OS 側の /dev/input を渡す必要があります。

[armadillo ~]# podman run -itd --name=touch_example --device=/dev/input docker.io/alpine /bin/sh

図9.89 タッチパネルを扱うためのコンテナ作成例


Wayland などの GUI 環境と組み合わせて使うことで、タッチパネルを利用した GUI アプリケーションの操作が可能となります。

9.1.9.5. VPU を扱う

Armadillo-IoT ゲートウェイ G4 で採用している i.MX 8M Plus には、動画のエンコード/デコード処理に特化した演算ユニットである VPU (Video Processing Unit) が搭載されています。 VPU を活用することでシステム全体のパフォーマンスを落とすことなく、動画のエンコード/デコード処理を行うことができます。 コンテナ内で動作するアプリケーションから VPU を扱うためには、コンテナ作成時にデバイスとして、 /dev/mxc_hantro と /dev/mxc_hantro_vc8000e および /dev/ion を渡す必要があります。 ここではアットマークテクノが提供するイメージからコンテナを作成します。 このイメージに関しては 「アットマークテクノが提供するイメージを使う」 を参照してください。 また、「VPU や NPU を使用する」 を実施済みであるとします。

[armadillo ~]# podman run -itd --name=vpu_example \
--device=/dev/mxc_hantro \
--device=/dev/mxc_hantro_vc8000e \
--device=/dev/ion \
localhost/at-debian-image:latest /bin/bash
[armadillo ~]# podman exec -it vpu_example /bin/bash
[container ~]# ls /dev/mxc_hantro /dev/mxc_hantro_vc8000e /dev/ion
/dev/ion  /dev/mxc_hantro  /dev/mxc_hantro_vc8000e

図9.90 VPU を扱うためのコンテナ作成例


weston と GStreamer がインストール済みのイメージと組み合わせて使うことで、 VPU を使用して動画のエンコード/デコードを行うことができます。

[armadillo ~]# podman run -itd --name=gst_example \
--env=XDG_RUNTIME_DIR=/tmp \
--device=/dev/dri \
--device=/dev/galcore \
--device=/dev/mxc_hantro \
--device=/dev/mxc_hantro_vc8000e \
--device=/dev/ion \
--device=/dev/input \
--device=/dev/tty1 \
--device=/dev/video3 \
--volume=/run/udev:/run/udev:ro \
--volume=/opt/firmware:/opt/firmware:ro \
--cap-add=SYS_TTY_CONFIG \
localhost/at-debian-image:latest /bin/bash

図9.91 weston と GStreamer を扱うためのコンテナ作成例


このようにして作成したコンテナにログインすると、 GStreamer で VPU を使用した動画のエンコード/デコードが行なえます。

[armadillo ~]# podman attach gst_example
[container ~]# apt install gstreamer1.0-imx libgstreamer-imx gstreamer1.0-plugins-bad \
libgstreamer-plugins-bad1.0-0 gstreamer1.0-plugins-base libgstreamer-plugins-base1.0-0 \
gstreamer1.0-plugins-good libgstreamer1.0-0 gstreamer1.0-tools gstreamer1.0-imx-tools
[container ~]# weston --tty=1 &
[container ~]# gst-launch-1.0 filesrc location=<ファイル名> ! qtdemux ! h264parse ! vpudec ! queue ! waylandsink

図9.92 GStreamer によるデコード実行例


USB カメラも組み合わせると、カメラからの映像をエンコードしてファイルに保存することも可能です。

[container ~]# gst-launch-1.0 -e v4l2src device=/dev/video3 ! video/x-raw,width=640,height=480,framerate=30/1 ! queue ! vpuenc_h264 ! h264parse ! queue ! qtmux ! filesink location=./output.mp4

図9.93 GStreamer によるエンコード実行例


上記を実行することで、USB カメラからの映像が H.264 にエンコードされてファイルに保存されます。この例ではカメラデバイスを /dev/video3 としていますが、 環境によって異なりますので適切なものを設定してください。

9.1.10. パワーマネジメント機能を使う

この章では、コンテナ内からパワーマネジメント機能を使う方法について示します。

9.1.10.1. サスペンド状態にする

パワーマネジメント機能を使ってサスペンド状態にするには、Podman のイメージからコンテナを作成する際に ホスト OS 側の /sys ディレクトリを渡す必要があります。 以下は、/sys を渡して alpine イメージからコンテナを作成する例です。ここで渡された /sys ディレクトリは コンテナ内の /sys にマウントされます。

[armadillo ~]# podman run -itd --name=pm_example --volume=/sys:/sys docker.io/alpine /bin/sh

図9.94 パワーマネジメント機能を使うためのコンテナ作成例


コンテナ内から、/sys/power/state に次の文字列を書き込むことにより、サスペンド状態にすることができます。

表9.1 対応するパワーマネジメント状態

パワーマネジメント状態 文字列 説明

Suspend-to-RAM

mem

最も消費電力を抑えることができる

Suspend-to-Idle

freeze

最も短時間で復帰することができる


[armadillo ~]# podman run -itd --name=pm_example --volume=/sys:/sys docker.io/alpine /bin/sh
[armadillo ~]# podman exec -it pm_example /bin/sh
[container ~]# echo mem > /sys/power/state

図9.95 サスペンド状態にする実行例


9.1.10.2. 起床要因を有効化する

サスペンド状態から起床要因として、利用可能なデバイスを以下に示します。

UART2 (console)
起床要因
データ受信
有効化
[container ~]# echo enabled > /sys/bus/platform/drivers/imx-uart/30890000.serial/tty/ttymxc1/power/wakeup
USB
起床要因
USBデバイスの挿抜
有効化
[container ~]# echo enabled > /sys/bus/platform/devices/32f10108.usb/power/wakeup
RTC(i.MX8MP)
起床要因
アラーム割り込み
実行例
[armadillo ~]# podman run -v /sys:/sys --device /dev/rtc0 -ti docker.io/alpine sh
[container ~]# apk add util-linux
[container ~]# rtcwake -m mem -s 5
: (省略)
[  572.720300] printk: Suspending console(s) (use no_console_suspend to debug)
<ここで5秒を待つ>
[  573.010663] Disabling non-boot CPUs ...
...

図9.96 サスペンド状態にする実行例、rtcで起こす


ユーザースイッチ
起床要因
ユーザースイッチ押下
有効化
[armadillo ~]# vi /boot/overlays.txt 1
fdt_overlays=armadillo_iotg_g4-sw1-wakeup.dtbo

[armadillo ~]# persist_file -vp /boot/overlays.txt 2
'/boot/overlays.txt' -> '/mnt/boot/overlays.txt'
Added "/boot/overlays.txt" to /etc/swupdate_preserve_files

[armadillo ~]# reboot 3
: (省略)
Applying fdt overlay: armadillo_iotg_g4-sw1-wakeup.dtbo 4
: (省略)

[armadillo ~]# cat /sys/devices/platform/gpio-keys/power/wakeup 5
enabled

1

/boot/overlays.txt ファイルに「armadillo_iotg_g4-sw1-wakeup.dtbo」を追加します。 ファイルが存在しない場合は新規に作成してください。 このファイルの詳細については 「DTS overlays によるカスタマイズ」 を参照してください。

2

/boot/overlays.txt を保存し、アップデートの場合でも保存します。

3

overlay の実行のために再起動します。

4

シリアルコンソールの場合に、u-bootによるメッセージを確認できます。

5

Linux からも確認できます。

SMS 受信(LTE モデルのみ)
起床要因
SMS 受信

9.1.11. コンテナからのpoweroffかreboot

Armadillo Base OSはbusybox initでshutdownとrebootを対応します。

busybox initでPID 1にsignalを送ることでshutdownやrebootとなります。 コンテナからsignalを送るように、pid namespaceを共有する必要がありますが、共有されたらkillで実行できます。

[armadillo ~]# podman run --pid=host -ti docker.io/alpine sh
[container ~]# kill -USR2 1  (poweroff)
[container ~]# kill -TERM 1  (reboot)

図9.97 コンテナからshutdownを行う


9.1.12. 異常検知

この章では、コンテナ内で動作しているアプリケーションに何らかの異常が発生し停止してしまった際に、 ソフトウェアウォッチドックタイマーを使って、システムを再起動する方法について示します。

9.1.12.1. ソフトウェアウォッチドッグタイマーを扱う

コンテナ内で動作するアプリケーションからソフトウェアウォッチドックタイマーを扱うためには、Podman のイメージからコンテナを作成する際にホスト OS 側の デバイスファイル /dev/watchdogN を渡す必要があります。以下は、/dev/watchdog0 を渡して alpine イメージからコンテナを作成する例です。

[armadillo ~]# podman run -itd --name=watchdog_example --device=/dev/watchdog0 docker.io/alpine /bin/sh

図9.98 ソフトフェアウォッチドッグタイマーを使うためのコンテナ作成例


ソフトウェアウォッチドックタイマーは、プログラム内からデバイスファイル /dev/watchdog0 を open した時点で起動します。 コンテナ内に入ってソフトウェアウォッチドックタイマーを echo コマンドで起動する例を以下に示します。

[armadillo ~]# podman exec -it watchdog_example /bin/sh
[container ~]# echo > /dev/watchdog0

図9.99 コンテナ内からソフトウェアウォッチドッグタイマーを起動する実行例


ソフトウェアウォッチドックタイマーを起動した後、/dev/watchdog0 に任意の文字を書き込むことで ソフトウェアウォッチドッグタイマーをリセットすることができます。 60 秒間任意の文字の書き込みがない場合は、システムが再起動します。

[armadillo ~]# podman exec -it watchdog_example /bin/sh
[container ~]# echo a > /dev/watchdog0

図9.100 ソフトウェアウォッチドッグタイマーをリセットする実行例


ソフトウェアウォッチドックタイマーを停止したい場合は、/dev/watchdog0 に V を書き込みます。

[armadillo ~]# podman exec -it watchdog_example /bin/sh
[container ~]# echo V > /dev/watchdog0

図9.101 ソフトウェアウォッチドッグタイマーを停止する実行例


9.1.13. NPU を扱う

Armadillo-IoT ゲートウェイ G4 で採用している i.MX 8M Plus には、機械学習に特化した演算処理ユニットである NPU (Neural Processor Unit) が搭載されています。 NPU を活用することで、顔認識や物体認識などの推論処理を高速に行うことができます。

コンテナ内で動作するアプリケーションから NPU を扱うためには、 アットマークテクノが提供するコンテナイメージである at-debian-image を使用する必要があります。また、コンテナ作成時にデバイスとして、/dev/galcore を渡す必要があります。 以下は、/dev/galcore を渡して at-debian-image からコンテナを作成する例です。 このイメージに関しては 「アットマークテクノが提供するイメージを使う」 を参照してください。

[armadillo ~]# podman run -itd --name=npu_example \
--volume=/opt/firmware:/opt/firmware \
--device=/dev/galcore \
localhost/at-debian-image:latest /bin/sh
[armadillo ~]# podman exec -it npu_example /bin/sh
[container ~]# ls /dev/galcore
/dev/galcore

図9.102 NPU を扱うためのコンテナ作成例


[注記]

i.MX 8M Plus に搭載されている NPU は INT8 で量子化された学習済みモデルを高速に推論するように設計されています。 INT8 で量子化されていないモデルの場合、正常に推論できない、または推論実行速度の低下が発生する場合があります。

具体的な機械学習アプリケーションの開発方法については、NXP Semiconductors の公式サイトを参照してください。

アットマークテクノからも機械学習に関する開発ガイドを公開していますので、そちらも参照してください。 Armadillo Base OS 開発ガイド

9.1.13.1. ONNX Runtime を使う

ONNX Runtime は 学習済みの ONNX モデルを使って推論を行うためのソフトウェアです。[7] Armadillo-IoT ゲートウェイ G4 では、NPU を使って ONNX Runtime を実行することができます。

  • ONNX Runtime をインストールする

at-debian-image から作成したコンテナであれば、apt install でインストールすることができます。

[armadillo ~]# podman run -it --name=onnxruntime_example \
--volume=/opt/firmware:/opt/firmware \
--device=/dev/galcore \
localhost/at-debian-image:latest /bin/bash
[container ~]# apt install onnxruntime onnxruntime-dev onnxruntime-tools python3-onnxruntime

図9.103 ONNX Runtime をインストールする例


  • python から ONNX Runtime を使う

python から ONNX Runtime を使うためには onnxruntime モジュールを import します。 また、NPU を使うために InferenceSession オブジェクトを作成する際に、Providers として 「VsiNpuExecutionProvider」を指定します。

[container ~]# python3
>>> import onnxruntime
: (省略)
>>> sess = onnxruntime.InferenceSession('model.onnx', providers=['VsiNpuExecutionProvider'])

図9.104 python から ONNX Runtime を使う例


以上により、python から ONNX Runtime を使うことができます。

9.1.13.2. TensorFlow Lite を使う

TensorFlow Lite からも NPU を使って高速に推論を行うことができます。

  • TensorFlow Lite をインストールする

at-debian-image から作成したコンテナであれば、apt install でインストールすることができます。

[armadillo ~]# podman run -it --name=tflite_example \
--volume=/opt/firmware:/opt/firmware \
--device=/dev/galcore \
localhost/at-debian-image:latest /bin/bash
[container ~]# apt install tensorflow-lite tensorflow-lite-dev python3-tflite-runtime \
tim-vx tensorflow-lite-vx-delegate

図9.105 TensorFlow Lite をインストールする例


  • python から TensorFlow Lite を使う

python から TensorFlow Lite を使うためには Interpreter モジュールを import します。 python から TensorFlow Lite を使う場合は特別な設定をしなくても、自動的に NPU が使われます。

[container ~]# python3
>>> from tflite_runtime.interpreter import Interpreter
: (省略)
>>> interpreter = Interpreter('model.tflite')

図9.106 python から TensorFlow Lite を使う例


以上により、python から TensorFlow Lite を使うことができます。

[警告]

tflite-runtime パッケージと、ライブラリイメージ(imx_lib)のバージョンの組み合わせによっては、使用する delegate と ライブラリの整合性が取れずに TensorFlow Liteを用いたアプリケーションが正しく動作しない場合があります。

バージョン 2.6.0-1 以降の tflite-runtime パッケージを使用する際には、必ずバージョン 2.2.0 以降のライブラリイメージ(imx_lib)を使用してください。

ライブラリイメージのアップデート方法については「VPU や NPU を使用する」を参照してください。

それぞれのバージョンと動作の関係を表9.2「ライブラリと tflite-runtime のバージョンと NPU を用いたアプリケーションの動作の関係」に示します。

表9.2 ライブラリと tflite-runtime のバージョンと NPU を用いたアプリケーションの動作の関係

                   tflite-runtime のバージョンが 2.6.0-1 以降 tflite-runtime のバージョンが 2.6.0-1 未満

ライブラリのバージョンが確認できる(2.2.0 以降)

VX delegateで動作

NNAPI delegate で動作

ライブラリのバージョンが確認できない(2.2.0 未満)

正しく動作しない場合あり

NNAPI delegate で動作


ライブラリのバージョン確認手順については、「ライブラリイメージのバージョンを確認する」を参照してください。

tflite-runtime パッケージのバージョンは、コンテナ内で以下のコマンドを実行することで確認できます。

[container ~]# dpkg -l python3-tflite-runtime
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                   Version      Architecture Description
+++-======================-============-============-===============================================
ii  python3-tflite-runtime 2.6.0-1      arm64        deep learning framework for on-device inference

図9.107 tflite-runtime のバージョンを確認する


推奨はしませんが、 tflite-runtime のバージョンを 2.6.0-1 未満に下げたい場合は表9.3「2.6.0-1 未満の TensorFlow Lite 関連 deb パッケージ」に示す deb パッケージを全てコンテナ内にダウンロードして、図9.108「tflite-runtime のバージョンを下げる」のコマンドを実行してください。


[container ~]# ls ./*.deb 1
python3-tflite-runtime_2.4.0-1_arm64.deb
python3-tflite-runtime-dbgsym_2.4.0-1_arm64.deb
tensorflow-lite_2.4.0-1_arm64.deb
tensorflow-lite-dev_2.4.0-1_arm64.deb
[container ~]# apt purge \
tensorflow-lite \
tensorflow-lite-dev \
tensorflow-lite-vx-delegate \
tensorflow-lite-vx-delegate-dev \
python3-tflite-runtime \
tim-vx \
tim-vx-dev 2
[container ~]# apt install ./*.deb 3

図9.108 tflite-runtime のバージョンを下げる


1

カレントディレクトリに表9.3「2.6.0-1 未満の TensorFlow Lite 関連 deb パッケージ」の deb パッケージのみ存在していることを確認します。

2

2.6.0-1 以上のインストールされているパッケージを削除します。

3

ダウンロードした deb パッケージをインストールします。

9.1.13.3. Arm NN を使う

Arm NN とは TensorFlow Lite および ONNX のモデル形式をサポートしている推論用ソフトウェアです。 Arm NN からも NPU を使って高速に推論を行うことができます。

  • Arm NN をインストールする

at-debian-image から作成したコンテナであれば、apt install でインストールすることができます。

[armadillo ~]# podman run -it --name=armnn_example \
--volume=/opt/firmware:/opt/firmware \
--device=/dev/galcore \
localhost/at-debian-image:latest /bin/bash
[container ~]# apt install libarmnn22 libarmnn-dev python3-pyarmnn armnn-examples

図9.109 Arm NN をインストールする例


  • python から Arm NN を使う

python から TensorFlow Lite を使うためには pyarmnn モジュールを import します。 また、NPU を使うために BackendId として「VsiNpu」を指定して、Optimize オブジェクトを作成します。

[container ~]# python3
>>> import pyarmnn as ann
: (省略)
>>> options = ann.CreationOptions()
>>> runtime = ann.IRuntime(options)
>>> parser = ann.ITfLiteParser()
>>> network = parser.CreateNetworkFromBinaryFile('model.tflite')
>>> preferred_backends = []
>>> preferred_backends.append(ann.BackendId('VsiNpu'))
>>> opt_network, _ = ann.Optimize(network, preferred_backends, runtime.GetDeviceSpec(), ann.OptimizerOptions())
>>> net_id, _ = runtime.LoadNetwork(opt_network)

図9.110 python から Arm NN を使う例


以上により、python から Arm NN を使うことができます。

9.2. コンテナの運用

9.2.1. コンテナの自動起動

Armadillo Base OSでは、/etc/atmark/containers/*.confファイルに指定されているコンテナがブート時に自動的に起動します。 nginx.confの記載例を以下に示します。

[armadillo ~]# cat /etc/atmark/containers/nginx.conf
set_image docker.io/library/nginx:alpine
set_readonly no
add_ports 80:80

図9.111 コンテナを自動起動するための設定例


.conf ファイルは以下のパラメータを設定できます。

  • コンテナイメージの選択: set_image [イメージ名]

    イメージの名前を設定できます。

    : set_image docker.io/debian:latest, set_image localhost/myimage

  • ポート転送: add_ports [ホストポート]:[コンテナポート]

    設定したポートで外部からコンテナへのアクセスが可能となります。

    デフォルトはTCPで、UDPも /udp を付けて使えます。スペースで分けて複数のポートを設定することができます。

    以下の例では、ポート80、443(web)、UDPの69(tftp)にアクセスすることができ、コンテナのポート22(ssh)にはポート2222からアクセスすることができます。

    : add_ports 80:80 443:443 2222:22 69:69/udp

    [警告]

    pod を使う場合、このオプションはpodの設定にしないと有効になりませんのでご注意ください。

  • デバイスファイル作成: add_devices [ホストパス]:[コンテナパス]

    コンテナでデバイスを作成して、使用可能となります。

    コンテナパスを設定しない場合はホストと同じパスを使います。

    複数のデバイスを作成したい場合はスペースで分けて設定してください。

    : add_devices /dev/galcore /dev/v4l/by-id/usb-046d_HD_Pro_Webcam_C920_78DA8CAF-video-index0:/dev/video3

    ホストパスに「:」を含む場合は add_device "[ホストパス]" "[コンテナパス]" で追加できます。

    : add_device "/dev/v4l/by-path/XXXXX" "/dev/video3"

    コンテナパスに「:」を含むようなパスは設定できません。

  • ボリュームマウント: add_volumes [ホストパス]:[コンテナパス]:[オプション]

    指定するパスをコンテナ内でマウントして、データの保存や共有することができます。

    ホストパスは以下のどちらかを指定してください。

    • /var/app/rollback/volumes/<folder><folder>:

      アップデートの際に新しくコピー(snapshot)した場合、コピー先のみ変更しますので、 アップデート中でもこのデータを使うことができます。 途中で電源が落ちた場合でも、このデータに影響はありません。

      SWUpdateでアップデートするデータに向いています。

    • /var/app/volumes/<folder>: appパーティションに書きます。

      アップデートの際にコピーされませんので、アップデート中の新たな変更は 更新されたコンテナ内のアプリケーションで見れます。

      ログやデータベースに向いています。

    • /tmp/<folder>: 複数のコンテナでメモリファイルシステムを共有したい場合に使ってください。
    • /opt/firmware: 学習能力に必要なファムウェアライブラリーのパス。

    コンテナパスを設定しない場合はホストパスと同じパスを使います。

    オプションは podman run--volume のオプションになりますので、 ro (read-only), nodev, nosuid, noexec, shared, slave 等を設定できます。

    *例*:add_volumes /var/app/volumes/database:/database: ロールバックされないデータを/databaseで保存します。

    : add_volumes assets:/assets:ro,nodev,nosuid /opt/firmware: アプリケーションのデータを/assetsで読み取り、/opt/firmwareのファームウェアを使えます。

    「:」はホスト側のパスとコンテナのパスを別ける意味があるため、ファイル名やデバイス名に「:」を使うことはできません。

    [ティップ]

    複数のコンテナでマウントコマンドを実行することがあれば、shared のフラグで起動後のマウントを共有することができます。

    [armadillo ~]# cat /etc/atmark/containers/mounter.conf
    set_image docker.io/alpine
    add_args -ti
    add_volumes /tmp/mnt:/mnt:shared 1
    add_args --cap-add SYS_ADMIN
    add_device /dev/sda1
    [armadillo ~]# cat /etc/atmark/containers/client.conf
    set_image docker.io/alpine
    add_volumes /tmp/mnt:/mnt:slave 2
    add_args -ti
    [armadillo ~]# podman exec mounter mount /dev/sda1 /mnt 3
    [armadillo ~]# podman exec client ls /mnt 4
    file_on_usb

    図9.112 ボリュームを shared でサブマウントを共有する例


    1

    マウントを行うコンテナに shared の設定とマウント権限 (SYS_ADMIN) を与えます。

    2

    マウントを使うコンテナに slave だけを設定すれば一方にしか共有されません。

    3

    USB デバイスをマウントします。

    4

    マウントされたことを確認します。

  • pod の選択: set_pod [ポッド名]

    「podの作成」で作成した pod の名前を入れてコンテナを pod 内で起動します。

    : set_pod mypod

  • ネットワークの選択: set_network [ネットワーク名]

    この設定に「networkの作成」で作成したネットワーク以外に nonehost の特殊な設定も選べます。

    none の場合、コンテナに localhost しかないネームスペースに入ります。

    host の場合はOSのネームスペースをそのまま使います。

    : set_network mynetwork

  • IP アドレスの設定: set_ip [アドレス]

    コンテナの IP アドレスを設定することができます。

    : set_ip 10.88.0.100

    [ティップ]

    コンテナ間の接続が目的であれば、podを使ってlocalhostかpodの名前でアクセスすることができます。

  • 読み取り専用設定: set_readonly yes

    コンテナ内からのファイルシステムへの書き込み許可を設定します。

    デフォルトで書き込み可能となっています。

    コンテナ内からのファイルシステムへの書き込みを禁止することで、 tmpfs として使うメモリの消費を明示的に抑えることができますが、 アプリケーションによっては読み込み専用のファイルシステムでは動作しない可能性もあります。

  • イメージの自動ダウンロード設定: set_pull [設定]

    この設定を missing にすると、イメージが見つからない場合にイメージを自動的にダウンロードします。

    always にすると、イメージがすでにダウンロード済みでも起動前に必ず更新の確認を取ります。

    デフォルトでは never で、イメージが見つからない場合にエラーを表示します。

    *例*:set_pull missingset_pull always

  • コンテナのリスタート設定: set_restart [設定]

    コンテナが停止した時にリスタートさせます。

    podman killpodman stop で停止する場合、この設定と関係なくリスタートしません。

    デフォルトで on-failure になっています。

    : set_restart alwaysset_restart no

  • 自動起動の無効化: set_autostart no

    手動かまたは別の手段で操作するコンテナがある場合、Armadillo の起動時に自動起動しないようにします。

    その場合、 podman_start <name> で起動させることができます。

    [ティップ]

    コンフィグに記載していないイメージはアップデートの際に削除されますので、そういったイメージに対して設定してください。

  • 実行コマンドの設定: set_command [コマンド]

    コンテナを起動するときのコマンド。設定されなかった場合、コンテナイメージのデフォルトを使います。

    : set_command /bin/sh -c "echo bad example"

  • podman run に引数を渡す設定: add_args [引数]

    ここまでで説明した設定項目以外の設定を行いたい場合は、この設定で podman run に直接引数を渡すことができます。

    *例*:add_args --cap-add=SYS_TTY_CONFIG --env=XDG_RUNTIME_DIR=/run/xdg_home

9.2.2. podの作成

podman_startpod 機能を使うことができます。

pod を使うことで、複数のコンテナが同じネットワークネームスペースを共有することができます。 同じ pod の中のコンテナが IP の場合 localhost で、 unix socket の場合 abstract path で相互に接続することができます。

[armadillo ~]# cat /etc/atmark/containers/mypod.conf
set_type pod
add_ports 80:80
set_infra_imager k8s.gcr.io/pause:3.5

[armadillo ~]# cat /etc/atmark/containers/nginx.conf
set_image docker.io/library/nginx:alpine
set_readonly no
set_pod mypod

armadillo:~# podman ps
CONTAINER ID  IMAGE                           COMMAND               CREATED      STATUS          PORTS               NAMES
0cdb0597b610  k8s.gcr.io/pause:3.5                                  2 hours ago  Up 2 hours ago  0.0.0.0:80->80/tcp  5ba7d996f673-infra
3292e5e714a2  docker.io/library/nginx:alpine  nginx -g daemon o...  2 hours ago  Up 2 hours ago  0.0.0.0:80->80/tcp  nginx

図9.113 podを使うコンテナを自動起動するための設定例


コンテナと同じく、 /etc/atmark/containers/[NAME].conf ファイルを作って、 set_type pod を設定することで pod を作成します。

pod を使う時にコンテナの設定ファイルに set_pod [NAME] の設定を追加します。

ネットワークネームスペースは pod を作成するときに必要なため、 ports, networkip の設定は pod のコンフィグファイルに入れなければなりません。

ネットワーク設定の他に、 infra_image のオプションで pod のイメージも固める事ができます。 この設定は set_type network の後しか使えませんので、set_type はファイルの最初のところに使ってください

必要であれば、他の podman pod create のオプションを add_args で設定することができます。

[警告]

pod を使う時に podman が特殊な「infra container」も起動します(例の場合、 k8s.gcr.io/pause:3.5 を起動させました)

コンフィグレーションに pod を入れるアップデートの際に自動的に podman pull でイメージをダウンロードしますが、 インターネットを使わせたくないアップデートがあれば swdesc_embed_containerswdesc_usb_container で入れてください。 その場合、 infra_image の設定も使ってください。

9.2.3. networkの作成

podman_start で podman の network も作成ことができます。

デフォルトの 10.88.0.0/16 が使えない場合、あるいはコンテナ同士で接続できないようにしたい場合は使ってください。

[armadillo ~]# cat /etc/atmark/containers/mynetwork.conf
set_type network
set_subnet 192.168.100.0/24

[armadillo ~]# cat /etc/atmark/containers/nginx.conf
set_image docker.io/library/nginx:alpine
set_ports 80:80
set_ip 192.168.100.10
set_network mynetwork

armadillo:~# podman ps
CONTAINER ID  IMAGE                           COMMAND               CREATED      STATUS          PORTS               NAMES
3292e5e714a2  docker.io/library/nginx:alpine  nginx -g daemon o...  2 hours ago  Up 2 hours ago  0.0.0.0:80->80/tcp  nginx

図9.114 networkを使うコンテナを自動起動するための設定例


コンテナと同じく、 /etc/atmark/containers/[NAME].conf ファイルを作って、 set_type network を設定することで network を作成します。

そのネットワークを使う時にコンテナの設定ファイルに set_network [NAME] の設定をいれます。

ネットワークのサブネットは set_subnet [SUBNET] で設定します。 この設定は set_type network の後しか使えませんので、set_type はファイルの最初のところに使ってください

他の podman network create のオプションが必要であれば、 add_args で設定することができます。

9.2.4. コンテナからのコンテナ管理

podman では REST API による管理アクセスも可能です。

自分のコンテナから他のコンテナの管理が必要な場合に、ホストの podman サービスを有効にして、 コンテナに /run/podman をボリュームマウントすれば podman --remote で管理できます。

podman_start をインストールすればそちらも --remote で使えます。

このオプションは Armadillo のホスト側の udev rules からコンテナを扱う時にも必要です。

9.2.5. コンテナの配布

[ティップ]

コンテナの作成は「アプリケーションをコンテナで実行する」を参考にしてください。

コンテナのイメージを配布する方法は大きく分けて二つあります:

  1. インターネット上のリポジトリ(dockerhub等)で登録してそこから配布する
  2. SWUpdateのアップデートイメージを配布する
[警告]

Podmanのイメージをインストールする時に、一時データを大量に保存する必要があります。

swuイメージ内で組み込む時は3倍、pullやUSBドライブで分けてインストールすると転送するデータ量の2倍の空き容量がappパーティションに必要です。

アップデート時にアップデート前のコンテナが使われているのでご注意ください。

9.2.5.1. リモートリポジトリにコンテナを送信する方法

  1. イメージをリモートリポジトリに送信する:

    [armadillo ~]$ podman image push <localimage> docker://<registry>/<remoteimage>:<tag>
  2. set_pull always を設定しないかぎり、SWUpdateでダウンロードの命令を送らないとアップデートを行いません。

    (mkswuについては「Armadilloのソフトウェアをアップデートする」を参考にしてください)

    [ATDE ~/mkswu]$ cp /usr/share/mkswu/examples/pull_container_nginx.desc .
    [ATDE ~/mkswu]$ cp -r /usr/share/mkswu/examples/nginx_start .
    [ATDE ~/mkswu]$ cat pull_container_nginx.desc
    swdesc_option version=1
    
    swdesc_pull_container "docker.io/nginx:alpine"
    swdesc_files --extra-os nginx_start
    [ATDE ~/mkswu]$ mkswu pull_container_nginx.desc
    Enter pass phrase for /home/atmark/mkswu/swupdate.key:
    pull_container_nginx.swu を作成しました。

9.2.5.2. イメージを eMMC に保存する方法

Armadillo Base OS のデフォルトでは、Podman のデータは tmpfs に保存されます。

起動時にイメージを起動するにはイメージを eMMC に書き込む必要があります。 想定の使い方では、以下の 「イメージを SWUpdate で転送する方法」 でコンテナのイメージを送信する場合には、 /var/lib/containers/storage_readonly の app パーティションのサブボリュームに展開します。

開発の時に、abos-ctrl podman-storage --disk を設定すると別の /var/log/containers/storage が作成されますが、SWUpdate で転送するイメージはそのまま readonly の方に書き込みます。

abos-ctrl podman-rw を使えば、read-only になっているイメージを扱う事ができます。

[armadillo ~]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED            SIZE        R/O
[armadillo ~]# mount /dev/sda1 /mnt
[armadillo ~]# abos-ctrl podman-rw load -i /mnt/at-debian-image.tar
Getting image source signatures
Copying blob 63c098a71e7b done
Copying blob 837e73dd4d20 done
Copying blob a25086e65f63 done
Copying config b5a30f8581 done
Writing manifest to image destination
Storing signatures
Loaded image(s): localhost/at-debian-image:latest
[armadillo ~]# podman image list
REPOSITORY                 TAG         IMAGE ID      CREATED      SIZE        R/O
localhost/at-debian-image  latest      b5a30f8581cc  2 hours ago  233 MB      true

図9.115 abos-ctrl podman-rw の実行例


[警告]

SWUpdate でアップデートをインストールする際には、/var/lib/containers/storage_readonly ディレクトリの不要になったイメージを自動的に削除します。

自動起動させる予定がなくても、「コンテナの自動起動」 を参考にして、 /etc/atmark/containers/*.conf を使ってください。 set_autostart no を設定することで自動実行されません。

9.2.5.3. イメージを SWUpdate で転送する方法

  1. イメージをファイルに保存する:

    [armadillo ~]$ podman image save -o <myimage>.tar <localimage>
  2. ファイルをSWUpdateのイメージに入れる。

    二つのやり方があります:

    1. swuイメージ内に組み込む

      [ATDE ~/mkswu]$ cp /usr/share/mkswu/examples/embed_container_nginx.desc .
      [ATDE ~/mkswu]$ cp -r /usr/share/mkswu/examples/nginx_start .
      [ATDE ~/mkswu]$ cat embed_container_nginx.desc
      swdesc_option version=1
      
      swdesc_embed_container "nginx_alpine.tar"
      swdesc_files --extra-os nginx_start
      [ATDE ~/mkswu]$ podman pull --arch arm64 docker.io/nginx:alpine
      [ATDE ~/mkswu]$ podman run --rm docker.io/nginx:alpine uname -m
      aarch64
      [ATDE ~/mkswu]$ podman save docker.io/nginx:alpine > nginx_alpine.tar
      [ATDE ~/mkswu]$ mkswu embed_container_nginx.desc
      Enter pass phrase for /home/atmark/mkswu/swupdate.key:
      embed_container_nginx.swu を作成しました
    2. USBドライブに保存する

      [ATDE ~/mkswu]$ cp /usr/share/mkswu/examples/usb_container_nginx.desc .
      [ATDE ~/mkswu]$ cp -r /usr/share/mkswu/examples/nginx_start .
      [ATDE ~/mkswu]$ cat usb_container_nginx.desc
      swdesc_option version=1
      
      swdesc_usb_container "nginx_alpine.tar"
      swdesc_files --extra-os nginx_start
      [ATDE ~/mkswu]$ podman pull --arch arm64 docker.io/nginx:alpine
      [ATDE ~/mkswu]$ podman run --rm docker.io/nginx:alpine uname -m
      aarch64
      [ATDE ~/mkswu]$ podman save docker.io/nginx:alpine > nginx_alpine.tar
      [ATDE ~/mkswu]$ mkswu -o usb_container_nginx.swu usb_container_nginx.desc
      Enter pass phrase for /home/atmark/mkswu/swupdate.key:
      以下のファイルをUSBメモリにコピーしてください:
      '/home/atmark/mkswu/usb_container_nginx.swu'
      '/home/atmark/mkswu/nginx_alpine.tar'
      '/home/atmark/mkswu/.usb_container_nginx/nginx_alpine.tar.sig'
      
      usb_container_nginx.swu を作成しました。

9.3. マルチメディアデータを扱う

9.3.1. GStreamer - マルチメディアフレームワーク

9.3.1.1. GStreamer - マルチメディアフレームワークとは

GStreamer は、オープンソースのマルチメディアフレームワークです。小さなコアライブラリに様々 な機能をプラグインとして追加できるようになっており、多彩な形式のデータを扱うことができます。 GStreamer で扱うことができるデータフォーマットの一例を下記に示します。

  • コンテナフォーマット: mp4, avi, mpeg-ps/ts, mkv/webm, ogg
  • 動画コーデック: H.264/AVC, VP8, VP9
  • 音声コーデック: AAC, MP3, Theora, wav
  • 画像フォーマット: JPEG, PNG, BMP
  • ストリーミング: http, rtp

GStreamer では、マルチメディアデータをストリームとして扱います。 ストリームを流すパイプラインの中に、エレメントと呼ばれる処理単位を格納し、 それらを繋ぎ合わせることで、デコードやエンコードなどの処理を行います。

9.3.2. GStreamer 実行用コンテナを作成する

この章における GStreamer の実行例はアットマークテクノが提供する debian イメージから作成したコンテナ内で実行することを想定しています。 「VPU や NPU を使用する」 を実施済みの環境で、以下のようにコンテナを作成します。

[armadillo ~]# podman run -it --name=gst-example \
--env=XDG_RUNTIME_DIR=/tmp \
--volume=/sys:/sys \
--volume=/dev:/dev \
--volume=/run/udev:/run/udev \
--volume=/opt/firmware:/opt/firmware \
--privileged \
localhost/at-debian-image:latest /bin/bash
[container /]#

図9.116 GStreamer を実行するためのコンテナ作成例


コンテナ内では最初に GStreamer をインストールします。

[container /]# apt install gstreamer1.0-imx libgstreamer-imx gstreamer1.0-plugins-bad \
libgstreamer-plugins-bad1.0-0 gstreamer1.0-plugins-base libgstreamer-plugins-base1.0-0 \
gstreamer1.0-plugins-good libgstreamer1.0-0 gstreamer1.0-tools gstreamer1.0-imx-tools

図9.117 gstreamer のインストール


次に、コンテナ内で画面表示を行うためのデスクトップ環境を起動します。 ここでは weston を起動します。

[container /]# weston --tty=1 &

図9.118 weston の起動


--tty=1 のオプションは画面表示に使用する tty の値を設定してください。

次に、音声を出力するのに必要な pulseaudio を起動します。

[conteiner /]# apt install pulseaudio
[container /]# pulseaudio --start --exit-idle-time=-1

図9.119 pulseaudio の起動


以上により、GSreamer をコンテナ内で実行できるようになります。

9.3.3. GStreamer パイプラインの実行例

パイプラインの実行例を以下に示します。

[container ~]# gst-launch-1.0 filesrc location=<ファイルパス> \
! qtdemux name=demux0 demux0.video_0 ! h264parse ! queue ! vpudec ! queue \
! waylandsink window-width=1920 window-height=1080 demux0.audio_0 ! queue ! beepdec ! autoaudiosink

図9.120 GStreamer の実行例


GStreamer のパイプラインは、シェルスクリプトのパイプ構文の構造に似ています。GStreamer の 各エレメントとシェルスクリプト内のコマンドを対比することができます。構文的な違いとして、 GStreamer のパイプラインは「!」を使って各エレメントを繋ぎますが、シェルスクリプトは「|」を使います。

上記例は、GStreamer のデバッグ/プロトタイピング用のコマンドラインツールである gst-launch-1.0 を使って説明しましたが、GStreamer はライブラリとして提供されているため、GStreamer を使った マルチメディア機能を自作のアプリケーションプログラムに組み込むことができます。API や アプリケーション開発マニュアルは、gstreamer.freedesktop.org の Documentation ページ (http://gstreamer.freedesktop.org/documentation/)から参照することができます。

Armadillo-IoT ゲートウェイ G4が採用している SoC である i.MX 8M Plus は、動画のデコード/エンコードを行うための Video Processing Unit(VPU) と呼ばれる 専用プロセッサを搭載しています。Armadillo-IoT ゲートウェイ G4には、この VPU を使用するための GStreamer エレメントがインストールされており、 以下の動画コーデックではメイン CPU のパフォーマンスを落とすことなく動画のデコード/エンコードが行なえます。

  • デコード可能なコーデック

    • H.264/AVC
    • VP8
    • VP9
  • エンコード可能なコーデック

    • H.264/AVC

以降の章では、これらのコーデックに対する GStreamer の実行例を紹介します。

上記で挙げたコーデック以外のものであってもデコード/エンコードは可能ですが、その場合は CPU を使ったソフトウェア処理となってしまうため、 システム全体のパフォーマンスは低下します。

9.3.4. 動画を再生する

GStreamer を使用して動画を再生するための実行例を、音声を含んでいる動画と含んでいない動画の 2 通りについて示します。 VPU でハードウェアデコードを行う GStreamer エレメントとして vpudec を使うことができます。

9.3.4.1. H.264/AVC 動画を再生する

[container ~]# gst-launch-1.0 filesrc location=<ファイルパス> \
! qtdemux name=demux0 demux0.video_0 ! h264parse ! queue ! vpudec ! queue \
! waylandsink window-width=1920 window-height=1080 demux0.audio_0 ! queue ! beepdec ! autoaudiosink

図9.121 H.264/AVC 動画の再生(音声あり)


[container ~]# gst-launch-1.0 filesrc location=<ファイルパス> \
! qtdemux ! h264parse ! vpudec ! queue ! waylandsink window-width=1920 window-height=1080

図9.122 H.264/AVC 動画の再生(音声なし)


9.3.4.2. VP8 動画を再生する

[container ~]# gst-launch-1.0 filesrc location=<ファイルパス> \
! matroskademux name=demux0 demux0.video_0 ! queue ! vpudec ! queue \
! waylandsink window-width=1920 window-height=1080 demux0.audio_0 ! queue ! beepdec ! autoaudiosink

図9.123 VP8 動画の再生(音声あり)


[container ~]# gst-launch-1.0 filesrc location=<ファイルパス> \
! matroskademux ! vpudec ! queue ! waylandsink window-width=1920 window-height=1080

図9.124 VP8 動画の再生(音声なし)


9.3.4.3. VP9 動画を再生する

[container ~]# gst-launch-1.0 filesrc location=<ファイルパス> \
! matroskademux name=demux0 demux0.video_0 ! queue ! vpudec ! queue \
! waylandsink window-width=1920 window-height=1080 demux0.audio_0 ! queue ! beepdec ! autoaudiosink

図9.125 VP9 動画の再生(音声あり)


[container ~]# gst-launch-1.0 filesrc location=<ファイルパス> \
! matroskademux ! vpudec ! queue ! waylandsink window-width=1920 window-height=1080

図9.126 VP9 動画の再生(音声なし)


9.3.5. ストリーミングデータを再生する

GStreamer を使用してネットワーク上にある動画ファイルを HTTP 及び RTSP でストリーミング再生する実行例を示します。 VPU でハードウェアデコードを行う GStreamer エレメントとして vpudec を使うことができます。

9.3.5.1. HTTP ストリーミング

[container ~]# gst-launch-1.0 souphttpsrc location=<動画ファイルのURI> \
! qtdemux name=demux demux. ! queue ! vpudec ! queue \
! waylandsink demux. ! queue ! beepdec ! autoaudiosink

図9.127 HTTP ストリーミングの再生(音声あり)


[container ~]# gst-launch-1.0 souphttpsrc location=<動画ファイルのURI> \
! qtdemux ! queue ! vpudec ! queue ! waylandsink

図9.128 HTTP ストリーミングの再生(音声なし)


9.3.5.2. RTSP ストリーミング

[container ~]# gst-launch-1.0 rtspsrc location=<動画ファイルのURI> name=source \
! queue ! rtph264depay ! vpudec ! queue ! waylandsink source. ! queue \
! rtpmp4gdepay ! aacparse ! beepdec ! autoaudiosink

図9.129 RTSP ストリーミングの再生(音声あり)


[container ~]# gst-launch-1.0 rtspsrc location=<動画ファイルのURI> \
! queue ! rtph264depay ! vpudec ! queue ! waylandsink

図9.130 RTSP ストリーミングの再生(音声なし)


9.3.6. USB カメラからの映像を表示する

GStreamer の v4l2src エレメントを使うことで、V4L2(Video for Linux 2) デバイスとして実装されているカメラデバイスから映像を取得できます。 どのデバイスから映像を取得するかは、v4l2src エレメントの device プロパティにデバイスファイル名を指定することで変更できます。 UVC 対応 USB カメラなども同様に v4l2src で扱うことができるので、ここでは USB カメラからの映像を表示する実行例を示します。

加えて、カメラの他にマイクも接続していて、同時にマイクからの音声も出力する場合の例も示しています。 実行例中のデバイスファイル /dev/video1 の部分や、縦横サイズである width や height の値は実行する環境によって異なる可能性がありますので、適宜変更してください。 また、/dev/v4l/by-id ディレクトリの下に、接続しているカメラ名の付いた /dev/videoN へのシンボリックリンクがありますので、デバイスとしてそれを指定することも可能です。

[container ~]# gst-launch-1.0 v4l2src device=/dev/video1 \
! video/x-raw,width=640,height=480,framerate=30/1 \
! waylandsink window-width=640 window-height=480 pulsesrc \
! audio/x-raw,rate=44100,channels=2 ! autoaudiosink

図9.131 USB カメラからの映像表示(音声あり)


[container ~]# gst-launch-1.0 v4l2src device=/dev/video1 \
! video/x-raw,width=640,height=480,framerate=30/1 \
! waylandsink window-width=640 window-height=480

図9.132 USB カメラからの映像表示(音声なし)


9.3.7. USBカメラからの映像を録画する

GStreamer の v4l2src エレメントを使うことで、V4L2(Video for Linux 2) デバイスとして実装されているカメラデバイスから映像を取得できます。 どのデバイスから映像を取得するかは、v4l2src エレメントの device プロパティにデバイスファイル名を指定することで変更できます。 UVC 対応 USB カメラなども同様に v4l2src で扱うことができるので、ここでは USB カメラからの映像をファイルへ保存する実行例と、 映像を表示しながら同時にファイルへ保存する実行例を示します。

加えて、カメラの他にマイクも接続していて、映像の保存と同時にマイクからの音声も MP3 へエンコードして保存する場合の例も示しています。 実行例中のデバイスファイル /dev/video1 の部分や、縦横サイズである width や height の値は実行する環境によって異なる可能性がありますので、適宜変更してください。 また、/dev/v4l/by-id ディレクトリの下に、接続しているカメラ名の付いた /dev/videoN へのシンボリックリンクがありますので、デバイスとしてそれを指定することも可能です。

パイプライン停止時に EOS イベントを発行するように、gst-launch-1.0 コマンドに-e オプションを付けています。 エンコードを終了するには、Ctrl-C で gst-launch-1.0 コマンドを停止してください。

9.3.7.1. H.264/AVC で録画する

VPU でハードウェアエンコードを行う GStreamer エレメントとして vpuenc_h264 を使うことができます。

[container ~]# gst-launch-1.0 -e v4l2src device=/dev/video1 \
! video/x-raw,width=640,height=480,framerate=30/1 \
! queue ! vpuenc_h264 ! h264parse ! queue ! mux. pulsesrc \
! audio/x-raw,rate=44100,channels=2 ! lamemp3enc ! queue \
! mux. qtmux name=mux ! filesink location=./output.mp4

図9.133 USB カメラからの映像をH.264で録画(音声あり)


[container ~]# gst-launch-1.0 -e v4l2src device=/dev/video1 \
! video/x-raw,width=640,height=480,framerate=30/1 \
! queue ! vpuenc_h264 ! h264parse ! queue \
! filesink location=./output.mp4

図9.134 USB カメラからの映像をH.264で録画(音声なし)


  • 表示と録画を同時に行う
[container ~]# gst-launch-1.0 -e v4l2src device=/dev/video1 \
! video/x-raw,width=640,height=480,framerate=30/1 \
! tee name=t1 ! queue ! vpuenc_h264 ! h264parse ! queue ! mux. pulsesrc \
! tee name=t2 ! audio/x-raw,rate=44100,channels=2 ! lamemp3enc ! queue \
! mux. qtmux name=mux ! filesink location=./output.mp4 t1. ! queue \
! waylandsink window-width=640 window-height=480 t2. ! queue ! autoaudiosink

図9.135 USB カメラからの映像を表示しながらH.264で録画(音声あり)


[container ~]# gst-launch-1.0 -e v4l2src device=/dev/video1 \
! video/x-raw,width=640,height=480,framerate=30/1 \
! tee name=t1 ! queue ! vpuenc_h264 ! h264parse ! queue \
! qtmux ! filesink location=./output.mp4 t1. ! queue \
! waylandsink window-width=640 window-height=480

図9.136 USB カメラからの映像を表示しながらH.264で録画(音声なし)


9.3.8. Video Processing Unit(VPU)

9.3.8.1. Video Processing Unit とは

Video Processing Unit(以下、VPU) とは i.MX 8M Plus に搭載されている、動画のエンコード/デコード処理専用のプロセッサです。 動画のエンコード/デコード処理は、システムに負荷をかけることが多く、メイン CPU で処理を行うとシステム全体のパフォーマンスが低下します。 VPU を利用することでシステム全体のパフォーマンスを落とすことなく、動画のエンコード/デコード処理を行うことができます。

VPU が対応しているフォーマットは以下の通りです。

  • デコーダーが対応しているフォーマット

    • H.264/AVC
    • VP8
    • VP9
  • エンコーダが対応しているフォーマット

    • H.264/AVC

9.3.8.2. VPUの仕様

  • H.264/AVC デコーダー

表9.4 H.264/AVC デコーダー仕様

Profile

High、Main、Baseline

Min resolution

48x48

Max resolution

1920x1080

Frame rate

60 fps

Bitrate

60 Mbps


  • VP8 デコーダー

表9.5 VP8 デコーダー仕様

Profile

-

Min resolution

48x48

Max resolution

1920x1080

Frame rate

60 fps

Bitrate

60 Mbps


  • VP9 デコーダー

表9.6 VP9 デコーダー仕様

Profile

Profile 0, 2

Min resolution

72x72

Max resolution

1920x1080

Frame rate

60 fps

Bitrate

100 Mbps


  • H.264/AVC エンコーダー

表9.7 H.264/AVC エンコーダー仕様

Profiles

Baseline、Main、High、High 10

Maximum Luma pixel sample rate

1920x1080 @ 60 fps

Slices

I, P and B slices

Frame Types

Progressive

Entropy encoding

CABAC、CAVLC

Error resilience

Slices

Maximum MV range

Horizontal (P slice) in pixels: +/-139

Horizontal (B slice) in pixels: +/-75

Vertical (P or B slice) in pixels:

  • Config1: +/-13 (planned)
  • Config2: +/-21
  • Config3: +/-29 (planned)
  • Config4: +/-45 (planned)
  • Config5: +/-61 (planned)

(= Search Window Size -3 pixels)

MV accuracy

1/4 pixel

Supported block sizes

Macroblock and sub-macroblock partitions:

  • Intra PU: 16x16 / 8x8 / 4x4
  • Inter PU: 16x16 / 8x16 / 16x8
  • TU: 4x4 and 8x8 transforms

Intra-prediction modes

16x16: 4 modes

8x8: 9 modes

4x4: 9 modes

Maximum number of reference frames

2

Encoding picture type

Only progressive frame

IPCM encoding

Supported

Temporal scalable video coding

Up to 5 layers including the base layer

IPCM

IPCM rectangle mode

ROI / ROI_map

Absolute QP and qpoffset mode (-32 〜 31)

User controllable CU coded as IPCM CU or skip CU


9.4. Armadilloのソフトウェアをビルドする

ここでは、Armadillo-IoT ゲートウェイ G4で使用するソフトウェアのビルド方法を説明します。

9.4.1. ブートローダーをビルドする

ここでは、Armadillo-IoT ゲートウェイ G4向けのブートローダーイメージをビルドする方法を説明します。

  1. ブートローダーのビルドに必要なパッケージのインストール

    次のコマンドを実行します。

    [PC ~]$ sudo apt install build-essential git wget gcc-aarch64-linux-gnu libgcc-*-dev-arm64-cross bison flex zlib1g-dev bash python3-pycryptodome python3-pyelftools device-tree-compiler
  2. ソースコードの取得

    Armadillo-IoT ゲートウェイ G4 ブートローダー から 「ブートローダー ソース」ファイル (imx-boot-[VERSION].tar.gz) をダウンロードして、次のコマンドを実行します。

    [PC ~]$ tar xf imx-boot-[VERSION].tar.gz
    [PC ~]$ cd imx-boot-[VERSION]
  3. ビルド

    次のコマンドを実行します。

    [PC ~/imx-boot-[VERSION]]$ make imx-boot_armadillo_x2
    :
    : (省略)
    :
    Second Loader IMAGE:
     sld_header_off         0x58000
     sld_csf_off            0x59020
     sld hab block:         0x401fcdc0 0x58000 0x1020
    make[1]: ディレクトリ '/home/atmark/imx-boot-[VERSION]/imx-mkimage' から出ます
    cp imx-mkimage/iMX8M/flash.bin imx-boot_armadillo_x2

    初めてのビルドの場合、i.MX 8M Plusに必要なファームウェアの EULA への同意を求められます。 内容を確認の上、同意してご利用ください。[8]

    Welcome to NXP firmware-imx-8.11.bin
    
    You need to read and accept the EULA before you can continue.
    
    LA_OPT_NXP_Software_License v19 February 2021
    :
    : (省略)
    :
    Do you accept the EULA you just read? (y/N)
  4. ビルド結果の確認

    次のコマンドを実行します。

    [PC ~/imx-boot-[VERSION]]$ ls imx-boot_armadillo_x2
    imx-boot_armadillo_x2

9.4.2. Linux カーネルをビルドする

ここでは、Armadillo-IoT ゲートウェイ G4向けのLinuxカーネルイメージをビルドする方法を説明します。

[ティップ]

Armadillo-IoT ゲートウェイ G4では、 基本的にはLinuxカーネルイメージをビルドする必要はありません。 「Alpine Linux ルートファイルシステムをビルドする」の手順を実施することで、 標準のLinuxカーネルイメージがルートファイルシステムに組み込まれます。

標準のLinuxカーネルイメージは、アットマークテクノが提供する linux-at というAlpine Linux用のパッケージに含まれています。

カスタマイズしたLinuxカーネルイメージを利用するには、 「Alpine Linux ルートファイルシステムをビルドする」の手順の中で、 ax2/packages から linux-at を削除し、 ax2/resources/boot/ にイメージを配置する必要があります。

  1. Linuxカーネルのビルドに必要なパッケージのインストール

    次のコマンドを実行します。

    [PC ~]$ sudo apt install crossbuild-essential-arm64 bison flex python3-pycryptodome python3-pyelftools zlib1g-dev libssl-dev bc firmware-misc-nonfree firmware-libertas firmware-atheros wireless-regdb
  2. ソースコードの取得

    Armadillo-IoT ゲートウェイ G4 Linuxカーネル から 「Linuxカーネル」ファイル (linux-at-[VERSION].tar) をダウンロードして、次のコマンドを実行します。

    [PC ~]$ tar xf linux-at-[VERSION].tar
    [PC ~]$ tar xf linux-at-[VERSION]/linux-[VERSION].tar.gz
    [PC ~]$ cd linux-[VERSION]
  3. デフォルトコンフィギュレーションの適用

    次のコマンドを実行します。

    [PC ~/linux-[VERSION]]$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- x2_defconfig
  4. カーネルコンフィギュレーションの変更

    次のコマンドを実行します。 カーネルコンフィギュレーションの変更を行わない場合はこの手順は不要です。

    [PC ~]$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

    コマンドを実行するとカーネルコンフィギュレーション設定画面が表示されます。 カーネルコンフィギュレーションを変更後、"Exit"を選択して 「Do you wish to save your new kernel configuration? (Press <ESC><ESC> to continue kernel configuration.)」で"Yes"とし、 カーネルコンフィギュレーションを確定します。

     .config - Linux/arm64 5.10.86 Kernel Configuration
     ─────────────────────────────────────────────
      ┌────────── Linux/arm64 5.10.86 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  [ ] excluded  <M> module  < > module capable                │
      │ ┌───────────────────────────────────────┐ │
      │ │         General setup  --->                                                  │ │
      │ │     [*] Support DMA zone                                                     │ │
      │ │     [*] Support DMA32 zone                                                   │ │
      │ │         Platform selection  --->                                             │ │
      │ │         Kernel Features  --->                                                │ │
      │ │         Boot options  --->                                                   │ │
      │ │         Power management options  --->                                       │ │
      │ │         CPU Power Management  --->                                           │ │
      │ │         Firmware Drivers  --->                                               │ │
      │ │     [ ] Virtualization  ----                                                 │ │
      │ │     -*- ARM64 Accelerated Cryptographic Algorithms  --->                     │ │
      │ │         General architecture-dependent options  --->                         │ │
      │ │     [*] Enable loadable module support  --->                                 │ │
      │ │     [*] Enable the block layer  --->                                         │ │
      │ │         IO Schedulers  --->                                                  │ │
      │ │         Executable file formats  --->                                        │ │
      │ │         Memory Management options  --->                                      │ │
      │ │     [*] Networking support  --->                                             │ │
      │ │         Device Drivers  --->                                                 │ │
      │ │         File systems  --->                                                   │ │
      │ │         Security options  --->                                               │ │
      │ │     -*- Cryptographic API  --->                                              │ │
      │ │         Library routines  --->                                               │ │
      │ │         Kernel hacking  --->                                                 │ │
      │ │                                                                              │ │
      │ └───────────────────────────────────────┘ │
      ├──────────────────────────────────────────┤
      │              <Select>    < Exit >    < Help >    < Save >    < Load >              │
      └──────────────────────────────────────────┘
    [ティップ]

    Linux Kernel Configuration メニューで"/"キーを押下すると、カーネルコンフィギュレーションの検索を行うことができます。 カーネルコンフィギュレーションのシンボル名(の一部)を入力して"Ok"を選択すると、 部分一致するシンボル名を持つカーネルコンフィギュレーションの情報が一覧されます。

  5. ビルド

    次のコマンドを実行します。

    [PC ~/linux-[VERSION]]$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j5
  6. ビルド結果の確認

    次のコマンドを実行します。

    [PC ~/linux-[VERSION]]$ ls arch/arm64/boot/Image
    arch/arm64/boot/Image
    [PC ~/linux-[VERSION]]$ ls arch/arm64/boot/dts/freescale/armadillo_*.dtb
    arch/arm64/boot/dts/freescale/armadillo_iotg_g4-nousb.dtb
    arch/arm64/boot/dts/freescale/armadillo_iotg_g4.dtb

9.4.3. Alpine Linux ルートファイルシステムをビルドする

ここでは、alpine/build-rootfsを使って、 Alpine Linux ルートファイルシステムを構築する方法を説明します。

alpine/build-rootfsはPCで動作しているLinux上でArmadillo-IoT ゲートウェイ G4用の aarch64アーキテクチャに対応したAlpine Linux ルートファイルシステムを構築することができるツールです。

9.4.3.1. デフォルトのAlpine Linux ルートファイルシステムを構築する

  1. ルートファイルシステムのビルドに必要な Podman のインストール

    次のコマンドを実行します。

    [PC ~]$ sudo apt install podman
  2. alpine/build-rootfsの入手

    Armadillo-IoT ゲートウェイ G4 開発用ツール から 「Alpine Linuxルートファイルシステムビルドツール」 ファイル (build-rootfs-[VERSION].tar.gz) をダウンロードして、 次のコマンドを実行します。

    [PC ~/]$ wget https://download.atmark-techno.com/armadillo-iot-g4/tool/build-rootfs-latest.tar.gz
    [PC ~/]$ tar xf build-rootfs-latest.tar.gz
    [PC ~/]$ cd build-rootfs-[VERSION]
  3. ビルド

    次のコマンドを実行します。

    パッケージをインターネット上から取得するため回線速度に依存しますが、 ビルドには数分かかります。

    [PC ~/build-rootfs-[VERSION]]$ sudo ./build_rootfs.sh
    use default(board=ax2)
    use default(arch=aarch64)
    use default(outdir=/home/xxxx/at-optee-build/build-rootfs)
    use default(output=baseos-x2-ATVERSION.tar.zst)
    'repositories' -> '/etc/apk/repositories'
    :
    : (略)
    :
    > Creating rootfs archive
    -rw-r--r--    1 root     root     231700480 Nov 26 07:18 rootfs.tar
    ERROR: No such package: .make-alpine-make-rootfs
    ============================================
    footprint[byte]  tarball[byte]  packages
          229904000       74942331  alpine-base coreutils chrony ...(省略)
    ============================================
    done.
    [注記]

    ビルド時のログにエラー "ERROR: No such package: .make-alpine-make-rootfs" が出ていますが、正常時でも出力されるメッセージのため、 問題はありません。

    [注記]

    リリース時にバージョンに日付を含めたくないときは --release を引数に追加してください。

    [注記]

    任意のパス、ファイル名で結果を出力することもできます。

    [PC ~/build-rootfs-[VERSION]]$ ./build_rootfs.sh ~/alpine.tar.gz
    :
    : (略)
    :
    [PC ~/build-rootfs-[VERSION]]$ ls ~/alpine.tar.gz
    ~/alpine.tar.gz
  4. ビルド結果の確認

    次のコマンドを実行します。

    [PC ~/build-rootfs-[VERSION]]$ ls *tar.zst
    baseos-x2-[VERSION].tar.zst

9.4.3.2. Alpine Linux ルートファイルシステムをカスタマイズする

alpine/build-rootfsディレクトリ直下にある ax2 ディレクトリ以下のファイルを変更し、 build.shを実行することで、 ルートファイルシステムをカスタマイズすることができます。

  • install

    • resources/ ディレクトリ内のファイルを、 ルートファイルシステムにインストールするためのスクリプト
  • resources/

    • ルートファイルシステムにインストールするファイルを含んだディレクトリ
  • packages

    • ルートファイルシステムにインストールするパッケージのリスト
  • fixup

    • パッケージのインストールや上記installスクリプトの後に実行されるスクリプト
  • ファイル/ディレクトリを追加する

ax2/resources/ 以下に配置したファイルやディレクトリは、 そのままルートファイルシステムの直下にコピーされます。 デフォルトでは、 UIDとGIDは共にroot、パーミッションは 0744(ディレクトリの場合は 0755) となります。

ax2/install を修正することで、 ファイルのUID、GID、パーミッションを変更することができます。 UID、GIDを変更する場合はchown、 パーミッションを変更する場合はchmodを利用してください。

  • パッケージを変更する

ax2/packages を変更することで、 ルートファイルシステムにインストールするパッケージをカスタマイズすることができます。

パッケージ名は1行に1つ書くことができます。 パッケージ名はArmadillo上で"apk add" の引数に与えることのできる正しい名前で記載してください。 誤ったパッケージ名を指定した場合は、 ルートファイルシステムのビルドに失敗します。

[注記]

利用可能なパッケージは以下のページで検索することができます。

Alpine Linuxルートファイルシステム使用した Armadilloで検索することもできます。

[armadillo ~]# apk list *ruby*
ruby-rmagick-4.1.2-r1 armhf {ruby-rmagick} (MIT)
ruby-concurrent-ruby-ext-1.1.6-r1 armhf {ruby-concurrent-ruby} (MIT)
ruby-net-telnet-2.7.2-r3 armhf {ruby} (Ruby AND BSD-2-Clause AND MIT)
:
: (省略)
:
ruby-mustache-1.1.1-r3 armhf {ruby-mustache} (MIT)
ruby-nokogiri-1.10.10-r0 armhf {ruby-nokogiri} (MIT)

9.5. SDブートの活用

本章では、microSDカードから直接起動(以降「SDブート」と表記します)する手順を示します。 SDブートを活用すると、microSDカードを取り替えることでシステムイメージを変更することができます。 本章に示す手順を実行するためには、容量が8Gbyte以上のmicroSDカードを必要とします。

[ティップ]

SDブートを行った場合、ブートローダーの設定は microSDカード に保存されます。

9.5.1. ブートディスクの作成

  1. ブートディスクイメージのビルドします

    「Alpine Linux ルートファイルシステムをビルドする」 で説明されているソースツリー alpine/build-rootfs にあるスクリプト build_image「ブートローダーをビルドする」 でビルドした imx-boot_armadillo_x2 を利用します。

    VPU や NPU も使用する場合は、 「VPU や NPU を使用する」 で用意した imx_lib.img も組み込めます。

    [PC ~/build-rootfs-[VERSION]]$ sudo ./build_image.sh \
            --boot ~/imx-boot-[VERSION]/imx-boot_armadillo_x2 \
            --firmware ~/at-imxlibpackage/imx_lib.img
    : (省略)
    [PC ~/build-rootfs-[VERSION]]$ ls baseos-x2*img
    baseos-x2-[VERSION].img
  2. ATDE に microSD カードを接続します。詳しくは「取り外し可能デバイスの使用」を参考にしてください。
  3. microSD カードのデバイス名を確認します

    [ATDE ~]$ ls /dev/sd?
    /dev/sda  /dev/sdb
    [ATDE ~]$ sudo fdisk -l /dev/sdb
    Disk /dev/sdb: 7.22 GiB, 7751073792 bytes, 15138816 sectors
    Disk model: SD/MMC
    : (省略)
  4. microSD カードがマウントされている場合、アンマウントします。

    [ATDE ~]$ mount
    : (省略)
    /dev/sdb1 on /media/52E6-5897 type ext2 (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0077,codepage=cp437,iocharset=utf8,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks)
    [ATDE ~]$ sudo umount /dev/sdb1

    図9.137 自動マウントされたmicroSDカードのアンマウント


  5. ブートディスクイメージの書き込み

    [PC ~]$ sudo dd if=~/build-rootfs-[VERSION]/baseos-x2-[VERSION].img \
                    of=/dev/sdb bs=1M oflag=direct status=progress

    microSDカードの性能にもよりますが、書き込みには5分程度かかります。

[ティップ]

microSDカードのパーティション構成は次のようになっています。

表9.8 microSDカードのパーティション構成

パーティション オフセット サイズ 説明

-

0

10MiB

ブートローダー

1

10MiB

300MiB

A/B アップデートのA面パーティション

2

310MiB

300MiB

A/B アップデートのB面パーティション

3

610MiB

50MiB

ログ用パーティション

4

660MiB

200MiB

ファームウェア

5

860MiB

残り

アプリケーション用パーティション


gdiskで確認すると次のようになります。

[PC ~]$ sudo gdisk -l /dev/mmcblk0
GPT fdisk (gdisk) version 1.0.8

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
Disk /dev/mmcblk0: 15319040 sectors, 7.3 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 309AD967-470D-4FB2-835E-7963578102A4
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 15319006
Partitions will be aligned on 2048-sector boundaries
Total free space is 20446 sectors (10.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1           20480          634879   300.0 MiB   8300  rootfs_0
   2          634880         1249279   300.0 MiB   8300  rootfs_1
   3         1249280         1351679   50.0 MiB    8300  logs
   4         1351680         1761279   200.0 MiB   8300  firm
   5         1761280        15319006   6.5 GiB     8300  app

9.5.2. SDブートの実行

「ブートディスクの作成」で作成したブートディスクから起動する方法を説明します。

  1. Armadillo-IoT ゲートウェイ G4に電源を投入する前に、ブートディスクをCON1(SD インターフェース)に挿入します。 また、JP1ジャンパーをショート(SDブートに設定)します。
  2. 電源を投入します。

    U-Boot SPL 2020.04-at1 (Dec 09 2021 - 11:17:22 +0900)
    rv8803 rtc woken by interrupt
    DDRINFO: start DRAM init
    DDRINFO: DRAM rate 4000MTS
    DDRINFO:ddrphy calibration done
    DDRINFO: ddrmix config done
    Normal Boot
    Trying to boot from BOOTROM
    image offset 0x8000, pagesize 0x200, ivt offset 0x0
    NOTICE:  BL31: v2.4(release):
    NOTICE:  BL31: Built : 11:24:17, Dec  9 2021
    
    
    U-Boot 2020.04-at1 (Dec 09 2021 - 11:17:22 +0900)
    
    CPU:   i.MX8MP[8] rev1.1 1600 MHz (running at 1200 MHz)
    CPU:   Industrial temperature grade (-40C to 105C) at 40C
    Model: Atmark-Techno Armadillo X2 Series
    DRAM:    Hold key pressed for tests: t (fast) / T (slow)
    2 GiB
    WDT:   Started with servicing (10s timeout)
    MMC:   FSL_SDHC: 1, FSL_SDHC: 2
    Loading Environment from MMC... OK
    In:    serial
    Out:   serial
    Err:   serial
    
     BuildInfo:
      - ATF
      - U-Boot 2020.04-at1
    
    first boot since power on
    switch to partitions #0, OK
    mmc1 is current device
    flash target is MMC:1
    Net:   eth0: ethernet@30be0000 [PRIME], eth1: ethernet@30bf0000
    Fastboot: Normal
    Saving Environment to MMC... Writing to MMC(1)... OK
    Normal Boot
    Warning: Bootlimit (3) exceeded. Using altbootcmd.
    Hit any key to stop autoboot:  0
    u-boot=>
  3. ブートディスク上のLinuxカーネルを起動します。

    u-boot=> boot

9.6. Armadilloのソフトウェアの初期化

microSD カードを使用し、Armadillo Base OS の初期化を行えます。

[ティップ]

初期化を行っても、ファームウェアパーティション(mmcblk2p4)は変更されません。 故障が疑われる場合など、ファームウェアも初期化したい場合、 初期化してから 「VPU や NPU を使用する」 を参考にしてもう一度書き込みしてください。

9.6.1. インストールディスクの作成

  1. 512 MB 以上の microSD カードを用意してください。
  2. 標準のインストールディスクイメージを使用する場合は、 Armadillo-IoT ゲートウェイ G4 インストールディスクイメージ から 「Armadillo Base OS」をダウンロードしてください。

    「Armadilloのソフトウェアをビルドする」 でビルドしたイメージを使用してインストールディスクを作成したい場合は、 以下のコマンドを実行して、インストールディスクイメージを作成してください。

    [ATDE ~/build-rootfs-[VERSION]]$ sudo ./build_image.sh \
            --firmware ~/at-imxlibpackage/imx_lib.img
    : (省略)
    [ATDE ~/build-rootfs-[VERSION]]$ ls baseos-x2*img
    baseos-x2-[VERSION].img
    [ATDE ~/build-rootfs-[VERSION]]$ sudo ./build_image.sh \
            --boot ~/imx-boot-[VERSION]/imx-boot_armadillo_x2 \
            --installer ./baseos-x2-[VERSION].img

    コマンドの実行が完了すると、baseos-x2-[VERSION]-installer.img というファイルが作成されていますので、 こちらを使用してください。

  3. ATDE に microSD カードを接続します。詳しくは「取り外し可能デバイスの使用」を参考にしてください。
  4. microSD カードのデバイス名を確認します

    [ATDE ~]$ ls /dev/sd?
    /dev/sda  /dev/sdb
    [ATDE ~]$ sudo fdisk -l /dev/sdb
    Disk /dev/sdb: 7.22 GiB, 7751073792 bytes, 15138816 sectors
    Disk model: SD/MMC
    : (省略)
  5. microSD カードがマウントされている場合、アンマウントします。

    [ATDE ~]$ mount
    : (省略)
    /dev/sdb1 on /media/52E6-5897 type ext2 (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0077,codepage=cp437,iocharset=utf8,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks)
    [ATDE ~]$ sudo umount /dev/sdb1
  6. ダウンロードしたファイルを展開し、imgファイルをmicroSDカードに書き込んでください。

    Linux PCの場合、以下のようにmicroSDカードに書き込むことができます。

    [ATDE ~]$ unzip baseos-x2-installer-[VERSION].zip
    [ATDE ~]$ sudo dd if=baseos-x2-installer-[VERSION].img \
                      of=/dev/sdb bs=1M oflag=direct status=progress

    また、Windowsの場合、エクスプローラー等でZipファイルからimgファイルを取り出し、「Win32 Disk Imager」などを使用してmicroSDカードに書き込むことができます。

9.6.2. インストールディスクを使用した初期化

  1. JP1ジャンパーをショート(SDブートに設定)し、microSDカードをCON1に挿入します。
  2. 電源を投入すると、1分程度でeMMCのソフトウェアの初期化が完了します。
  3. 完了すると電源が切れます(LED4が消灯、コンソールに reboot: Power down が表示)。
  4. 電源を取り外し、続いてJP1ジャンパーとmicroSDカードを外してください。
  5. 10秒以上待ってから再び電源を入れると、初回起動時と同じ状態になります。

9.7. Armadilloのソフトウェアをアップデートする

Armadillo-IoT ゲートウェイ G4では、 開発・製造・運用それぞれに適した複数のソフトウェアアップデート方法を用意しています。 本章では、それぞれのソフトウェアアップデート方法について説明します。

ソフトウェアアップデートを実現するソフトウェアの概要や仕様、用語については 13章ソフトウェア仕様 を参照してください。

9.7.1. SWUイメージとは?

Armadillo Base OS ではソフトウェアアップデートのためにOS やコンテナ等を格納するためにSWUというイメージ形式を使います。

SWUイメージは swupdate (https://sbabic.github.io/swupdate/swupdate.html) によってArmadillo Base OS上で検証とインストールが実行されます。SWUイメージをArmadilloに転送するための方法は、用途や状況に合わせて様々な方法を用意しています。例えば、USBメモリから読み取る、ウェブサーバーからダウンロードする、hawkBitというWebアプリケーションを使うなどです。

9.7.2. SWUイメージの作成

SWUイメージの作成には、mkswu というツールを使います。

mkswu に含まれる mkswu を実行すると、アップデート対象やバージョン等の情報を記載した .desc ファイルに含まれる命令を順次実行してイメージを作り上げます。

詳しくは「mkswu の desc ファイル」を参考にしてください。

  1. mkswu の取得

    [ATDE ~]$ sudo apt update && sudo apt install mkswu

    インストール済みの場合は、以下のコマンドを実行し最新版への更新を行ってください。

    [ATDE ~]$ sudo apt update && sudo apt upgrade
[ティップ]

git のバージョンからアップデートする場合、 mkswu --import で以前使っていたコンフィグをロードしてください。

[ATDE ~/swupdate-mkimage]$ mkswu --import
コンフィグファイルを更新しました:/home/atmark/swupdate-mkimage/mkswu.conf
/home/atmark/swupdate-mkimage/mkswu.conf のコンフィグファイルとその鍵を
/home/atmark/mkswu にコピーします。
mkdir: ディレクトリ '/home/atmark/mkswu' を作成しました
'/home/atmark/swupdate-mkimage/swupdate.key' -> '/home/atmark/mkswu/swupdate.key'
'/home/atmark/swupdate-mkimage/swupdate.pem' -> '/home/atmark/mkswu/swupdate.pem'
/home/atmark/swupdate-mkimage/mkswu.conf のコンフィグファイルを
/home/atmark/mkswu/mkswu.conf にコピーしました。
mkswu でイメージ作成を試してから前のディレクトリを消してください。
  1. 最初に行う設定

    mkswu --init を実行して鍵や最初の書き込み用のイメージを生成します。 作成する鍵は、swuパッケージを署名するために使用します。

    使用しているArmadilloに、過去に一度でもこの初回アップデート作業を行っている場合は二度同じ作業を行うことはできず、する必要もありません。 その際にArmadilloに配置した公開鍵に対応する秘密鍵でアップデートを行いますので、 「mkswu の desc ファイル」 を参考にしてそのままにお使い下さい。

    [ATDE ~]$ mkswu --init
    mkdir: ディレクトリ '/home/atmark/mkswu' を作成しました
    コンフィグファイルを更新しました:/home/atmark/mkswu/mkswu.conf
    証明書のCommon nameを入力してください: [COMMON_NAME] 1
    証明書の鍵のパスワードを入力ください(4-1024文字)2
    証明書の鍵のパスワード(確認):
    Generating an EC private key
    writing new private key to '/home/atmark/mkswu/swupdate.key'
     -----
    アップデートイメージを暗号化しますか? (N/y) 3
    アットマークテクノが作成したイメージをインストール可能にしますか? (Y/n) 4
    rootパスワード: 5
    rootパスワード(確認):
    atmarkユーザのパスワード(空の場合はrootパスワードを使います): 6
    atmarkユーザのパスワード(確認):
    BaseOSイメージのarmadillo.atmark-techno.comサーバーからの自動アップデートを行いますか? (y/N) 7
    /home/atmark/mkswu/initial_setup.swu を作成しました。
    
    "/home/atmark/mkswu/initial_setup.swu" をそのまま使えますが、追加の desc を入れたい場合
    次のコマンドで作成してください: mkswu "/home/atmark/mkswu/initial_setup.swu" other_desc_files
    
    インストール後は、このディレクトリを削除しないように注意してください。
    鍵を失うと新たなアップデートはデバイスの /etc/swupdate.pem
    を修正しないとインストールできなくなります。
    
    [ATDE ~]$ ls ~/mkswu
    initial_setup.desc  initial_setup.swu  mkswu.conf
    swupdate.aes-key    swupdate.key       swupdate.pem 8

    1

    COMMON_NAME には証明鍵の「common name」として会社や製品が分かるような任意の名称を入力ください。

    2

    証明鍵を保護するパスフレーズを2回入力します。

    3

    swuイメージ自体を暗号化する場合に「y」を入力します。詳細は 「SWUpdate と暗号化について」 を参考にしてください。

    4

    アットマークテクノのアップデートをインストールしない予定でしたら「n」を入力します。

    5

    rootのパスワードを2回入力します。

    6

    atmarkユーザーのパスワードも2回入力します。何も入力しない場合はrootと同じパスワードを使います。

    7

    自動アップデートを無効のままで進みます。ここで「y」を入れると、定期的に アットマークテクノのサーバーからアップデートの有無を確認し、自動にインストールします。

    8

    作成したファイルを確認します。「swupdate.aes-key」は暗号化の場合のみに作成されます。

    このイメージは初回インストール用の署名鍵を使って、作成した鍵とユーザーのパスワードを設定します。

    インストール後にコンフィグの mkswu.conf と鍵の swupdate.* をなくさないようにしてください。

    [ティップ]

    このイメージに他の変更も入れれます。他の /usr/share/mkswu/examples/ ディレクトリーにある.descファイルや「mkswu の desc ファイル」を参考にして、以下の例のように同じswuにいくつかの.descを組み込めます。

    例えば、opensshを有効にします。

    [ATDE ~/mkswu]$ cp -rv /usr/share/mkswu/examples/enable_sshd* .
    : (省略)
    '/usr/share/mkswu/examples/enable_sshd/root/.ssh/authorized_keys'
        -> './enable_sshd/root/.ssh/authorized_keys'
    '/usr/share/mkswu/examples/enable_sshd.desc' -> './enable_sshd.desc'
    [ATDE ~/mkswu]$ cp ~/.ssh/id_rsa.pub \
                     enable_sshd/root/.ssh/authorized_keys
    [ATDE ~/mkswu]$ mkswu initial_setup.desc enable_sshd.desc
    enable_sshd.desc を組み込みました。
    initial_setup.swu を作成しました。
  2. イメージのインストール

    「イメージのインストール」を参考に、作成したイメージをインストールしてください。

  3. 次回以降のアップデート

    次回以降のアップデートは作成した証明鍵を使用してArmadillo-IoT ゲートウェイ G4 のSWUイメージを作成します。

    .desc ファイルの内容は /usr/share/mkswu/examples/ のディレクトリや「mkswu の desc ファイル」を参考にしてください。

9.7.3. イメージのインストール

イメージをインストールする方法として下記に示すような方法があります。

  • USBメモリまたはSDカードからの自動インストール

    Armadillo-IoT ゲートウェイ G4にUSBメモリを接続すると自動的にアップデートが始まります。 アップデート終了後にArmadillo-IoT ゲートウェイ G4は自動で再起動します。

    USBメモリやSDカードをvfatもしくはext4形式でフォーマットし、作成した.swuのファイルをディレクトリを作らずに配置してください。

    [ティップ]

    ATDE上でUSBメモリ/microSDカードのパーティションを作成・フォーマットする方法

    https://armadillo.atmark-techno.com/howto/atde-partition-howto

    [ATDE ~/mkswu]$ df -h
    Filesystem           Size  Used Avail Use% Mounted on
    : (省略)
    /dev/sda1        15G  5.6G  9.1G  39% /media/USBDRIVE 1
    [ATDE ~/mkswu]$ cp initial_setup.swu /media/USBDRIVE/ 2
    [ATDE ~/mkswu]$ umount /media/USBDRIVE 3

    1

    USBメモリのマウントされている場所を確認します。

    2

    ファイルをコピーします。

    3

    /media/USBDRIVEをアンマウントします。コマンド終了後にUSBメモリを取り外してください。

    エラーの場合、/var/log/messageに保存されます。例えば、コンソールで証明の間違ったイメージのエラーを表示します:

    [armadillo ~]# tail /var/log/messages
    Nov 19 10:48:42 user.notice swupdate-auto-update: Mounting sda0 on /mnt
    Nov 19 10:48:42 user.notice swupdate-auto-update: Trying update /mnt/initial_setup.swu
    Nov 19 10:48:42 user.info swupdate: START Software Update started !
    Nov 19 10:48:42 user.err swupdate: FAILURE ERROR : Signature verification failed 1
    Nov 19 10:48:42 user.err swupdate: FAILURE ERROR : Compatible SW not found
    Nov 19 10:48:42 user.err swupdate: FATAL_FAILURE Image invalid or corrupted. Not installing ...

    1

    証明が間違ったメッセージ。

  • 外部記憶装置からイメージのインストール(手動)

    USBメモリやmicroSDカード等の外部記憶装置のルートディレクトリ以外にswuイメージを保存して、イメージのインストールを行います。 ルートディレクトリに保存すると自動アップデートが行われますので、/var/log/messagesを確認してください。

    以下は外部記憶装置が/dev/mmcblk1p1(microSDカード)として認識された場合に、イメージのインストールを行う例です。

    [armadillo ~]# mount /dev/mmcblk1p1 /mnt
    [armadillo ~]# swupdate -i /mnt/swu/initial_setup.swu
    [INFO ] : SWUPDATE started :  Software Update started !
    [INFO ] : SWUPDATE running :  Installation in progress
    : (省略)
    [ERROR] : SWUPDATE failed [0] ERROR : swupdate triggering reboot! 1
    [INFO ] : SWUPDATE successful ! SWUPDATE successful !
  • ウェブサーバーからイメージのインストール(手動)

    swuイメージをウェブサーバーにアップロードして、イメージのインストールを行います。 以下は、http://server/initial_setup.swu のイメージをインストールする例です。

[armadillo ~]# swupdate -d '-u http://server/initial_setup.swu'
[INFO ] : SWUPDATE started :  Software Update started !
[INFO ] : SWUPDATE running :  Installation in progress
: (省略)
[ERROR] : SWUPDATE failed [0] ERROR : swupdate triggering reboot! 1
[INFO ] : SWUPDATE successful ! SWUPDATE successful !

1 1

はエラーとして赤で表示されますが、見やすくするためでエラーではありません。

  • ウェブサーバーからの定期的な自動インストール

    swupdate-urlを有効にしたら、定期的にチェックしてインストールします。 以下はサービスの有効化とタイミングの設定の例です。

    [armadillo ~]# rc-update add swupdate-url 1
    [armadillo ~]# persist_file /etc/runlevels/default/swupdate-url 2
    [armadillo ~]#
        echo https://download.atmark-techno.com/armadillo-iot-g4/image/baseos-x2-latest.swu \
                            > /etc/swupdate.watch 3
    [armadillo ~]# echo 'schedule="0 tomorrow"' > /etc/conf.d/swupdate-url
    [armadillo ~]# echo 'rdelay="21600"' >> /etc/conf.d/swupdate-url 4
    [armadillo ~]# persist_file /etc/swupdate.watch /etc/conf.d/swupdate-url 5

    1

    swupdate-urlサービスを有効します。

    2

    サービスの有効化を保存します。

    3

    イメージのURLを登録します。一行ごとにイメージのURLを設定することができ、複数行にイメージのURLを設定することができます。

    4

    チェックやインストールのスケジュールを設定します。

    5

    変更した設定ファイルを保存します。

    USBメモリからのアップデートと同様に、ログは/var/log/messagesに保存されます。

    [ティップ]

    initial_setupのイメージを作成の際に /usr/share/mkswu/examples/enable_swupdate_url.desc を入れると有効にすることができます。

  • hawkBit を使用した自動インストール

    hawkBit で Armadillo-IoT ゲートウェイ G4 を複数台管理してアップデートすることができます。 以下の「hawkBitサーバーから複数のArmadilloに配信する」を参考にしてください。

9.7.4. hawkBitサーバーから複数のArmadilloに配信する

hawkBitサーバーを利用することで複数のArmadillo のソフトウェアをまとめてアップデートすることができます。

手順は次のとおりです。

  1. コンテナ環境の準備

    Dockerを利用すると簡単にサーバーを準備できます。 Dockerの準備については https://docs.docker.com/get-docker/ を参照してください。

    Dockerの準備ができたら、要件に合わせてコンテナの設定を行います。

    • ATDE の場合

    • ATDE以外の場合

      • Armadillo-IoT ゲートウェイ G4 開発用ツール から 「Hawkbit docker-composeコンテナ」 をダウンロードして展開してください。 この場合、以下に /usr/share/mkswu/hawkbit-compose を使う際に展開先のディレクトリとして扱ってください。
      • dockerがアクセスできるホストネームやアドレスを控えておいてください。
  2. hawkBitサーバーの準備

    /usr/share/mkswu/hawkbit-compose/setup_container.sh を実行して、質問に答えてください。

    以下に簡単な(TLSを有効にしない)テスト用の場合と、 TLSを有効にした場合の例を参考にしてください。

    setup_container.sh を一度実行した場合はデータのディレクトリーにある setup_container.sh のリンクを実行して、ユーザーの追加等のオプション変更を行うこともできます。 --help を参考にしてください。

    [ATDE ~]$ /usr/share/mkswu/hawkbit-compose/setup_container.sh
    docker-compose の設定ファイルと hawkBit のデータをどこに保存しますか? [/home/atmark/hawkbit-compose] 1
    setup_container.sh へのリンクを /home/atmark/hawkbit-compose に作ります。
    docker サービスに接続できませんでした。sudo でもう一度試します。
    [sudo] atmark のパスワード: 2
    OK!
    Hawkbit admin user name [admin] 3
    admin ユーザーのパスワード:  4
    パスワードを再入力してください:
    追加の管理人アカウントのユーザーネーム(空にすると追加しません) 5
    hawkBit の「device」ユーザーを登録しますか?(自動登録用) [Y/n]  6
    device ユーザーのパスワード:
    パスワードを再入力してください:
    hawkBit の「mkswu」ユーザーを登録しますか?(swuのアップロード用) [Y/n] 7
    ユーザーにロールアウトの権限を与えますか?(インストール要求を出すこと) [Y/n] 8
    mkswu ユーザーのパスワード:
    パスワードを再入力してください:
    Setup TLS reverse proxy? [y/N] 9
    
    コンテナの設定が完了しました。docker-compose コマンドでコンテナの管理が可能です。
    /home/atmark/hawkbit-compose/setup_container.sh を再び実行すると設定の変更が可能です。
    hawkBit コンテナを起動しますか? [Y/n] 10
    Creating network "hawkbit-compose_default" with the default driver
    Pulling mysql (mysql:5.7)...
    : (省略)
    Creating hawkbit-compose_hawkbit_1 ... done
    Creating hawkbit-compose_mysql_1   ... done

    図9.138 hawkBit コンテナの一番簡単な設定(テスト用)の実行例


    1

    コンテナのコンフィグレーションとデータベースの場所を設定します。

    2

    dockerの設定によってsudoが必要な場合もあります

    3

    hawkBit の Web UI のログインを admin とデフォルトにします。

    4

    そのパスワードを二回入力します。

    5

    追加のユーザーが必要な場合に追加できます。

    6

    examples/hawkbit_register.desc で armadillo を登録する場合に作っておいてください。 詳細は 「SWU で hawkBit を登録する」 を参考にしてください。

    7

    hawkbit_push_update でアップデートを CLI で扱う場合に作っておいてくダサい。 詳細は <sct.hawkbit_push_update>> を参照してください。

    8

    さらに、hawkbit_push_update でアップデートを実行までする場合は、この権限を許可してください。

    9

    ここでは http でテストのコンテナを作成するので、「N」のままで進みます。

    10

    コンテナを起動します。初期化が終わったら <IP>:8080 でアクセス可能になります。

    [ATDE ~]$ /usr/share/mkswu/hawkbit-compose/setup_container.sh
    docker-compose の設定ファイルと hawkBit のデータをどこに保存しますか? [/home/atmark/hawkbit-compose]
    setup_container.sh へのリンクを /home/atmark/hawkbit-compose に作ります。
    docker サービスに接続できませんでした。sudo でもう一度試します。
    OK!
    Hawkbit admin user name [admin]
    admin ユーザーのパスワード:
    パスワードを再入力してください:
    パスワードが一致しません。
    admin ユーザーのパスワード:
    パスワードを再入力してください:
    追加の管理人アカウントのユーザーネーム(空にすると追加しません)
    hawkBit の「device」ユーザーを登録しますか?(自動登録用) [Y/n]
    device ユーザーのパスワード:
    パスワードを再入力してください:
    hawkBit の「mkswu」ユーザーを登録しますか?(swuのアップロード用) [Y/n]
    ユーザーにロールアウトの権限を与えますか?(インストール要求を出すこと) [Y/n]
    mkswu ユーザーのパスワード:
    パスワードを再入力してください:
    Setup TLS reverse proxy? [y/N] y 1
    lighttpd が起動中で、リバースプロキシ設定と競合しています。
    lighthttpd サービスを停止しますか? [Y/n] 2
    Synchronizing state of lighttpd.service with SysV service script with /lib/systemd/systemd-sysv-install.
    Executing: /lib/systemd/systemd-sysv-install disable lighttpd
    Removed /etc/systemd/system/multi-user.target.wants/lighttpd.service.
    リバースプロキシの設定に証明書の domain name が必要です。
    この domain はこのままデバイスからアクセスできる名前にしてください。
    例えば、https://hawkbit.domain.tld でアクセスしたら hawkbit.domain.tld、
    https://10.1.1.1 でしたら 10.1.1.1 にしてください。
    証明書の domain name: 10.1.1.1 3
    証明書の有効期限を指定する必要があります。Let's encryptを使用する場合、
    この値は新しい証明書が生成されるまでしか使用されないので、デフォルトの値
    のままにしておくことができます。Let's encryptを使用しない場合、
    数年ごとに証明書を新しくすることが最も好ましです。
    証明書の有効期間は何日間にしますか? [3650] 4
    クライアントのTLS認証を設定するためにCAが必要です。
    署名CAのファイルパス(空にするとクライアントTLS認証を無効になります) [] 5
    サーバーが直接インタネットにアクセス可能であれば、Let's Encryptの証明書
    を設定することができます。TOSへの同意を意味します。
    https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
    certbotコンテナを設定しますか? [y/N] 6
    
    /home/atmark/hawkbit-compose/data/nginx_certs/proxy.crt を /usr/local/share/ca-certificates/ にコピーして、 update-ca-certificates を実行する必要があります。
    このbase64でエンコードされたコピーをexamples/hawkbit_register.sh の
    SSL_CA_BASE64 に指定する手順が推奨されます。
    
    LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlekNDQVNHZ0F3SUJBZ0lVQTByZ0cwcTJF
    SFNnampmb0tUZWg3aGlaSVVVd0NnWUlLb1pJemowRUF3SXcKRXpFUk1BOEdBMVVFQXd3SU1UQXVN
    UzR4TGpFd0hoY05Nakl3TXpJMU1EVXhOVFU0V2hjTk16SXdNekl5TURVeApOVFU0V2pBVE1SRXdE
    d1lEVlFRRERBZ3hNQzR4TGpFdU1UQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFC
    SDFFREhBN3NOTlFJUDlTdlhlUnNmWjl2dVVFWkRkMVE2TzViRlV2RTh4UjUwUlBCLzNlajMzd0VI
    NEoKYmZqb296bEpXaExlSG5SbGZsaHExVDlKdm5TalV6QlJNQjBHQTFVZERnUVdCQlFBUmYvSkdT
    dkVJek5xZ2JMNQpQamY2VGRpSk1EQWZCZ05WSFNNRUdEQVdnQlFBUmYvSkdTdkVJek5xZ2JMNVBq
    ZjZUZGlKTURBUEJnTlZIUk1CCkFmOEVCVEFEQVFIL01Bb0dDQ3FHU000OUJBTUNBMGdBTUVVQ0lD
    Nis3ZzJlZk1SRXl0RVk5WDhDNC8vUEw1U1kKWUlGZHUxVFZiUEZrSlV0SUFpRUE4bm1VSnVQSFlz
    SHg2N2ErZFRwSXZ1QmJUSG1KbWd6dUl3bTJ2RXppRnZRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0t
    LS0tCg== 7
    
    
    Let's encryptの設定は後で足したい場合にsetup_container.shを--letsencryptで実行してください。
    
    コンテナの設定が完了しました。docker-compose コマンドでコンテナの管理が可能です。
    /home/atmark/hawkbit-compose/setup_container.sh を再び実行すると設定の変更が可能です。
    hawkBit コンテナを起動しますか? [Y/n]

    図9.139 hawkBit コンテナのTLSありの場合の実行例


    1

    今回は TLS を有効にしますので、「y」を答えます。

    2

    lighttpd サービスが起動している場合に聞かれます。不要なので、停止します。

    3

    証明書の common name を入力してください。ATDE の場合、 ポート転送によってホストのIPアドレスで接続しますのでそのアドレスを入力します。 Let’s encrypt を使用する場合には外部からアクセス可能なDNSを入力してください。

    4

    証明書の有効期間を設定します。デフォルトでは10年になっています。 Let’s encryptを使用する場合には使われていません。

    5

    クライアント側では x509 証明書で認証をとることができますが、この例では使用しません。

    6

    Let’s encrypt による証明書を作成できます。 ATDE の場合は外部からのアクセスが難しいので、この例では使用しません。

    7

    自己署名証明書を作成したので、 Armadillo に設置する必要があります。 この証明書の取扱いには 「SWU で hawkBit を登録する」 を参照してください。

  3. hawkBitへのログイン

    作成したコンテナによって http://<サーバーのIPアドレス>:8080https://<サーバーのアドレス> にアクセスすると、ログイン画面が表示されます。

    images/hawkBit_login.png

    デフォルトでは次のアカウントでログインできます。

    ユーザー

    admin

    パスワード

    admin

  4. ArmadilloをTargetに登録する

    左側のメニューから Deployment をクリックして、Deployment の画面に移ります。

    images/hawkBit_security_token.png

    "+"をクリックしてTargetを作成します。

    作成したターゲットをクリックすると、 下のペインに "Security token:<文字列>" と表示されるので、 <文字列>の部分をメモします。

    メモした<文字列>をArmadilloの /etc/swupdate.cfg に設定すると Hawkbit への接続認証が通るようになります。

  5. Target Filterを作成する

    左側のメニューから"Target Filters"をクリックして、Target Filters の画面に移ります。

    images/hawkBit_Target_filters.png

    "+" をクリックして新規にTarget Filterを作成します。

    images/hawkBit_Target_filters_new.png

    Filter name と 検索式を入力して保存します。

  6. Software moduleを作成する

    左側のメニューから"Upload"をクリックして、Upload Managementの画面に移ります。

    images/hawkBit_software_module.png

    "+" をクリックしてSoftware moduleを作成します。 type には OS/Application、 version には 任意の文字列を指定します。

  7. swuパッケージをアップロードしてSoftware moduleに関連付ける

    先程作成した Software module を選択して、ハイライトされた状態で、 "Upload File"ボタン、もしくは、ファイルをドラッグアンドドロップします。

    images/hawkBit_software_module_result.png
  8. Distributionを作成してSoftware moduleを関連付ける

    左側のメニューから"Distribution"をクリックして、Distribution Managementの画面に移ります。

    images/hawkBit_distribution.png

    "+" をクリックしてDistributionを作成します。 type には OS/OSwithApp/Apps、 version には任意の文字列を指定します。

    images/hawkBit_distribution_new.png

    "Software module"のペインから先程作成した Softwareをドラッグして、作成したDistributionの上にドロップします。

    images/hawkBit_Distribution_assignment.png
  9. Rolloutを作成してアップデートを開始する

    左側のメニューから"Rollout"をクリックして、Rollout Managementの画面に移ります。

    images/hawkBit_Rollouts.png

    "+"をクリックしてRolloutを作成します。

    images/hawkBit_Rollouts_new.png

    項目

    説明

    Name

    任意の文字列を設定します。

    Distribution Set

    先程作成したDistributionを選択します。

    Custom Target Filter

    先程作成したTarget Filterを選択します。

    Action Type

    アップデート処理をどのように行うかを設定します。 ・Forced/Soft: 通常のアップデート ・Time Forced: 指定した時刻までにアップデートする ・Download only: ダウンロードのみ行う

    Start Type

    Rollout の実行をどのように始めるかを設定します。 ・Manual: 後で手動で開始する ・Auto: Targetからのハートビートで開始する ・Scheduled: 決まった時間から開始する

  10. アップデートの状態を確認する。

    Rollout Managementの画面のDetail Statusで、各Rolloutのアップデートの状態を確認できます。

    アップデート中は黄色、アップデートが正常に完了すると緑色になります。

9.7.4.1. hawkBit のアップデート管理を CLI で行う

一つのアップデートを登録するには、hawkBit の Web UI で必要な手順が長いので CLI で行うことで 効率よく実行できます。

サーバーの設定の段階では、「mkswu」のユーザーを作成する必要があります。 作成していない場合は setup_container.sh --add-user mkswu で作成してください。

  1. hawkbit_push_update の実行例です
[ATDE ~/mkswu]$ ls enable_sshd.swu 1
enable_sshd.swu

[ATDE ~/mkswu]$ hawkbit_push_update --help
Usage: /usr/bin/hawkbit_push_update [options] file.swu

rollout creation:
  --no-rollout: only upload the file without creating a rollout 2
  --new: create new rollout even if there already is an existing one 3
  --failed: Apply rollout only to nodes that previously failed update 4

post action:
  --start: start rollout immediately after creation 5

[ATDE ~/mkswu]$ hawkbit_push_update --start enable_sshd.swu 6
Uploaded (or checked) image extra_os.sshd 1 successfully
Created rollout extra_os.sshd 1 successfully
Started extra_os.sshd 1 successfully

1

この例ではあらかじめ作成されてる enable_sshd.swu を hawkBit に登録します。

2

--no-rollout を使う場合に SWU を「distribution」として登録します。 デフォルトでは rollout も作成します。 テストする際、デバイスがまだ登録されていなければ rollout の段階で失敗します。

3

同じ SWU で rollout を二回作成した場合にエラーが出ます。 もう一度作りたい場合は --new を使ってください。

4

一度 rollout をスタートして、 Armadillo で失敗した場合には 失敗したデバイスだけに対応した rollout を作れます。

5

作成した rollout をすぐ実行します。このオプションには追加の権限を許可する必要があります。

6

スタートまで行う実行例です。実行結果は Web UI で表示されます。

9.7.4.2. SWU で hawkBit を登録する

デバイスが多い場合は、SWUを一度作って armadillo を自己登録させることができます。

サーバーの設定の段階では、「device」のユーザーを作成する必要があります。 作成していない場合は setup_container.sh --add-user device で作成してください。

  1. hawkbit_register.desc で hawkBit の自己登録を行う例
[ATDE ~]$ cd mkswu/

[ATDE ~/mkswu]$ cp /usr/share/mkswu/examples/hawkbit_register.* . 1

[ATDE ~/mkswu]$ vi hawkbit_register.sh 2
# Script configuration: edit this if required!
# user given here must have CREATE_TARGET,READ_TARGET_SECURITY_TOKEN permissions
HAWKBIT_USER=device
HAWKBIT_PASSWORD="CS=wC,zJmrQeeKT.3" 3
HAWKBIT_URL=https://10.1.1.1 4
HAWKBIT_TENANT=default
# set custom options for suricatta block or in general in the config
CUSTOM_SWUPDATE_SURICATTA_CFG="" # e.g. "polldelay = 86400;"
CUSTOM_SWUPDATE_CFG=""
# set to non-empty if server certificate is invalid
SSL_NO_CHECK_CERT=
# or set to cafile that must have been updated first
SSL_CAFILE=
# ... or paste here base64 encoded crt content
SSL_CA_BASE64="
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlakNDQVNHZ0F3SUJBZ0lVYTMvYXpNSHZ0
bFFnaFZnZDhIZWhMaEwxNm5Bd0NnWUlLb1pJemowRUF3SXcKRXpFUk1BOEdBMVVFQXd3SU1UQXVN
UzR4TGpFd0hoY05Nakl3TWpFNE1EVTFNakV6V2hjTk16SXdNakUyTURVMQpNakV6V2pBVE1SRXdE
d1lEVlFRRERBZ3hNQzR4TGpFdU1UQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFC
RFJGcnJVV3hHNnBHdWVoejRkRzVqYkVWTm5scHUwYXBHT1c3UVBPYUF4cWp1ZzJWYjk2UHNScWJY
Sk8KbEFDVVo2OStaMHk3clBqeDJHYnhDNms0czFHalV6QlJNQjBHQTFVZERnUVdCQlJtZzhxL2FV
OURRc3EvTGE1TgpaWFdkTHROUmNEQWZCZ05WSFNNRUdEQVdnQlJtZzhxL2FVOURRc3EvTGE1TlpY
V2RMdE5SY0RBUEJnTlZIUk1CCkFmOEVCVEFEQVFIL01Bb0dDQ3FHU000OUJBTUNBMGNBTUVRQ0lB
ZTRCQ0xKREpWZnFTQVdRcVBqNTFmMjJvQkYKRmVBbVlGY2VBMU45dE8rN0FpQXVvUEV1VGFxWjhH
UFYyRUg1UWdOMFRKS05SckJDOEtpNkZWcFlkRUowYWc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0t
LS0tCg== 5
"
# ... or add your own options if required
CURLOPT=-s

: (省略)

[ATDE ~/mkswu]$ cat hawkbit_register.desc 6
: (省略)
swdesc_script hawkbit_register.sh --version extra_os.hawkbit 1

[ATDE ~/mkswu]$ mkswu hawkbit_register.desc 7
hawkbit_register.swu を作成しました。

[ATDE ~/mkswu]$ mkswu initial_setup.desc hawkbit_register.desc 8
hawkbit_register.desc を組み込みました。
initial_setup.swu を作成しました。

1

hawkbit_register.sh と .desc ファイルをカレントディレクトリにコピーします。

2

hawkbit_register.sh を編集して、設定を記載します。

3

hawkBit の設定の時に選んだ「device」ユーザーのパスワードを入力します。この例のパスワードは使用しないでください。

4

hawkBit サーバーのURLを入力します。

5

TLS を使用の場合に、コンテナ作成の時の証明書を base64 で入力します。

6

hawkbit_register.desc の中身を確認します。hawkbit_register.sh を実行するだけです。

7

SWU を作成して、initial_setupがすでにインストール済みの Armadillo にインストールできます。

8

または、initial_setup.desc と合わせて hawkbit_register を含んだ initial_setup.swu を作成します。

9.7.5. mkswu の desc ファイル

.desc ファイルを編集して、いくつかのコマンドが使えます。

[ATDE ~/mkswu]$ tree /usr/share/mkswu/examples/nginx_start
/usr/share/mkswu/examples/nginx_start
└── etc
    └── atmark
        └── containers
            └── nginx.conf

[ATDE ~/mkswu]$ cat /usr/share/mkswu/examples/usb_container_nginx.desc
swdesc_option version=1

swdesc_usb_container "nginx_alpine.tar" 1
swdesc_files --extra-os "nginx_start" 2

1

nginx_alpine.tar ファイルに保存されたコンテナをインストールします。

2

nginx_start ディレクトリーの中身を転送します。

コマンドは書かれた順番でインストールします。インストールするかどうかの判断はバージョンで行います:

swdesc_option component=<component>
swdesc_option version=<version>
か
swdesc_xxx --version <component> <version> [options]
  • <component>は以下のどれかにしてください (デフォルトでは .desc ファイルのファイル名を使います)

    1. base_os: rootfs (Armadillo Base OS)を最初から書き込む時に使います。現在のファイルシステムは保存されていない。

      この場合、/etc/swupdate_preserve_filesに載ってるファイルのみをコピーして新しいbase OSを展開します。

      このcomponentがないと現在のrootfsのすべてがコピーされます。

    2. extra_os.<文字列>: rootfsの変更を行う時に使います。<文字列> には任意の文字列を指定します。

      rootfsを変更を行う時に使います。 swdesc_* コマンドに --extra-os オプションを追加すると、 component に自動的に extra_os. を足します。

    3. <文字列> (コンテナの名前などの任意の文字列): rootfsの変更がないときに使います。

      このcomponentを使うとrootfsの変更ができませんのでご注意ください。

  • アップデートをインストールする際にこのバージョンと現在のバージョンを比べてアップデートの判断します。

    <component> がまだインストールされてなかった時か <version> が上がる時にインストールします。

    デフォルトではダウングレードはできませんが、 --install-if=different オプションを追加することで <version> が変わる際にインストール可能になります。

    アップデートの一部をインストールすることもありますので、複数の component で管理し、いくつかの古いバージョンに対応するアップデートも作成可能です。

以下のコマンドから使ってください

  • swdesc_tarswdesc_files でファイルを転送します。

    swdesc_tar [--dest <dest>] <tar_file>
    swdesc_files [--dest <dest>] [--basedir <basedir>] \
                 <file> [<more files>]

    swdesc_tar の場合、予め用意されてあるtarアーカイブをこのままデバイスで展開します。

    --dest <dest> で展開先を選ぶことができます。デフォルトは /--extra-os を含め、バージョンの component は base_osextra_os.* の場合)か /var/app/rollback/volumes/ (それ以外のcomponent)。 後者の場合は /var/app/volumes/var/app/rollback/volumes 以外は書けないので必要な場合に --extra-os を使ってください。

    swdesc_files の場合、mkswu がアーカイブを作ってくれますが同じ仕組みです。

    --basedir <basedir> でアーカイブ内のパスをどこで切るかを決めます。

    • 例えば、swdesc_files --extra-os --basedir /dir /dir/subdir/file ではデバイスに /subdir/file を作成します。
    • デフォルトは <file> から設定されます。ディレクトリであればそのまま basedir として使います。それ以外であれば親ディレクトリを使います。
  • swdesc_commandswdesc_script でコマンドを実行する

    swdesc_command <command> [<more commands>]
    swdesc_script <script>

    アップデート先の環境でコマンドやスクリプトファイルを走らせます。

    バージョンの component は base_osextra_os 以外の場合、 /var/app/volumes/var/app/rollback/volumes 以外何も変更できないのでご注意ください。

    コマンドが成功しないとアップデートが失敗します。

  • swdesc_exec でファイルを配ってコマンドでそのファイルを使う

    swdesc_exec <file> <command>

    swdesc_command と同じくコマンドを走らせますが、<file> を先に転送してコマンド内で"$1"として使えます。

  • swdesc_command_nochroot, swdesc_script_nochroot, swdesc_exec_nochroot で起動中のシステム上でコマンドを実行します。

    このコマンドは nochroot なしのバージョンと同じ使い方で、現在起動中のシステムに変更や確認が必要な場合にのみ使用してください。

    [警告]

    nochroot コマンドは確認を一切しないため、Armadillo が起動できない状態になる可能性もあります:充分にご注意ください。

    例が必要な場合は /usr/share/mkswu/examples/firmware_update.desc を参考にしてください。

  • swdesc_embed_container, swdesc_usb_container, swdesc_pull_container で予め作成したコンテナを転送します。

    swdesc_embed_container <container_archive>
    swdesc_usb_container <container_archive>
    swdesc_pull_container <container_url>

    例は「コンテナの配布」を参考にしてください。

  • swdesc_bootimx-boot を更新します。

    swdesc_boot <boot image>

    このコマンドだけにバージョンは自動的に設定されます。

コマンドの他には、設定変数もあります。以下の設定は /home/atmark/mkswu/mkswu.conf に設定できます。

  • DESCRIPTION="<text>": 自由なイメージの説明、ログに残ります。
  • PRIVKEY=<path>, PUBKEY=<path>: 署名鍵と証明書
  • PRIVKEY_PASS=<val>: 鍵のパスワード(自動用)

    openssl のPass Phraseをそのまま使いますので、pass:password, env:varfile:pathname のどれかを使えます。 passenv の場合他のプロセスに見られる恐れがありますのでfileをおすすめします。

  • ENCRYPT_KEYFILE=<path>: 暗号化の鍵

以下のオプションも mkswu.conf に設定できますが、.descファイルにも設定可能です。swdesc_option で指定することで、 誤った使い方した場合 mkswu の段階でエラーを出力しますので、必要な場合は使用してください。

  • swdesc_option CONTAINER_CLEAR: インストールされたあるコンテナと /etc/atmark/containers/*.conf をすべて削除します。

    このオプションは簡単な初期化と考えてください。通常の運用では、不要になったイメージは自動的に削除されますので このオプションを設定する必要はありません。

以下のオプションは Armadillo 上の /etc/atmark/baseos.conf に、例えば MKSWU_POST_ACTION=xxx として設定することができます。

その場合に swu に設定されなければ /etc の設定で実行されますので、 アットマークテクノが用意している Base OS のアップデートでも動作の変更は可能です。 swu に特定なオプションが設定された場合に設定されたオプションが優先されますので一時的な変更も可能です。

  • swdesc_option POST_ACTION=container: コンテナのみのアップデート後に再起動を行いません。 コンテナの中身だけをアップデートする場合、Armadillo-IoT ゲートウェイ G4を再起動せずにコンテナだけを再起動させます。
  • swdesc_option POST_ACTION=poweroff: アップデート後にシャットダウンを行います。
  • swdesc_option POST_ACTION=wait: アップデート後に自動的に再起動は行われず、次回起動時にアップデートが適用されます。
  • swdesc_option POST_ACTION=reboot: デフォルトの状態に戻します。アップデートの後に再起動します。
  • swdesc_option NOTIFY_STARTING_CMD="command", swdesc_option NOTIFY_SUCCESS_CMD="command", swdesc_option NOTIFY_FAIL_CMD="command": アップデートをインストール中、成功した場合と失敗した場合に実行されるコマンドです。

    コマンドを実行する事で、アプリケーションやユーザーにアップデートを知らせることができます。

    LEDで知らせる例を /usr/share/mkswu/examples/enable_notify_led.desc に用意してあります。

9.7.5.1. swupdate_preserve_files について

extra_os のアップデートで rootfs にファイルを配置することができますが、次の OS アップデートの際に削除される可能性があります。

デフォルトでは、 /etc/atmark と、 swupdatesshd やネットワークの設定を保存しますがそれ以外はコピーされてません。

そうでないファイルを更新する際には /etc/swupdate_preserve_files に記載します。「例: swupdate_preserve_files で Linux カーネル以外の Armadillo-IoT ゲートウェイ G4 向けのイメージをインストールする方法」 を参考にしてください。

コピーのタイミングによって、以下のどれかを使ってください:

  1. 単にファイルを記載する。

    この場合、アップデートする前にファイルをコピーします。 baseos のイメージと同じ swu にアップデートしたいファイルを記載していても、 このファイルが Armadillo Base OS に含まれないのであれば問題なくアップデートできます。

    : echo "/root/.profile" >> /etc/swupdate_preserve_files

  2. POST のキーワードの後に記載する。

    この場合、アップデートの最後でコピーします。 Armadillo Base OS に含まれてるファイルであれば、インストール前にコピーしても保存されないのでコピーのタイミングをずらします。

    そのコピーが最後に行われるので、同じアップデートでファイルの変更ができません。アップデートを別けて、 baseos のイメージをインストールしてからこのファイルを更新することができます。

    : echo "POST /etc/conf.d/podman-atmark" >> /etc/swupdate_preserve_files

9.7.5.2. 例: sshdを有効にする

/usr/share/mkswu/examples/enable_sshd.desc を参考にします。

descファイルを編集する必要がありませんが自分の公開鍵を指定された場所に配置してください。

[ATDE ~/mkswu]$ cp -r /usr/share/mkswu/examples/enable_sshd* .
[ATDE ~/mkswu]$ cat enable_sshd.desc
swdesc_option component=extra_os.sshd version=1

# add your public key in enable_sshd/root/.ssh/authorized_keys
if [ -z "$SWDESC_TEST" ]; then
    grep -qE '^ssh-' enable_sshd/root/.ssh/authorized_keys \
        || error "Add your keys in enable_sshd/root/.ssh/authorized_keys"
fi
swdesc_files --dest /root enable_sshd/root 1

swdesc_command "ssh-keygen -A" \ 2
        "rc-update add sshd" 3
[ATDE ~/mkswu]$ cp ~/.ssh/id_rsa.pub \
                         enable_sshd/root/.ssh/authorized_keys 4
[ATDE ~/mkswu]$ mkswu enable_sshd.desc 5
Enter pass phrase for /home/atmark/mkswu/swupdate.key:
enable_sshd.swu を作成しました。

1

自分の公開鍵を転送します。デフォルトのオプションなので enable_sshd/root ディレクトリの中身をこのまま /root に転送されます。

2

再起動する度に新しいサーバーの鍵が変わらないように、アップデートの時に一回作成します。

3

サービスを有効にします。

4

自分の公開鍵を指定された場所に配置します。

5

イメージを作成します。パスワードは証明鍵のパスワードです。

9.7.5.3. 例: Armadillo Base OSアップデート

ここでは、「Armadilloのソフトウェアをビルドする」でメインシステム向けのビルドで作成したファイルを使用します。

/usr/share/mkswu/examples/OS_update.desc を参考にします。

[ATDE ~/mkswu]$ cp /usr/share/mkswu/examples/OS_update.desc update-[VERSION].desc
[ATDE ~/mkswu]$ vi update-[VERSION].desc
# uboot image can be generated with atmark imx-boot script
swdesc_uboot imx-boot_armadillo_x2 1

# base OS is a tar that will be extracted on a blank filesystem,
# after copying just a few key config files.
#
# OS updates are only installed if version is greater than previous update
# so if you install your own updates atmark-techno provided Armadillo Base OS
# updates might not get installed
swdesc_tar "baseos-x2-[VERSION].tar.zst" \ 2
           --version base_os [VERSION] 3
[ATDE ~/mkswu]$ mkswu update-[VERSION].desc 4
Enter pass phrase for /home/atmark/mkswu/swupdate.key:
update-[VERSION].swu を作成しました。

1

imx-bootでビルドしたイメージを使います。

2

build-rootfsでビルドしたイメージを使います。

3

バージョンを上がるときにしかインストールされませんので、現在の/etc/sw-versionsを見て上がるように設定してください。

4

イメージを作成します。パスワードは証明鍵の時のパスワードです。

9.7.5.4. 例: swupdate_preserve_files で Linux カーネル以外の Armadillo-IoT ゲートウェイ G4 向けのイメージをインストールする方法

Armadillo-IoT ゲートウェイ G4 向けのアップデートイメージに Linux カーネルが含まれています。

swupdate_preserve_files を使って、以下のコマンドでインストール後に現在のカーネルをコピーして更新させないようにします。

[armadillo ~]# echo 'POST /boot' >> /etc/swupdate_preserve_files
[armadillo ~]# echo 'POST /lib/modules' >> /etc/swupdate_preserve_files 1
[armadillo ~]# persist_file /etc/swupdate_preserve_files 2

1

swupdate_preserve_files/boot/lib/modules を保存するように追加します。

2

変更した設定ファイルを保存します

[ティップ]

/usr/share/mkswu/examples/update_kernel*.desc を使うと、このパスを自動的に /etc/swupdate_preserve_files に追加します:

swdesc_script update_preserve_files.sh -- \
        "POST /boot" \
        "POST /lib/modules"

9.7.6. SWUpdate と暗号化について

mkswu --init の時に暗号化を有効にする場合は AES でファイルを暗号化します。

現在使われてる SWUpdate の暗号化はコマンドやメタデータを含む sw-description ファイルは暗号化されてません。 そのため、通信の暗号化(HTTPSで送信するなど)を使うことを推奨します。

9.8. Armadillo Base OS の操作

Armadillo Base OS は Alpine OS をベースとして作られています。

このセクションでは Armadillo Base OS の機能を紹介します。

9.8.1. アップデート

Armadillo Base OS は SWUpdate によってアップデートすることができます。

アップデートする際には、rootfs ファイルシステムにインストールされたファイルをすべて消して、アップデートの中身と /etc/swupdate_preserve_files に記載されているファイルで新しい rootfs を作ります。「swupdate_preserve_files について」 を参照してください。

アップデートでファイルを削除してしまった場合に abos-ctrl mount-old で前のシステムを read-only でマウントして、 削除されたファイルをコピーすることもできます。

9.8.2. overlayfs と persist_file について

Armadillo BaseOS ではルートファイルシステムに overlayfs を採用しています。

そのため、ファイルを変更した後 Armadillo の電源を切ると変更内容は保持されません。 開発中などに rootfs の変更内容を保持するには、変更したファイルに対して persist_file コマンドを使用します。

開発以外の時は安全のため、ソフトウェアアップデートによる更新を実行してください。 アップデート手順に関しては 「Armadilloのソフトウェアをアップデートする」 を参照してください。

rootfs の内容を変更しても、ソフトウェアアップデートを実施した際に変更した内容が保持されない可能性があります。 ソフトウェアアップデート実施後も変更内容を保持する手順に関しては 「swupdate_preserve_files について」 を参照してください。

persist_file コマンドの概要を 図9.140「persist_file のヘルプ」 に示します。

[armadillo ~]# persist_file -h
Usage: /usr/bin/persist_file [options] file [more files...]

Mode selection:
  (none) single entry copy
  -d, --delete   delete file
  -l, --list     list content of overlay
  -a, --apk      apk mode: pass any argument after that to apk on rootfs
  -R, --revert   revert change: only delete from overlay, making it
                 look like the file was reverted back to original state

Copy options:
  -r, --recurse  recursive copy (note this also removes files!)
  -p, --preserve make the copy persist through baseos upgrade
                 by adding entries to /etc/swupdate_preserve_files
  -P, --preserve-post   same, but copy after upgrade (POST)

Delete options:
  -r, --recurse  recursively delete files

Common options:
  -v, --verbose  verbose mode for all underlying commands

Note this directly manipulates overlayfs lower directories
so might need a reboot to take effect

図9.140 persist_file のヘルプ


  1. ファイルの保存・削除手順例

    [armadillo ~]# echo test > test
    [armadillo ~]# persist_file -rv /root
    '/root/test' -> '/mnt/root/test' 1
    '/root/.ash_history' -> '/mnt/root/.ash_history'
    [armadillo ~]# rm -f test
    [armadillo ~]# persist_file -rv /root
    removed '/mnt/root/test' 2
    removed '/mnt/root/.ash_history' 3
    '/root/.ash_history' -> '/mnt/root/.ash_history'

    図9.141 persist_file 保存・削除手順例


    1

    追加・変更したファイルを rootfs へコピーします。

    2

    -r を指定すると、ひとつ前の rm -f コマンドで削除したファイルがrootfsからも削除されますのでご注意ください。

    3

    すでに rootfs に存在するファイルも一度削除してからコピーするため、このようなメッセージが表示されます。

  2. ソフトウェアアップデート後も変更を維持する手順例

    [armadillo ~]# vi /etc/conf.d/podman-atmark 1
    [armadillo ~]# persist_file -P /etc/conf.d/podman-atmark 2
    [armadillo ~]# tail -n 2 /etc/swupdate_preserve_files 3
    # persist_file 20211216
    POST /etc/conf.d/podman-atmark

    図9.142 persist_file ソフトウェアアップデート後も変更を維持する手順例


    1

    何らかのファイルの内容を変更します。

    2

    -P オプションを付与して persist_file を実行します。

    3

    swupdate_preserve_files に追加されたことを確認します。

  3. 変更ファイルの一覧表示例

    [armadillo ~]# mkdir dir
    [armadillo ~]# persist_file -l
    directory          /
    directory          /root
    opaque directory   /root/dir 1
    whiteout           /root/test 2
    regular file       /root/.ash_history
    directory          /etc
    regular file       /etc/resolv.conf
    directory          /var
    symbolic link      /var/lock
    : (省略)

    図9.143 persist_file 変更ファイルの一覧表示例


    1

    rootfs のファイルを見せないディレクトリは opaque directory と表示されます。

    2

    削除したファイルは whiteout と表示されます。

  4. パッケージをインストールする時はapkコマンドを使用してメモリ上にインストールできますが、 persist_file コマンドで rootfs に直接インストールすることも可能です。

    [armadillo ~]# persist_file -a add strace
    (1/3) Installing fts (1.2.7-r1)
    (2/3) Installing libelf (0.185-r0)
    (3/3) Installing strace (5.14-r0)
    Executing busybox-1.34.1-r3.trigger
    OK: 251 MiB in 188 packages
    Install succeeded, but might not work in the running system
    Please reboot if installed program does not work 1
    [armadillo ~]# strace ls
    : (省略)
    exit_group(0)                           = ?
    +++ exited with 0 +++

    図9.144 persist_file でのパッケージインストール手順例


    1

    この例では Armadillo を再起動せずにインストールしたコマンドを使用できましたが、Armadillo の再起動が必要となるパッケージもありますので、その場合は Armadillo を再起動してください。

9.8.3. ロールバック状態の確認

Armadillo Base OS の ルートファイルシステムが壊れて起動できなくなった場合に自動的に前のバージョンで再起動します。

自分で確認する必要がある場合に abos-ctrl status でロールバックされてるかどうかの確認ができます。

必要な場合(例えば、自分のアプリケーションがアップデート直後に問題があった場合)、 abos-ctrl rollback で手動のロールバックも可能です。ロールバックにエラーがなかったら、再起動してロールバックを完了します。

なお、/var/at-log/atlog に切り替えの際に必ずログを書きますので、調査の時に使ってください。

[armadillo ~]# cat /var/at-log/atlog
Mar 17 14:51:35 armadillo NOTICE swupdate: Installed update to /dev/mmcblk2p2: \
extra_os.sshd: unset -> 1, extra_os.initial_setup: unset -> 1
Mar 17 16:48:52 armadillo NOTICE swupdate: Installed update to /dev/mmcblk2p1: \
boot: 2020.04-at5 -> 2020.04-at6, base_os: 3.15.0-at.3 -> 3.15.0-at.4
Mar 17 17:42:15 armadillo NOTICE swupdate: Installed update to /dev/mmcblk2p2: \
other_boot: 2020.04-at5 -> 2020.04-at6, container: unset -> 1, extra_os.container: unset -> 1

図9.145 /var/at-log/atlog の内容の例


9.8.4. ボタンやキーを扱う

自分のアプリケーションで直接入力の処理ができない場合に Base OS から簡単な処理ができます。

buttond サービスで指定されたイベントでコマンドを実行します。

デフォルトでは 表14.26「CON12 信号配列」 にある PWR_OFFREBOOT を3秒押す(pull down)場合に poweroffreboot を 実行します。

/etc/atmark/buttond.confBUTTOND_ARGS を上書きすればその対応を無効にすることもできますし、 別のキー(SW1 など)の対応も追加できます:

  • -s <key> -a "command" : 早押しの設定。キーを1秒以内に離せば早押しと認識されてコマンドを実行します。その1秒のタイミングは -t <time_ms> でチューニング可能です。
  • -l <key> -s "command" : 長押しの設定。キーを5秒押しつづけたらその時にコマンドを実行します。その5秒のタイミングは -t <time_ms> でチューニング可能です。
  • 一つのキーを違うタイミングで何回か設定できます。その場合、長押しの設定あればその一番長いタイミングで実行されますが、他のアクションはキーを放す時に合っているコマンドを実行します。(例:-s 1秒、-l 2秒、-l 10秒では、1秒以内に離したら一番目、2秒以上で10秒以内に離したら二番目、10秒を越えたら三番目のコマンドを実行します)

以下にデフォルトを維持したままで SW1 の早押しと長押しにそれぞれの場合にコマンドを実行させます。

[armadillo ~]# vi /etc/atmark/buttond.conf 1
BUTTOND_ARGS="$BUTTOND_ARGS -s prog1 -a 'date >> /tmp/shortpress'"
BUTTOND_ARGS="$BUTTOND_ARGS -l prog1 -t 5000 -a 'date >> /tmp/longpress'"
[armadillo ~]# persist_file /etc/atmark/buttond.conf 2
[armadillo ~]# rc-service buttond restart 3
buttond          | * Stopping button watching daemon ...                                         [ ok ]
buttond          | * Starting button watching daemon ...                                         [ ok ]
[armadillo ~]# cat /tmp/shortpress 4
Tue Mar 22 17:16:42 JST 2022
Tue Mar 22 17:16:43 JST 2022
[armadillo ~]# cat /tmp/longpress
Tue Mar 22 17:16:48 JST 2022

図9.146 buttond で SW1 を扱う


1

カスタマイズ用のコンフィグファイルを編集します。早押しで shortpress, 長押し(5秒)で longpress に日付を出力します。

2

コンフィグファイルを保存します。

3

buttond サービスを再起動させます。ここで早押し二回、長押し一回行います。

4

押された回数を確認します。

USB キーボードや他の入力デバイスにも対応できます。

  1. デバイスを接続してから、 buttond でデバイス名とキーコードを確認します。

    [armadillo ~]# buttond -vvv /dev/input/* /dev/input/by-*/* 1
    Skipping directory /dev/input/by-id
    Skipping directory /dev/input/by-path
    [78972.042] /dev/input/event2 4 4 458976: non-keyboard event ignored
    [78972.042] /dev/input/event2 LEFTCTRL (29) pressed: ignored 2
    [78972.042] /dev/input/by-id/usb-0566_3029-event-kbd 4 4 458976: non-keyboard event ignored
    [78972.042] /dev/input/by-id/usb-0566_3029-event-kbd LEFTCTRL (29) pressed: ignored
    [78972.042] /dev/input/by-path/platform-xhci-hcd.1.auto-usb-0:1:1.0-event-kbd 4 4 458976: non-keyboard event ignored
    [78972.042] /dev/input/by-path/platform-xhci-hcd.1.auto-usb-0:1:1.0-event-kbd LEFTCTRL (29) pressed: ignored
    [78972.130] /dev/input/event2 4 4 458976: non-keyboard event ignored
    [78972.130] /dev/input/event2 LEFTCTRL (29) released: ignored
    [78972.130] /dev/input/by-id/usb-0566_3029-event-kbd 4 4 458976: non-keyboard event ignored
    [78972.130] /dev/input/by-id/usb-0566_3029-event-kbd LEFTCTRL (29) released: ignored
    [78972.130] /dev/input/by-path/platform-xhci-hcd.1.auto-usb-0:1:1.0-event-kbd 4 4 458976: non-keyboard event ignored
    [78972.130] /dev/input/by-path/platform-xhci-hcd.1.auto-usb-0:1:1.0-event-kbd LEFTCTRL (29) released: ignored

    1

    buttond-vvv で冗長出力にして、すべてのデバイスを指定します。

    2

    希望のキーを押すと、LEFTCTRL が三つのパスで認識されました。 一番安定する by-id のパスを控えておきます。

  2. USB デバイスを外すこともありますので、-i (inotify) で管理されてる入力デバイスとして追加します。 そうしないとデバイスを外したときにbuttondが停止します。

    [armadillo ~]# vi /etc/atmark/buttond.conf
    BUTTOND_ARGS="$BUTTOND_ARGS -i /dev/input/by-id/usb-0566_3029-event-kbd"
    BUTTOND_ARGS="$BUTTOND_ARGS -s LEFTCTRL -a 'podman_start button_pressed_container'"
    [armadillo ~]# persist_file /etc/atmark/buttond.conf
    [armadillo ~]# rc-service buttond restart

9.8.5. Armadillo Base OS 側の起動スクリプト

起動時に何かスクリプトを走らせるためにはコンテナとして実行することを推奨します。 「コンテナの自動起動」 を参照してください。

コンテナで実行不可能な場合に、「local」サービスを使うことができます: /etc/local.d ディレクトリに .start ファイルを置いておくと起動時に実行されて、 .stop ファイルは終了時に実行されます。

[armadillo ~]# vi /etc/local.d/date_test.start 1
#!/bin/sh

date > /tmp/boottest
[armadillo ~]# chmod +x /etc/local.d/date_test.start 2
[armadillo ~]# persist_file /etc/local.d/date_test.start 3
[armadillo ~]# reboot
: (省略)
[armadillo ~]# cat /tmp/boottest 4
Tue Mar 22 16:36:12 JST 2022

図9.147 local サービスの実行例


1

スクリプトを作ります。

2

スクリプトを実行可能にします。

3

スクリプトを保存して、再起動します。

4

実行されたことを確認します。

9.8.6. Network Time Protocol (NTP, ネットワーク・タイム・プロトコル)

Armadillo Base OS では chronyd を使っています。

デフォルトの設定(使用するサーバーなど)は /etc/chrony/conf.d/ にあり、 変更用に /etc/atmark/chrony.conf.d/ のファイルも読み込みます。 /etc/atmark/chrony.conf.d ディレクトリに /etc/chrony/conf.d/ と同じファイル名の 設定ファイルを置いておくことで、デフォルトのファイルを読まないようになります。

例えば、 NTP サーバーの設定は servers.conf に記載されてますので、変更する際はに /etc/atmark/chrony.conf.d/servers.conf のファイルに記載します:

[armadillo ~]# vi /etc/atmark/chrony.conf.d/servers.conf 1
pool my.ntp.server iburst
[armadillo ~]# persist_file /etc/atmark/chrony.conf.d/servers.conf 2
[armadillo ~]# rc-service chronyd restart 3
chronyd          | * Stopping chronyd ... [ ok ]
chronyd          | * Starting chronyd ... [ ok ]
armadillo:~# chronyc sources 4
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^? my.ntp.server                 1   6     3     2    +88ms[  +88ms] +/-  173ms

図9.148 chronyd のコンフィグの変更例


1

コンフィグファイルを作ります。

2

ファイルを保存します

3

chronyd サービスを再起動します。

4

chronyc で新しいサーバーが使用されていることを確認します。

9.9. Device Treeをカスタマイズする

at-dtweb を利用して Device Tree をカスタマイズする方法を説明します。at-dtweb では、 Web ブラウザ上のマウス操作でDTSおよび DTB を生成することができます。 カスタマイズの対象は拡張インターフェース(CON11、CON12)です。

9.9.1. at-dtweb のインストール

ATDE9 に at-dtweb パッケージをインストールします。

[ATDE ~]$ sudo apt update
[ATDE ~]$ sudo apt install at-dtweb

インストール済みの場合は、以下のコマンドを実行し最新版への更新を行ってください。

[ATDE ~]$ sudo apt update
[ATDE ~]$ sudo apt upgrade

9.9.2. at-dtweb の起動

  1. at-dtweb の起動開始

    at-dtweb の起動を開始するには、デスクトップ左上のアプリケーションの「システムツール」から「at-dtweb」を選択してください。

    images/at-dtweb-activity.png

    図9.149 at-dtweb の起動開始


コマンドライン上からでも、at-dtweb コマンドで起動できます。

[ATDE ~]$ at-dtweb
  1. ボードの選択

    ボードを選択します。Armadillo-IoT_G4 を選択して、「OK」をクリックします。

    images/at-dtweb-board-select.png

    図9.150 ボード選択画面


  2. Linux カーネルディレクトリの選択

    Linux カーネルディレクトリを選択します。コンフィギュレーション済みの Linux カーネルディレクトリを選択して、「OK」をクリックします。

    images/at-dtweb-kernel-select.png

    図9.151 Linux カーネルディレクトリ選択画面


[警告]

at-dtweb のバージョン が 2.6.2 以降の場合は、 Linux カーネルソースのバージョン v5.10.112-r0 以降を、 mkswu のバージョンは 3.15.at.6 以降を使用してください。

at-dtweb と mkswu のバージョンは以下のコマンドで調べることができます。

[ATDE ~]$ ~/mkswu/at-dtweb$ dpkg -l at-dtweb mkswu
要望=(U)不明/(I)インストール/(R)削除/(P)完全削除/(H)保持
| 状態=(N)無/(I)インストール済/(C)設定/(U)展開/(F)設定失敗/(H)半インストール/(W)トリガ待ち/(T)トリガ保留
|/ エラー?=(空欄)無/(R)要再インストール (状態,エラーの大文字=異常)
||/ 名前           バージョン   アーキテクチ 説明
+++-==============-============-============-=============================================
ii  at-dtweb       2.6.2        all          Device Tree editor for Atmark Techno products
ii  mkswu          3.15.at.6-1  all          build SWU images for armadillo base OS
  1. at-dtweb の起動完了

    at-dtweb が起動し、次のように画面が表示されます。

    images/at-dtweb-main.png

    図9.152 at-dtweb 起動画面


[ティップ]

Linux カーネルは、事前にコンフィギュレーションされている必要があります。コンフィギュレーションの手順については「Armadilloのソフトウェアをビルドする」を参照してください。

9.9.3. Device Tree をカスタマイズ

9.9.3.1. 機能の選択

機能の選択は、ドラッグ&ドロップで行います。画面左上の「Available features」から有効にしたい機能をドラッグし、画面右側の「Armadillo-IoT Gateway G4」の白色に変化したピンにドロップします。例として CON11 8/10 ピンを UART3(RXD/TXD) に設定します。

[ティップ]

何も機能が選択されていないピンには GPIO の機能が割り当てられます。

images/at-dtweb-enable-feature1.png

図9.153 UART3(RXD/TXD) のドラッグ


images/at-dtweb-enable-feature2.png

図9.154 CON11 8/10 ピンへのドロップ


9.9.3.2. 信号名の確認

画面右側の「Armadillo-IoT Gateway G4」にドロップして設定したピンを左クリックすると信号名が表示されます。 どのピンがどの信号に対応しているのかを確認することができます。

例として UART3(RXD/TXD) の信号名を確認します。

images/at-dtweb-show-signal-name.png

図9.155 信号名の確認


[ティップ]

再度ピンを左クリックすると機能名の表示に戻ります。

9.9.3.3. プロパティの設定

いくつかの機能にプロパティを設定することができます。画面右側の「Armadillo-IoT Gateway G4」に選択した機能を左クリックすると、画面左下の「Properties」からプロパティを選択することができます。

例としてCON11 19/27 ピンの I2C5(SCL/SDA) の clock_frequency プロパティを設定します。

images/at-dtweb-set-property.png

図9.156 プロパティの設定


設定したプロパティを確定させるには「Apply」をクリックします。

images/at-dtweb-apply-property.png

図9.157 プロパティの保存


9.9.3.4. 機能の削除

全ての機能を削除する場合は、画面右上の「Reset configuration」をクリックします。機能ごとに削除する場合は、画面右側の「Armadillo-IoT Gateway G4」のピンを右クリックして「Remove」をクリックします。

images/at-dtweb-reset-configuration.png

図9.158 全ての機能の削除


images/at-dtweb-remove-configuration.png

図9.159 I2C5(SCL/SDA) の削除


9.9.3.5. DTS/DTBの生成

DTS および DTB を生成するには、画面右上の「Save」をクリックします。

images/at-dtweb-save-configuration.png

図9.160 DTS/DTB の生成


at-dtweb のバージョンによって DTS および DTB の生成は完了画面は異なります。

  • バージョン 2.6.2 未満の場合

以下の画面ようなメッセージが表示されると、DTS および DTB の生成は完了です。

images/at-dtweb-save-complete.png

図9.161 DTS/DTB の生成完了


ビルドが終了すると、arch/arm64/boot/dts/freescale 以下に DTS/DTB が作成されています。

[ATDE ~/linux-5.10]$ ls arch/arm64/boot/dts/freescale/armadillo_iotg_g4-expansion-interface.dtsi
arch/arm64/boot/dts/freescale/armadillo_iotg_g4-expansion-interface.dtsi
[ATDE ~/linux-5.10]$ ls arch/arm64/boot/dts/freescale/armadillo_iotg_g4-at-dtweb.dtb
arch/arm64/boot/dts/freescale/armadillo_iotg_g4-at-dtweb.dtb
  • バージョン 2.6.2 以降の場合

以下の画面ようなメッセージが表示されると、DTS および DTB の生成は完了です。

images/at-dtweb-save-complete-dtbo.png

図9.162 DTS/DTB の生成完了


at-dtweb のバージョン 2.6.2 以降では、ビルドが完了するとホームディレクトリ下の mkswu/at-dtweb ディレクトリに、DTB overlays ファイル(dtboファイル)と desc ファイルが生成されます。 Armadillo-IoT ゲートウェイ G4 本体に書き込む場合は、mkswu コマンドで desc ファイルから SWU イメージを生成してアップデートしてください。

[ATDE ~]$ ls ~/mkswu/at-dtweb
armadillo_iotg_g4-at-dtweb.dtbo  at-dtweb.desc.old   update_preserve_files.sh
at-dtweb.desc                    update_overlays.sh
[ATDE ~]$ cd ~/mkswu/at-dtweb
[ATDE ~]$ mkswu at-dtweb.desc 1
Enter pass phrase for /home/atmark/mkswu/swupdate.key:
at-dtweb.swu を作成しました。

1

SWU イメージを生成します。

SWU イメージを使ったアップデートの詳細は 「Armadilloのソフトウェアをアップデートする」 を参照してください。

9.9.4. DTS overlays によるカスタマイズ

Device Treeは「DTS overlay」(dtbo) を使用することでも変更できます。

DTS overlay を使用することで、通常の dts の更新が自動的に入りつづける状態で dts の変更でしかできない設定を行うことができます。

/boot/overlays.txtfdt_overlays を dtbo 名で設定することで、 u-bootが起動時にその DTS overlay を通常の dtb と結合して起動します。

複数の DTS overlay を使う場合は以下の例のようにスペースで別けたファイル名を記載することができます。

[armadillo ~]# vi /boot/overlays.txt 1
fdt_overlays=armadillo_iotg_g4-nousb.dtbo armadillo_iotg_g4-sw1-wakeup.dtbo

[armadillo ~]# persist_file -vp /boot/overlays.txt 2
'/boot/overlays.txt' -> '/mnt/boot/overlays.txt'
Added "/boot/overlays.txt" to /etc/swupdate_preserve_files

[armadillo ~]# reboot 3
: (省略)
Applying fdt overlay: armadillo_iotg_g4-nousb.dtbo 4
Applying fdt overlay: armadillo_iotg_g4-sw1-wakeup.dtbo
: (省略)

[armadillo ~]# cat /sys/firmware/devicetree/base/regulator-usb1-vbus/status; echo
broken 5
[armadillo ~]# cat /sys/devices/platform/gpio-keys/power/wakeup 6
enabled

図9.163 /boot/overlays.txt の変更例


1

/boot/overlays.txt ファイルに「armadillo_iotg_g4-sw1-wakeup.dtbo」を追加します。 ファイルが存在しない場合は新規に作成してください。 このファイルの詳細については 「DTS overlays によるカスタマイズ」 を参照してください。

2

/boot/overlays.txt を保存し、アップデートの場合でも保存します。

3

overlay の実行のために再起動します。

4

シリアルコンソールの場合に、u-bootによるメッセージを確認できます。

5

Linux からも「nousb」overlay の確認ができます。USB の regulator を無効にしたため、 USB を使えないようになりました。

6

sw1-wakeupも有効になっていることを確認できます。

9.9.4.1. 提供している DTS overlay

以下の DTS overlay を用意しています:

  • armadillo_iotg_g4-nousb.dtbo: USB の電源を切ります。
  • armadillo_iotg_g4-sw1-wakeup.dtbo: SW1 の起床要因を有効にします。
  • armadillo_iotg_g4-con10-arducam.dtbo: arducam カメラを MIPI-DSI で接続する場合にご使用ください。
  • armadillo_iotg_g4-con10-imx219.dtbo: Raspberry Pi 向けの imx219 カメラを MIPI-DSI で接続する場合にご使用ください。
  • armadillo_iotg_g4-con10-ox01f10.dtbo: OMNIVISION の OX01F10 カメラを MIPI-DSI で接続する場合にご使用ください。
  • armadillo_iotg_g4-lte-ext-board.dtbo: LTE モデルで自動的に使用します。

9.9.4.2. カスタマイズした DTS overlay の作成

at-dtweb では対応できない変更を行いたい場合にカスタマイズした DTS overlay を作成することでができます。

overlay を使用することで、今後のアップデートで overlay される側の dts に変更があっても自動的に適用され続けます。

  1. 「Linux カーネルをビルドする」 を参照して、カーネルのソースコードを取得します。
  2. ソースディレクトリの arch/arm64/boot/dts/freescale/armadillo_iotg_g4-customize.dts を編集します。
  3. make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs で DTS overlay をビルドします。
  4. arch/arm64/boot/dts/freescale/armadillo_iotg_g4-customize.dtbo ファイルを Armadillo の /boot に配置し、/boot/overlays.txt に記載します。
[PC ~]$ cd linux-[VERSION] 1
[PC ~/linux-[VERSION]]$ vim \
    arch/arm64/boot/dts/freescale/armadillo_iotg_g4-customize.dts 2
/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/clock/imx8mp-clock.h>
#include <dt-bindings/input/input.h>

#include "imx8mp-pinfunc.h"

&pwm2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
        status = "okay";
};

&iomuxc {
        pinctrl_pwm2: pwm2grp {
                fsl,pins = <
                        MX8MP_IOMUXC_SPDIF_RX__PWM2_OUT  0x186
                >;
        };
};
[PC ~/linux-[VERSION]]$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs 3
: (省略)
  DTC     arch/arm64/boot/dts/freescale/armadillo_iotg_g4-customize.dtbo
: (省略)
[PC ~/linux-[VERSION]]$ scp \
    arch/arm64/boot/dts/freescale/armadillo_iotg_g4-customize.dtbo \
    armadillo:/boot 4
armadillo_iotg_g4-customize.dtbo          100%  551   207.5KB/s   00:00
[armadillo ~]# cd /boot
[armadillo /boot]# vi /boot/overlays.txt 5
fdt_overlays=armadillo_iotg_g4-customize.dtbo
[armadillo /boot]# persist_file -vp overlays.txt \
                                    armadillo_iotg_g4-customize.dtbo 6
'/boot/overlays.txt' -> '/mnt/boot/overlays.txt'
'/boot/armadillo_iotg_g4-customize.dtbo' -> '/mnt/boot/armadillo_iotg_g4-customize.dtbo'
Added "/boot/armadillo_iotg_g4-customize.dtbo" to /etc/swupdate_preserve_files
[armadillo /boot]# reboot 7
: (省略)
Applying fdt overlay: armadillo_iotg_g4-customize.dtbo

図9.164 DTS overlay を作成する例


1

取得したカーネルのソースディレクトリに入ります。

2

dts ファイルを編集します。この例では pwm2 を SPDIF_RX (CON9.28) ピンを有効にします。

3

DTS overlay をビルドします。

4

ビルドされたファイルを Armadillo にコピーします。この例では scp を使いましたが、USBドライブでのコピーや SWUpdate でも可能です。

5

overlays.txt にこの DTS overlay をロードするように記載します。

6

ファイルを永続化します。DTS overlay は swupdate_preserve_files のデフォルトには記載されていないため、SWUpdate で更新する場合は必ず swupdate_preserve_files も更新してください。

7

再起動して、u-boot の出力で DTS overlay がロードされてることを確認します。

9.10. eMMC のデータリテンション

eMMC は主に NAND Flash メモリから構成されるデバイスです。NAND Flash メモリには書き込みしてから1年から3年程度の長期間データが読み出されないと電荷が抜けてしまう可能性があります。その際、電荷が抜けて正しくデータが読めない場合は、eMMC 内部で ECC (Error Correcting Code) を利用してデータを訂正します。しかし、訂正ができないほどにデータが化けてしまう場合もあります。そのため、一度書いてから長期間利用しない、高温の環境で利用するなどのケースでは、データ保持期間内に電荷の補充が必要になります。電荷の補充にはデータの読み出し処理を実行し、このデータの読み出し処理をデータリテンションと呼びます。

Armadillo-IoT ゲートウェイG4に搭載のeMMCには長期間データが読み出されない状態であっても、データリテンションを自動的に行う機能を搭載しています。

[ティップ]

詳しい仕様については 「実装仕様に関する技術情報」 を参照してください。

9.10.1. データリテンションの設定

データリテンションは /etc/conf.d/micron_emmc_reten というファイルに書かれた設定、use_system_time によって以下の2通りの挙動を示します。

表9.9 データリテンションの挙動

/etc/conf.d/micron_emmc_reteninitiating condition

use_system_time=yes

Linux 起動した時に前回のリテンションから1日以上経過していたら開始する

use_system_time=no (default)

Linux 起動した時に毎回開始する


これで設定は完了しました。

以下は挙動ごとのシステム概略図です。

images/common-images/emmc-sref.png

図9.165 データリテンション開始トリガーの方式


use_system_time を有効にした場合のデータリテンションの動作例を以下に示します。

images/common-images/emmc-sref_counter.png

図9.166 データリテンションの開始トリガーの動作例


9.10.2. より詳しくデータリテンションの統計情報を確認するには

Micron Technology が提供する emmcparm というツールを使うことで、データリテンションの統計情報を確認することができます。統計情報として eMMC 内部に保存されているのは実行回数、最終実行完了時のカウンター値、現在のデータリテンション処理の進捗があります。 次の手順で、emmcparmを使ってeMMCの情報を確認することができます。このツールではデータリテンション処理のことを「セルフリフレッシュ」と呼びます。

  1. emmcparm をダウンロードする

    以下の検索結果から最新の emmcparm をダウンロードする。ユーザー登録が必要になります。

    [注記]

    マニュアル作成時点では 5.0.0 を利用しました

  2. パッケージを展開する

    [armadillo ~]# unzip emmc_emmcparm_c_code_derived_from_TN\ FC\ 25_v5.0.0 _binary.zip
  3. SSR を取得する

    [armadillo ~]# emmcparm/bin/emmcparm_arm_64bit -r /dev/mmcblk2
    : (省略)
    =======================================================================
    |                         Secure Smart Report                         |
    =======================================================================
      Self Refresh progress of scan[215-212]:               0x00000000 (0) 1
      Power Loss Counter[195-192]:                          0x00000005 (5)
      Current total ON time[131-128]:                       0x00001b28 (6952)
      Number of Blocks in Refresh Queue[99-96]:             0x00000000 (0)
      Self Refresh Completion date [95-88]:                 0xffffffffd8148931 2
                                                            (-669742799)
      Self Refresh Loop Count[81-80]:                       0x00000002 (2)  3
      Written Data 100MB Size Count (from NAND)[79-76]:     0x0004889d (297117)
      Cumulative Initialization Count (from NAND)[75-72]:   0x00005300 (21248)
      Written Data 100MB Size Count (from RAM)[71-68]:      0x0004889d (297117)
      Refresh Count[55-52]:                                 0x00000004 (4)
    : (省略)

    1

    現在のセルフリフレッシュ処理の進捗。0 ということは実行中ではない

    2

    最後に行ったセルフリフレッシュのカウンター値

    3

    セルフリフレッシュを行った回数

9.10.3. 実装仕様に関する技術情報

ここではデータリテンションを自動的におこなう機能の仕様について詳細に説明します。 Armadillo で採用しているeMMCには、データリテンションを自動的に実行することができる「セルフリフレッシュ」と呼ばれる機能が搭載されます。実行トリガーは2種類のうちどちらかを選択できます。OTP のため一度設定すると変更できません。この設定は出荷時に「eMMC 内部レジスタ値とコマンドに入力された値を比較して1日以上経過していると実行する」を設定しています。

  1. リセット後に毎回実行する
  2. eMMC 内部レジスタ値とコマンドに入力された値を比較して1日以上経過していると実行する

2の設定の場合、セルリフレッシュ機能が実行されるまでの流れは以下のとおりです。

  1. ホストによって eMMC がハードウェアもしくはソフトウェアリセットされる
  2. 一定時間 (delay 1) 以内に、ホストから SET_TIME (CMD49)と呼ばれるコマンドが eMMC に発行される
  3. eMMC コントローラは、バスの稼動状態を監視する
  4. eMMC コントローラは、アイドルになってから一定時間 (delay 2) 経過した後にセルフリフレッシュを実行する

    • ECC エラーなどのエラーがしきい値 (2) を越えたセルに対してのみセルフリフレッシュを実行する

Armadillo でのセルフリフレッシュ機能搭載 eMMC への設定は以下のとおりです。

表9.10 Armadillo のデータリテンションの設定

settingvaluedescription

RTC

ON

eMMC 内部レジスタの値と SET_TIME の値を比較してセルフリフレッシュを実行する

Delay 1

60s

リセット後の SET_TIME 有効期間

Delay 2

100ms

アイドル確認後のセルフリフレッシュ実行までの遅れ時間


[注記]

詳しい情報は以下を参照してください。

マイクロンのサイトの会員登録が必要になります。

9.11. デモアプリケーションを実行する

この章では、アットマークテクノが提供するデモアプリケーションについて説明します。 デモアプリケーションは GUI アプリケーションであるため、ディスプレイを接続している必要があります。 デモアプリケーションを実行するためのコンテナイメージとして、アットマークテクノが提供する コンテナイメージを想定しています。 このイメージに関しては 「アットマークテクノが提供するイメージを使う」 を参照してください。

9.11.1. コンテナを作成する

デモアプリケーションを実行するためのコンテナを以下のように作成します。 ここでは 「VPU や NPU を使用する」 をすでに実行済みであるとします。

[armadillo ~]# podman run -it --name=demo-app \
--env=XDG_RUNTIME_DIR=/tmp \
--env=QT_QPA_PLATFORM=wayland \
--volume=/sys:/sys \
--volume=/dev:/dev \
--volume=/run/udev:/run/udev \
--volume=/opt/firmware:/opt/firmware \
--privileged \
localhost/at-debian-image:latest /bin/bash
[container /]#

図9.167 デモアプリケーションを実行するためのコンテナ作成例


9.11.2. weston を起動する

デモアプリケーションは GUI アプリケーションであるため、コンテナにログイン後、 まずデスクトップ環境を起動する必要があります。ここでは weston を起動します。

[container /]# weston --tty=1 &

図9.168 weston の起動


--tty=1 のオプションは画面表示に使用する tty の値を設定してください。

9.11.3. デモアプリケーションランチャを起動する

デモアプリケーションランチャを起動します。 個々のデモアプリケーションはこのデモアプリケーションランチャから起動できます。 このデモアプリケーションランチャは GUI フレームワークとして Qt を使用しています。 デモアプリケーションランチャのソースコードは、apt source で取得することができます。

[container /]# apt install armadillo-demo-experience
[container /]# demoexperience

図9.169 デモアプリケーションランチャの起動


以下のようなアプケーションが起動します。

images/demo_app_launcher_1.png

左側のカテゴリから起動したいデモアプリケーションを選びます。

images/demo_app_launcher_2.png
images/demo_app_launcher_3.png

選んだアプリケーションは、右下の Launch ボタンで起動することができます。

9.11.4. mediaplayer

mediaplayer は動画を再生するアプリケーションです。H.264, VP8, VP9 でエンコードされた 動画ファイルであれば、動画のデコードに VPU が使われます。File メニューから、再生したい 動画ファイルを選択することができます。 このアプリケーションは、GUI フレームワークとして wxWidgets を使用しています。

images/demo_app_mediaplayer.png

音声も出力したい場合は、pulseaudio をインストールして起動する必要があります。

[container /]# apt install pulseaudio
[container /]# pulseaudio --start --exit-idle-time=-1

図9.170 pulseaudio のインストールと起動


9.11.5. video recoder

video recoder は gstreamer を使用してカメラからの映像を録画することができます。 そのため、このアプリケーションを使用するためには、Armadillo 本体にカメラを接続する必要があります。 カメラが接続されていると Video device の項目でカメラを選択できるようになります。 カメラを選択し、Start ボタンを押すと別ウィンドウが表示され録画が開始されます。 アプリケーション上のテキストボックスには、Start ボタンを押したときに起動する gstreamer の コマンドを表示しています。テキストボックスの内容はキーボードで編集可能です。 このアプリケーションは、GUI フレームワークとして wxWidgets を使用しています。

images/demo_app_video_rec_tester.png

マイク付きのカメラなどで同時に音声も録音したい場合は、「mediaplayer」 を参照して pulseaudio を起動してください。

9.11.6. led switch tester

led switch tester は Armadillo 本体上の LED と SW1 を扱うアプリケーションです。 LED ボタンを押すことで Armadillo 本体上の LED の 点灯・消灯を確認することができます。 Armadillo 本体上の SW1 を押すとアプリケーションの SW1 部分の表示が変化することを確認できます。 このアプリケーションは、GUI フレームワークとして wxWidgets を使用しています。

images/demo_app_led.png

9.11.7. rtc tester

rtc tester は Armadillo 本体上の RTC に対して日時の設定および取得が行えるアプリケーションです。 カレンダー上から日付を選び、Time に設定したい時刻を入力した後、Set ボタンを押すと RTC にその日時が 設定されます。Get ボタンを押すと、現在の日時を RTC から読み込みアプリケーション上に反映されます。 このアプリケーションは、GUI フレームワークとして wxWidgets を使用しています。

images/demo_app_rtc_tester.png

9.11.8. object detection demo

object detection demo はカメラからの映像に対して物体認識を行うアプリケーションです。 NPU を使用しているため高速に物体認識を行えます。画面の左側には認識した物体を囲む四角形が表示され、 右側には認識した物体のラベルとスコアが表示されます。 このアプリケーションは機械学習のライブラリとして TensorFlow Lite を使用しています。

起動する前に、必要な Python ライブラリをインストールする必要があります。

[container /]# pip3 install pillow

図9.171 pillow のインストールと起動


images/demo_app_object_detection.png

このアプリケーションはカメラデバイスとしてデフォルトで /dev/video2 を使用します。 お使いの環境によって別のカメラデバイスに設定したい場合は、以下のファイルを変更してください。

[container /]# vi /usr/share/armadillo-demo-experience/resources/demos.json
:
: (省略)
:
{"Machine Learning":[{
        "Tensorflow Lite":[{
            "name": "object detection demo",
            "executable": "python3 /usr/share/armadillo-demo-experience/AI-demo/object_detection/detect_usbcamera.py --model /usr/share/armadillo-demo-experience/AI-demo/object_detection/detect.tflite --labels /usr/share/armadillo-demo-experience/AI-demo/object_detection/coco_labels.txt --camera_id 2", 1
            "compatible": "armadillo-x2",
            "description": "This is a simple object detection aplication that used NPU and TensorFlow Lite on the Armadillo-X2 board."
        }]
    }]

図9.172 ビデオデバイスの変更


1

--camera_id の値を環境に合わせて変更します。

9.11.9. pose estimation demo

pose estimation demo はカメラに映った人物の姿勢を推定して表示するアプリケーションです。 NPU を使用しているため高速に姿勢推定を行えます。推定した姿勢は人物の上に重ねて表示されます。 このアプリケーションは機械学習のライブラリとして TensorFlow Lite を使用しています。

images/demo_app_pose_estimation.png

このアプリケーションは起動してから画面に映像が表示されるまで約 1 分ほどかかります。 また、カメラデバイスとしてデフォルトで /dev/video2 を使用します。 お使いの環境によって別のカメラデバイスに設定したい場合は、以下のファイルを変更してください。

[container /]# vi /usr/share/armadillo-demo-experience/resources/demos.json
:
: (省略)
:
{"Machine Learning":[{
:
: (省略)
:
        {
            "name": "pose estimation",
            "executable": "python3 /usr/share/armadillo-demo-experience/AI-demo/pose_estimation/pose_estimation.py --model /usr/share/armadillo-demo-experience/AI-demo/pose_estimation/posenet.tflite --camera_id 2", 1
            "source": "",
            "screenshot": "pose_estimation_demo.png",
            "compatible": "armadillo-x2",
            "description": "This is a simple pose estimation aplication that uses NPU on the Armadillo-X2 board."
        }]
    }]

図9.173 ビデオデバイスの変更


1

--camera_id の値を環境に合わせて変更します。

9.11.10. image segmentation demo

image segmentation demo はカメラに映った人物の「人物として認識された領域(セグメント)」を推定して表示するアプリケーションです。 NPU を使用しているため高速に領域推定を行えます。推定した領域は人物の上に青の透過色で重ねて表示されます。 このアプリケーションは機械学習のライブラリとして TensorFlow Lite を使用しています。

images/demo_app_image_segmentation.png

このアプリケーションはカメラデバイスとしてデフォルトで /dev/video2 を使用します。 お使いの環境によって別のカメラデバイスに設定したい場合は、以下のファイルを変更してください。

[container /]# vi /usr/share/armadillo-demo-experience/resources/demos.json
:
: (省略)
:
{"Machine Learning":[{
:
: (省略)
:
        {
            "name": "image segmentation",
            "executable": "python3 /usr/share/armadillo-demo-experience/AI-demo/image_segmentation/image_segmentation.py --model /usr/share/armadillo-demo-experience/AI-demo/image_segmentation/human_segmentation.tflite --camera_id 2", 1
            "source": "",
            "screenshot": "image_segmentation_demo.png",
            "compatible": "armadillo-x2",
            "description": "This is a simple image segmentation aplication that uses NPU on the Armadillo-X2 board."
        }]
    }]

図9.174 ビデオデバイスの変更


1

--camera_id の値を環境に合わせて変更します。

9.12. SMS を利用する

Armadillo-IoT ゲートウェイ G4 は、3G/LTE モジュール を使用した SMS の送受信を行うことができます。 SMS の送信、受信した SMS の確認および削除などの操作は ModemManager の mmcli コマンドで行うことができます。

本章では mmcli コマンドでの SMS の使用方法について説明します。

9.12.1. 初期設定

SMS が利用可能な SIM を挿入して Armadillo-IoT ゲートウェイ G4の電源を入れると、 ModemManager が必要な初期設定を行い、 SMS が利用可能になります。

SMS の受信は自動的に行われます。

図9.175「言語設定」に示すコマンドを実行し、言語設定を行います。

[armadillo ~]# export LANG="ja_JP.UTF-8"

図9.175 言語設定


9.12.2. SMS を送信する

SMS を作成するには、図9.176「SMS の作成」に示すコマンドを実行します。

[armadillo ~]# mmcli -m 0 --messaging-create-sms="number=[送信先電話番号],text='[SMS 本文]'"

図9.176 SMS の作成


SMSの作成に成功すると、以下のようにSMS番号が表示されます。SMS番号は送信時に使用します。

Successfully created new SMS: /org/freedesktop/ModemManager1/SMS/[SMS 番号]

図9.177 SMS 番号の確認


図9.178「SMS の送信」に示すコマンドを実行し、SMS 送信を行います。 [SMS番号] には、 SMS の作成時に表示された番号を指定します。

[armadillo ~]# mmcli -s [SMS 番号] --send

図9.178 SMS の送信


9.12.3. SMS を受信する

SMS を送信可能な端末から Armadillo-IoT ゲートウェイ G4 に SMS を送信すると、 Armadillo-IoT ゲートウェイ G4 は自動的に SMS を受信します。

また、 EC25-J の内蔵ストレージに 4 件 SMS を保存した状態で Armadillo-IoT ゲートウェイ G4 に SMS を送信した場合は、Armadillo-IoT ゲートウェイ G4 は受信を行いません。

受信を行うには、 EC25-J の内蔵ストレージに保存している SMS を削除するか、他のストレージに移動する必要があります。

9.12.4. SMS 一覧を表示する

図9.179「SMS の一覧表示」のコマンドを実行することで、 SMS 一覧を表示できます。

末尾が "(sent)" となっているものが送信した SMS で "(received)" となっているものが受信した SMS です。

[armadillo ~]# mmcli -m 0 --messaging-list-sms
Found 7 SMS messages:
         /org/freedesktop/ModemManager1/SMS/0 (received)
         /org/freedesktop/ModemManager1/SMS/1 (received)
         /org/freedesktop/ModemManager1/SMS/2 (received)
         /org/freedesktop/ModemManager1/SMS/3 (received)
         /org/freedesktop/ModemManager1/SMS/4 (sent)
         /org/freedesktop/ModemManager1/SMS/5 (received)
         /org/freedesktop/ModemManager1/SMS/6 (sent)

図9.179 SMS の一覧表示


9.12.5. SMS の内容を表示する

SMS の内容を表示するには、図9.180「SMSの内容を表示」に示すコマンドを実行します。

[armadillo ~]# mmcli -s [SMS 番号]
  ----------------------------------
  Content    |              number: XXXXXXXXXXX
             |                text: hello world
  ----------------------------------
  Properties |            PDU type: deliver
             |               state: received
             |             storage: me
             |                smsc: +XXXXXXXXXXXX
             |           timestamp: XXXXXXXXXXXX+XX

図9.180 SMSの内容を表示


受信した SMS は自動的に 3G/LTE モジュールの内蔵ストレージに保存されます。Armadillo-IoT ゲートウェイ G4 に搭載されている、 EC25-J は、最大 4 件まで SMS を保存することが可能です。

SMS の内容を表示した際の「storage: 'me'」は、 3G/LTEモ ジュールの内蔵ストレージに SMS が保存されていることを意味しています。

「storage: 'sm'」と表示された場合、 SIM カードのストレージに SMS が保存されています。 SIM カードのストレージに保存できる SMS の件数は SIM カードによって異なります。

ストレージに保存されている SMS は、Armadillo-IoT ゲートウェイ G4 の電源を切断してもデータが保持されます。

9.12.6. SMS を削除する

SMS を削除するには、図9.181「SMSの削除」に示すコマンドを実行します。

[armadillo ~]# mmcli -m 0 --messaging-delete-sms=[SMS 番号]

図9.181 SMSの削除


9.12.7. SMS を他のストレージに移動する

SIM カードのストレージに SMS を移動するには、図9.182「SIM カードのストレージに SMS を移動」に示すコマンドを実行します。

[armadillo ~]# mmcli -s [SMS 番号] --store-in-storage="sm"

図9.182 SIM カードのストレージに SMS を移動


3G/LTE モジュールの内蔵ストレージに SMS を移動するには、図9.183「3G/LTE モジュールの内蔵ストレージに SMS を移動」に示すコマンドを実行します。

[armadillo ~]# mmcli -s [SMS 番号] --store-in-storage="me"

図9.183 3G/LTE モジュールの内蔵ストレージに SMS を移動




[7] 推論実行用のソフトウェアであり、学習は行なえません。

[8] スペースキーでページを送ると、 最終ページに同意するかどうかの入力プロンプトが表示されます。