Howto

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

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

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

CON11 に関しては、Armadillo-IoT G4 もまったく同じ仕様です。

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

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

必要な回路

1.8V レベルの入出力を使用する場合、 MOSFETの選定において、オン電圧に注意してください。

Armadillo-X2 ではCON16 の VEXT_3V3 から 3.3V 電源を取ることもできます。

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

使用ソフトウェア

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

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

Device Tree のカスタマイズ

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

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

ダウンロードページ(Armadillo-X2) ダウンロードページ(Armadillo-IoT G4)

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

[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_x2-gpio-keys_gpio-leds-howto/armadillo_iotg_g4-gpiokeys-gpioleds.dts
[ATDE ~]$ mv armadillo_iotg_g4-gpiokeys-gpioleds.dts linux-[VERSION]/arch/arm64/boot/dts/freescale/

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

[ATDE ~]$ cd linux-[VERSION]
[ATDE ~/linux-[VERSION]]$ sed -i "/^dtb-\$(CONFIG_ARCH_MXC) += armadillo_iotg_g4-at-dtweb.dtbo/i \\dtb-\$(CONFIG_ARCH_MXC) += armadillo_iotg_g4-gpiokeys-gpioleds.dtbo\\" arch/arm64/boot/dts/freescale/Makefile
[PC ~/linux-[VERSION]]$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- x2_defconfig
[PC ~/linux-[VERSION]]$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8

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

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

[ATDE ~/linux-[VERSION]]$ ls arch/arm64/boot/dts/freescale/armadillo_iotg_g4-gpiokeys-gpioleds.dtbo
arch/arm64/boot/dts/freescale/armadillo_iotg_g4-gpiokeys-gpioleds.dtbo

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

[armadillo ~]# mount /dev/sda /mnt
[armadillo ~]# cp /mnt/armadillo_iotg_g4-gpiokeys-gpioleds.dtbo /boot
[armadillo ~]# if [ ! -f /boot/overlays.txt ]
[armadillo ~]# then echo "fdt_overlays=armadillo_iotg_g4-gpiokeys-gpioleds.dtbo" > /boot/overlays.txt
[armadillo ~]# else echo "$(cat /boot/overlays.txt)" "armadillo_iotg_g4-gpiokeys-gpioleds.dtbo" >/boot/overlays.txt
[armadillo ~]# fi
[armadillo ~]# persist_file -rvp /boot
[armadillo ~]# reboot

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

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

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

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

[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 1677808703.540358, type 1 (EV_KEY), code 148 (KEY_PROG1), value 1
Event: time 1677808703.540358, -------------- SYN_REPORT ------------
Event: time 1677808703.948360, type 1 (EV_KEY), code 148 (KEY_PROG1), value 0
Event: time 1677808703.948360, -------------- SYN_REPORT ------------

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

出力のテスト

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

[container ~]# ls /sys/class/leds/
FW_UPDATE_IND  STDWN_IND  USER_LED2  enet1_led3  led1    mmc2::
PWR_IND        USER_LED1  USER_LED3  enet_led3   mmc1::
[container ~]# echo 1 > /sys/class/leds/USER_LED1/brightness
[container ~]# echo 0 > /sys/class/leds/USER_LED1/brightness

テストプログラム

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

スイッチ 動作
USER_SW1 (Armadillo 上の)LED1 のトグル
USER_SW2 USER_LED2 の点灯
USER_LED3 の消灯
USER_SW3 USER_LED2 の消灯
USER_LED3 の点灯

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

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

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

armadillo_iotg_g4-gpiokeys-gpioleds.dts の説明

gpio-keys-howto ノード

拡張インターフェースの USER_LED1,2,3 を追加しています。

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 mmc2 timer oneshot mtd nand-disk [heartbeat] activity default-on panic pattern mmc1 30be0000.ethernet-1:00:link 30be0000.ethernet-1:00:1Gbps 30be0000.ethernet-1:00:100Mbps 30be0000.ethernet-1:00:10Mbps

pinctrl_gpio_keys_howto ノード

gpio-keys-howto ノードで使用する GPIO の pinctrl の記述を行っています。

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

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

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

pinctrl_gpio_leds_howto ノード

gpio-leds-howto ノードで使用する GPIO の pinctrl の記述を行っています。

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