ブログ

Armadillo Base OS:コンテナでC言語でGPIOを操作する方法

at_shinya.matsumoto
2023年9月28日 14時13分

本ブログではコンテナ内でGPIOをC言語で制御する方法を説明します。
ここではArmadillo-IoT A6Eを用いて、GPIOを制御してDI(Digital Input)とDO(Digital Output)を動作させます。

はじめに

Armadillo Base OSではeMMC(ストレージ)への書き込みを最小限にする観点から、出荷時及び運用時は
tmpfs(メモリ上に作成するファイルシステム)に保存する設定にしております。メモリ上のファイルは
電源を落とすと消えてしまう為、開発時はeMMCへ書き込む様に下記の様に設定を変更します。
※動いているコンテナがある場合は先にコンテナを停止します。

全てのコンテナを停止
#podman stop -a

ファイルをeMMCへ保存に変更するコマンド
# abos-ctrl podman-storage --disk  

ファイルをtmpfs(メモリ)へ保存に変更するコマンド
# abos-ctrl podman-storage --tmpfs 

ファイルの保存先設定を確認するコマンド
# abos-ctrl podman-storage --status 

以下、eMMCへ保存する事を前提で記載致します。

《注意》
 本ブログではArmadillo-IoT A6Eを使用しますが、プリインストールされているゲートウェイコンテナは
 デフォルトでDI/DOを使用しています。その場合、下記アプリケーションでは使用出来なくなりますので、
 上記コマンドで事前にゲートウェイコンテナを停止しておく必要があります。

作成するアプリケーション

Armadillo-IoT A6EのDI(Digital Input)、DO(Digital Output)はGPIOで操作可能な為、GPIOを操作して
値を取得するアプリケーションを作成します。配線は以下の図の様にします。

アプリケーションの内容
・DO1(gpiochip5 2)をHigh/Lowさせた時のDI1(gpiochip5 0)の値を取得する
・本ブログでは5回ループで終了させる(=コンテナが自動終了する)

実施手順

1.コンテナのコンフィグファイルを作成(デバッグ用)
2.コンテナの作成
3.アプリケーションの作成
4.コンパイル及び動作確認
5.コンテナイメージ保存~コンフィグファイル修正(自動起動用)
6.自動起動確認

1.コンテナのコンフィグファイルを作成(デバッグ用)

最初にコンテナを作成する為のコンフィグファイルを下記の様に作成します。

コンフィグファイルを作成(gpio.confはコンテナ名がgpioになります)
[Armadillo]# cat /etc/atmark/containers/gpio.conf
set_image debian:bullseye        //ここではコンテナイメージはdebian:bullseyeを使用
add_devices /dev/gpiochip5     //制御したいgpiochipを選択(DI/DOはgpiochip5)
add_args -it                     //デバッグ時は必須
set_autostart no                   //デバッグ時は必須
set_command /bin/bash           //デバッグ時は必須(shでも可)

コンフィグファイルをeMMCに保存(=電源OFFで消えない)
[Armadillo]# persist_file /etc/atmark/containers/gpio.conf

以上でコンフィグファイル作成は完了です。

2.コンテナの作成

アプリケーションをコンテナ内で作成する為、コンテナイメージをダウンロード、
コンテナ作成~起動、コンテナに入ります。

コンテナイメージのダウンロード
[Armadillo]# podman pull docker.io/debian:bullseye

コンテナ作成~起動
[Armadillo]# podman_start gpio

コンテナに入る
[Armadillo]# podman attach gpio

3.アプリケーションの作成

コンテナ内で開発に必要なパッケージをインストールします。
gpioを制御する為に libgpiod2をインストールします。

必要なパッケージのインストール
[container]# apt update && apt install vim build-essential libgpiod2 libgpiod-dev

ソースコードの作成
[container]# cd       // /rootに移動

下記のサンプルコードを作成
[container]# cat gpio.c
#include <stdio.h>
#include <unistd.h>
#include <gpiod.h>

