2019/05/06

仮想GPIOドライバひとまず完成

仮想GPIOドライバがひとまず完成しました。

GitHubの以下の場所にアップしています。
vgpio

動作確認は、ubuntu 18.04 (2019/05/06時点のupdate済)でしました。

●使い方
0.ビルドする。
cd vgpio
make
→vgpio.koができる。

1.ドライバをinsmodする。
sudo insmod vgpio.ko
→/sys/kernel/vgpioができる。

2.使いたいGPIOポートを作成する。
(例)GPIO23を作成する場合
echo 23 > /sys/kernel/vgpio/export
→GPIO23ができる。

あとは、通常のGPIOと同じ使い方です。

3.direction、value、edge、active_lowを読み書きする。
(例)GPIO23を入力モードにして、1回読み出す
echo "in" > /sys/kernel/vgpio/gpio23/direction
cat /sys/kernel/vgpio/gpio23/value


4.もう使わない場合は、vgpio.koをrmmodする
sudo rmmod vgpio.ko
→/sys/kernel下のvgpioと、作っていたgpio23が消える。
※作成したGPIOポートは、unexport操作しなくても
rmmodすると自動的にunexportします。

使い方は以上です。

●注意点
※1.本物のGPIOは、入力モードに設定しているので
書き込みはできませんが、この仮想GPIOでは、
入力モードでも書き込みができてしまいます。
デバッグで、GPIOの値を変える場合は、別コンソールで
echoなどでvalueの値を書き換えてください。

※2.select/pollのシステムコールが、現在使えません。
すぐできそうですですが、私がやりたいことは
現状でできたので、とりあえずこのままにします。

----------------------------------------------------------

この仮想GPIOドライバは、linuxカーネルのリポジトリの
以下のファイルを参考にしました。

v4.18
/samples/kobject/kobject-example.c
/drivers/gpio/gpiolib-sysfs.c

・アクセス権について
本物のGPIOでは、otherのアクセス権が読出しのみになっています。
これはカーネルレベルで制限かけられていました。
/include/linux/kernel.h VERIFY_OCTAL_PERMISSIONSマクロ
/fs/sysfs/group.c create_files関数

ラズベリーパイなどでは、GPIO操作用のGPIOグループがあり、
piユーザはGPIOグループに属しており、
GPIOの各属性にGPIOグループで読み書きしているようです。

PCでデバッグするとき、GPIOグループ作って、各属性を
GPIOグループに変えて、GPIOグループへの権限を変えて・・・
ということをいちいちするのは面倒なので、
仮想GPIOドライバではちょっと細工して、otherでも読み書き
できるようにしました。

・select/poll対応について
現在はできません。なので、edgeになにか書き込んでも
特に影響ありません。(書き込み自体はできます)
カーネルの以下の機能を使えばできそうであることはわかっています。
sysfs_get_dirent()  edgeがnone以外が書き込まれたら、kernfs_nodeを取得する
sysfs_notify_dirent() valueが変化したら、kernfs_nodeにイベント発生を通知する
sysfs_put() edge、active_lowが変化したら、kernfs_nodeを解放する

2019/05/03

仮想GPIOを/sys/class以下に作ってみたものの

仮想GPIOドライバをとりあえず作ってみました。
設定値をメモリ上にとって、gpiochipへの読み書きを
メモリの値に置き換えるだけなので、とりあえず動くものは
すぐにできました。

gpiolib-sysfs.cを参考にして、/sys/class以下に
vgpioという名前のディレクトリを作って、
その配下にexport等を作るようにしました。
しかし、同時に/sys/devices/virtual/vgpioもできてしまう。

また、動作させてexportへ任意の番号を書き込むとgpioNができるが、
このエイリアスが/sys/devices/virtual/vgpio/gpioNになり、
direction、value、edge、active_low以外にpower、uevent等
よくわからないものがたくさんできていました。

ただ direction/value/edge/active_low だけ読み書きできれば
良いのですが・・他のはsysfsのclassAPIが作ってるものなので、
なにか意図しないことが起きるかもしれない・・

というわけで、別の方法を模索してみます。

linux kernelのリポジトリを見ると、/samples/kobject があります。
これは、/sys/kernel以下にアトリビュートというファイルのようなものを
作って読み書きするサンプルです。
(sysfsはファイルではなくアトリビュートと言う)
これが、ほぼやりたいことをしているので、これを参考にして作り直します。
こんなのがあったんだな。