Howto

拡張インターフェースで入出力を行う方法 (Armadillo-IoT ゲートウェイ A6E)

拡張インターフェースで入出力を行う方法 (Armadillo-IoT ゲートウェイ A6E)

この Howto では、Armadillo-IoT A6E の 入出力インターフェースの接点入出力や 拡張インターフェースの GPIO を使用し、 入出力を行う方法を紹介します。

ここでは、入力を gpio-keys を介して行うことで、 チャタリング除去を行い、キーボードのボタンと同様に扱えます。

また、出力を gpio-leds を介して行うことで、 OS 起動時に出力にし、初期状態を決めたり、 簡単にアクセスランプなどとして機能させることができます。

ゲートウェイコンテナなど、接点入出力や GPIO を使用する他のアプリケーションとの競合に注意してください。

必要な回路

例として CON6 と CON8 に次のようにスイッチや LED を接続します。


使用ソフトウェア

本Howtoで使用したソフトウェアは次のとおりです。

項目 ファイル
Armadillo Base OS v3.17.2-at.3
Linux カーネル v5.10.161-r0

Device Tree のカスタマイズ

現時点では at-dtweb では設定できないので、Devicetree Overlay により対応します。

Linux カーネルのソースコードを未取得であれば取得します。

ダウンロードページ

ホームディレクトリにダウンロードしたとし、解凍します。

[ATDE ~]$ tar xf linux-at-[VERSION].tar
[ATDE ~]$ tar xf linux-at-[VERSION]/linux-[VERSION].tar.gz

サンプルファイルをダウンロードします。

[ATDE ~]$ wget https://download.atmark-techno.com/sample/armadillo_iotg_a6e-gpio-keys_gpio-leds-howto/armadillo-iotg-a6e-gpiokeys-gpioleds.dts
[ATDE ~]$ mv armadillo-iotg-a6e-gpiokeys-gpioleds.dts linux-[VERSION]/arch/arm/boot/dts/

armadillo-iotg-a6e-gpiokeys-gpioleds.dts を使用し、.dtbo ファイルを生成します。

[ATDE ~]$ cd linux-[VERSION]
[ATDE ~/linux-[VERSION]]$ sed -i "/^\tarmadillo-iotg-a6e-at-dtweb.dtbo*/i \\\tarmadillo-iotg-a6e-gpiokeys-gpioleds.dtbo \\\\" arch/arm/boot/dts/Makefile
[ATDE ~/linux-[VERSION]]$ make ARCH=arm armadillo-iotg-a6e_defconfig
[ATDE ~/linux-[VERSION]]$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOADADDR=0x82000000 uImage -j8
[ATDE ~/linux-[VERSION]]$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8

armadillo-iotg-a6e-gpiokeys-gpioleds.dts を編集した際は、 最後のコマンドのみを再度実行します。

生成されたファイルを確認します。

[ATDE ~/linux-[VERSION]]$ ls arch/arm/boot/dts/armadillo-iotg-a6e-gpiokeys-gpioleds.dtbo
arch/arm/boot/dts/armadillo-iotg-a6e-gpiokeys-gpioleds.dtbo

これを USB メモリーなどにコピーし、Armadillo に書き込みます。 下記コマンドは、 USB メモリー(/dev/sda とする)を使用する例です。

[armadillo ~]# mount /dev/sda /mnt
[armadillo ~]# cp /mnt/armadillo-iotg-a6e-gpiokeys-gpioleds.dtbo /boot
[armadillo ~]# echo "$(cat /boot/overlays.txt)" "armadillo-iotg-a6e-gpiokeys-gpioleds.dtbo" >/boot/overlays.txt
[armadillo ~]# persist_file -rvp /boot
[armadillo ~]# reboot

コンテナの作成・ログイン

tmpfs では容量不足になる可能性があるため、 eMMC に Podman のデータが保存されるようにします。

[armadillo ~]# abos-ctrl podman-storage --disk

その際、ゲートウェイコンテナなどが実行中の場合、podman kill -a で停止させます。

コンテナをイメージをダウンロード・起動します(ネットワークに繋がっている必要があります)。

[armadillo ~]# podman run -it --rm \
> --device=/dev/input/by-path/platform-gpio-keys-howto-event:/dev/input/event0 \
> --volume=/sys:/sys docker.io/debian /bin/bash
[container /]# cd

必要なパッケージのインストール

[container ~]# apt update && apt install -y wget evtest python3 python3-pip && pip3 install evdev

入力のテスト