int main(void)
{
  const char *appname = "gpiotest";
  const char *chipname = "gpiochip5";     //gpiochip5を指定
  struct gpiod_chip *chip;

  struct gpiod_line *line_in, *line_out;
  int value,loop=0;

  chip = gpiod_chip_open_by_name(chipname);   //デバイスをオープン

  line_in=gpiod_chip_get_line(chip, 0);      //DI1のハンドラを取得(gpiochip5 0)
  gpiod_line_request_input(line_in, appname);   //DI1を入力モードに設定

  line_out=gpiod_chip_get_line(chip, 2);    //DO1のハンドラを取得(gpiochip5 2)
  gpiod_line_request_output(line_out, appname, 1);   //DO1を出力モードで初期値1(High)に設定

  while(loop<5){
     if(loop%2==0){
        gpiod_line_set_value(line_out, 1);     //DO1を1(High)に設定
     }
     else{
        gpiod_line_set_value(line_out, 0);     //DO1を0(Low)に設定
     }

     sleep(1);

     value=gpiod_line_get_value(line_in);   //DI1の値を取得
     printf("DI1: %d\n", value);
     loop++;
  }

  gpiod_line_release(line_in);      //ポート予約の解除
  gpiod_line_release(line_out);   //ポート予約の解除
  gpiod_chip_close(chip);         //デバイスをクローズ

  return 0;
}

4.コンパイル及び動作確認

ソースファイルを作成したらコンパイルし、動作確認します。

コンパイル
[container]# gcc gpio.c -o gpio.exe -lgpiod

動作確認(DI1が交互に0/1反転していればOK)
[container]# ./gpio.exe
DI1: 1
DI1: 0
DI1: 1
DI1: 0
DI1: 1

以上でコンテナは作成完了の為、コンテナから出る
[container]# exit

5.コンテナイメージ保存~コンフィグファイル修正(自動起動用)

作成したコンテナ(アプリケーション)をコンテナイメージとして保存します。
ここではコンテナイメージ名をimage_gpio、タグ名をv1.0としています。
※製品のCPUやコンテナサイズによっては時間が掛かる場合があります。

[armadillo]# podman commit gpio image_gpio:v1.0

次に、コンテナを自動起動させる為にコンテナのコンフィグファイルを編集します。

コンフィグファイルを自動起動用に編集
[Armadillo]# cat /etc/atmark/containers/gpio.conf
set_image image_gpio:v1.0        //保存したコンテナイメージを指定
add_devices /dev/gpiochip5
set_command /root/gpio.exe    //gpio.exeを実行に設定

コンフィグファイルをeMMCに保存
[Armadillo]# persist_file /etc/atmark/containers/gpio.conf

6.自動起動確認

最後に abos-ctrl podman-storage --tmpfs に変更し、実運用と同じコンテナをRAM上に展開する
設定にして動作確認します。

コンテナをRAM上に展開する設定に変更
[armadillo]# abos-ctrl podman-storage --tmpfs
List of images configured on development storage:
REPOSITORY                TAG            IMAGE ID      CREATED                 SIZE
docker.io/library/debian  bullseye       5184fee18788  Less than a second ago  105 MB
localhost/image_gpio      v1.0           0c8f72921f19  16 minutes ago          386 MB

What should we do? ([C]opy (default), [N]othing, [D]elete)    //ここではcを選択
c
<以下略>

reboot前に動作確認
[armadillo]# podman_start gpio

rebootで自動起動させて動作確認
[armadillo]# reboot

以上、で完了となります。

参考情報

ビルドツールの様な運用時には不要なパッケージやファイルは無い方が望ましいですが、
コンテナはレイヤー構造になっている為、削除してもコンテナサイズが変化しません。
そこで、ビルドだけ別のコンテナで実行し、実行ファイル(+その他必要なものは別途
インストールが必要)のみ別のコンテナにコピーする方法として下記を紹介致します。

Armadillo Base OS:Dockerfileを用いたコンテナイメージ作成方法