(と思ってるけど、実はあるのだろうか・・)
例えば、GPIO23に出力するとき、コンソールで以下のようにします。
> echo 23 > /sys/class/gpio/export > echo "out" > /sys/class/gpio/gpio23/direction > echo 1 > /sys/class/gpio/gpio23/value
この操作を、実機ではなくPC上で行おうとすると、
最初の exportへ23を書き込む ところで、引数エラーになります。
> echo 23 > /sys/class/gpio/export echo: 書き込みエラー: 無効な引数です
dmesgで見ると、以下のメッセージが出力されています。
> dmesg ~省略~ [ 955.6530668] export_store: invalid GPIO 23
これを出してるのは、linux v4.18.0 のカーネルソースを見ると、
以下の場所で出力しているようです。
/drivers/gpio/gpiolib-sysfs.c
453 static ssize_t export_store(struct class *class, 454 struct class_attribute *attr, 455 const char *buf, size_t len) 456 { ~省略~ 465 desc = gpio_to_desc(gpio); 466 /* reject invalid GPIOs */ 467 if (!desc) { 468 pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); 469 return -EINVAL; 470 }
エラーになってるのはgpio_to_desc関数で、引数gpioに対応する
ディスクリプタを返すが、このディスクリプタはカーネルソース内で
チップ情報によって作成されています。つまり、この動作を変えるには、
カーネルソースの再ビルドが必要となりそうです。
なので、GPIO操作のテストには実機が必要だが、現場では数人で
実機を共有しているので、気軽にテストできません。
ようやく実機使えてテストしたら、「不等号の向き間違えた」なんかの
つまらないバグが出ると、時間の無駄だし、気が滅入ってきます。
なので、PC上でコーディングミスレベルの不具合は潰しておきたい。
PC上での方法を考えると、デバッグ時は/sys/class/gpio/gpioN/value を
mkfifo で作ったパイプで代替する方法をしている人が、私の職場でいました。
しかし、これは、書き込み側は動作は変わらないが、読み出し側がパイプを
readしたときに書き込みがあるまで関数がブロックしてしまいます。
また、読み出しが遅い場合、書き込みを、例えば2回1を書き込んだ場合、
読み出すと11になるので、一文字ずつ処理するなど、実機の場合には
不要な処理を足さなくてはならないので面倒です。
カーネルソースのgpiolib-sysfs.cを見ていると、実ポートには出力せず、
メモリ上の値を読み書きするだけの、GPIOの動作を模擬できる
仮想GPIOドライバが作れそうです。
というわけで、このゴールデンウィーク中に仮想GPIOドライバを
作ってみることにしました。