入力は /dev/input/event0 を通して読むことができます。 evtest 起動後に USER_SW1 を 1 回押して離すと、以下のようになります。 value はスイッチが押されているときに 1 となります。

[container ~]# evtest /dev/input/event0
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "gpio-keys-howto"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 148 (KEY_PROG1)
    Event code 149 (KEY_PROG2)
    Event code 202 (KEY_PROG3)
Properties:
Testing ... (interrupt to exit)
Event: time 1677808106.967892, type 1 (EV_KEY), code 148 (KEY_PROG1), value 1
Event: time 1677808106.967892, -------------- SYN_REPORT ------------
Event: time 1677808107.187907, type 1 (EV_KEY), code 148 (KEY_PROG1), value 0
Event: time 1677808107.187907, -------------- SYN_REPORT ------------

[Ctrl]+C で終了します。

出力のテスト

出力は /sys/class/leds/XXX/brightness を通して読み書きすることができます。 USER_LED1 は以下のように点灯・消灯することができます。 0 が消灯、0 以外が点灯です。

[container ~]# ls /sys/class/leds/
DO1  DO2  USER_LED1  app  mmc0::  mmc1::  sys  wwan  yellow
[container ~]# echo 1 > /sys/class/leds/USER_LED1/brightness
[container ~]# echo 0 > /sys/class/leds/USER_LED1/brightness

テストプログラム

下記のように動作するプログラムを作成しました。

スイッチ 押したときの動作
USER_SW1 (Armadillo 上の)LED APP のトグル
DI1 DO1 点灯
DO2 消灯
DI2 DO1 消灯
DO2 点灯

以下のように、ダウンロード・実行します。

[container ~]# wget https://download.atmark-techno.com/sample/armadillo_iotg_a6e-gpio-keys_gpio-leds-howto/howto_a6e_gpio-keys_gpio-leds.py
[container ~]# python3 howto_a6e_gpio-keys_gpio-leds.py

[Ctrl]+C で終了します。

armadillo-iotg-a6e-gpiokeys-gpioleds.dts の説明

gpio-keys-howto ノード

入出力インターフェースの接点入力 DI1,2 と、 拡張インターフェースの USER_LED1 を追加しています。

GPIO_ACTIVE_LOW はスイッチがオンになると入力が Low になる負論理回路であることを示します。 そうでない場合、GPIO_ACTIVE_HIGH とします。

また、チャタリング防止のための待ち時間を debounce_intervalで設定できます。 標準は 5ms です。

linux,code = <>; ではスイッチを押した際に発行されるキーコードを指定しています。 キーコードの一覧は include/uapi/linux/input-event-codes.h を参照してください。

gpio-leds-howto ノード

入出力インターフェースの接点出力 DO1,2 と、 拡張インターフェースの USER_LED1 を追加しています。

こちらも GPIO_ACTIVE_LOW で負論理にできます。 default-state で起動時の状態も指定できます。

USER_LED1 は点滅の仕方が CPU 負荷によって変わる heartbeat をトリガーとしています。 その他の利用できるトリガーについては、実機で以下のように確認することができます。

[armadillo ~]# cat /sys/class/leds/USER_LED1/trigger
none rc-feedback bluetooth-power rfkill-any rfkill-none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock rfkill0 rfkill1 mmc0 mmc1 timer oneshot [heartbeat] backlight gpio default-on

pinctrl_gpio_keys_howto ノード

gpio-keys-howto ノードで使用する GPIO の pinctrl の記述を行っています。 SoC と直接接続されている GPIO に関してのみ必要なので、CON6 に関しては必要ありません。

ここで、例えば USER_SW1 では上で &gpio1 1 としたので、GPIO1_IO01 のように数字を一致させます。

0x4001f008はプルアップ(22kΩ)有効、シュミットトリガ有効とする設定です。 0x40013008にすると、プルダウン(100kΩ)有効、シュミットトリガ有効になります。 内蔵プルアップ/プルダウンの抵抗は大き目でばらつきもあるので、 安定動作のために 10kΩ 程度の抵抗を使用してください。

ほかのピンを使用する際は、 arch/arm/boot/dts/armadillo-iotg-a6-expansion-interface.dtsi から、使用したいピンの MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 の部分の記述をコピーして下さい。

pinctrl_gpio_leds_howto ノード

gpio-leds-howto ノードで使用する GPIO の pinctrl の記述を行っています。 SoC と直接接続されている GPIO に関してのみ必要なので、CON6 に関しては必要ありません。

0x40013008とし、出力に設定されるまでの間は内部でプルダウンされるようにしています。