拡張インターフェースで入出力を行う方法 (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
とし、出力に設定されるまでの間は内部でプルダウンされるようにしています。