sysfs方式の概要(/sys/class/gpio・非推奨)
かつてGPIOは /sys/class/gpio 以下に echo でピン番号を書き込み、export して direction や value を操作する「sysfs方式」が主流でした。たとえば export にBCM番号を書くと gpioN ディレクトリが現れ、その中の value を読み書きします。この方式はLinux 4.8以降で非推奨(deprecated)となり、プロセスが落ちてもピンが解放されない・番号体系がボード依存といった問題があるため、新規開発では libgpiod を使うべきです。既存スクリプトの保守で見かけることがあるので、読み解ける程度に概要を押さえておきます。
libgpiodが標準になる前、LinuxでGPIOを操作する主流だったのがsysfs方式です。これは /sys/class/gpio 以下に並ぶ特別なファイルに対して、echo や cat でテキストを読み書きすることでピンを制御する仕組みでした。Linuxには「ハードウェアやカーネルの状態をファイルとして見せる」という設計思想があり、sysfsはその代表例です。GPIOもこの考え方に乗せて、ピンの向きや値を普通のファイルの読み書きとして扱えるようにしたのがこの方式でした。
この方式の魅力は、なんといっても手軽さでした。プログラミング言語の専用ライブラリやコンパイルが一切いらず、シェルから echo 一発でLEDを点けられます。シェルスクリプトだけで完結するので、入門記事・電子工作のチュートリアル・現場の運用スクリプトで非常に広く使われてきました。そのため、現在は非推奨(deprecated)になったとはいえ、世の中にはこの方式で書かれた資産がまだ大量に残っています。新規に採用することはないにせよ、古いコードを読んだり保守したりする場面のために「読んで意味が分かる」程度には押さえておく価値があります。
操作の流れ
sysfs方式の操作は、いくつかの手順を踏みます。まず使いたいピンをBCM番号で /sys/class/gpio/export に書き込みます。たとえば `echo 17 > /sys/class/gpio/export` とすると、/sys/class/gpio/gpio17 というディレクトリが新たに現れます。次にその中の direction ファイルに向きを設定します。`echo out > /sys/class/gpio/gpio17/direction` で出力、`echo in > .../direction` で入力です。出力に設定したら value ファイルへ `echo 1 > .../value` でHIGH、`echo 0` でLOWを書き込みます。入力なら `cat .../value` で現在の値(0か1)を読みます。使い終わったら、確保したピンを `echo 17 > /sys/class/gpio/unexport` で解放するのが本来の作法です。
`ls /sys/class/gpio` とすると、export・unexport といった制御用ファイルや、exportした gpioN ディレクトリが見え、構造をのぞけます。gpio17 ディレクトリの中をさらに `ls` すれば、direction・value のほか、割り込みの検出方法を指定する edge や、論理を反転させる active_low といったファイルも並んでいるのが分かります。一連の流れを言葉にすると「exportで確保 → directionで向き決め → valueで読み書き → unexportで解放」となり、libgpiodがコマンド一発で行うことを、ファイル操作として手作業で並べているとイメージすると理解しやすいでしょう。番号は基本的にBCM番号で指定するため、物理ピン番号との対応を取り違えないよう、ここでも事前のピン配置確認が前提になります。
なぜ非推奨になったのか
この方式はLinux 4.8以降で公式に非推奨(deprecated)とされました。理由はいくつかあります。第一に、ピンを確保したプロセスが途中で異常終了しても、exportしたピンが自動では解放されず、出力状態のまま取り残されてしまいます。LEDが点いたまま、あるいはモータ制御線がHIGHのまま残り、次にそのピンを使おうとした操作とぶつかる、という事故が起きやすいのです。第二に、どのプロセスがそのピンを使っているかをカーネルが把握しないため、複数のプログラムが同じピンを同時に触る衝突を防げません。早い者勝ちでも排他でもなく、ただ無防備に共有されてしまいます。第三に、ピンを番号だけで指すため、チップが複数あるボードでは番号体系が分かりにくく、ボードが変わると同じ番号が別のピンを指すなど移植性に欠けます。加えて、ファイルを開いて読み書きする方式はオーバーヘッドが大きく、高速な切り替えにも向きませんでした。これらの弱点を設計から解消したのが、チップとラインの組で管理し、プロセス終了時に確保したラインを自動解放するlibgpiodです。
既存資産との付き合い方
とはいえ、現場では古いシェルスクリプトやドキュメントがsysfs方式で書かれていることが珍しくありません。そうしたものを保守する場面では、上記の export/direction/value/unexport の対応さえ分かっていれば読み解けますし、必要ならlibgpiodの gpioget/gpioset へ書き換える指針も立ちます。読み替えの目安として、export+direction が gpioget/gpioset でのライン指定と向きの指定に、value の読み書きがそれぞれ gpioget と gpioset の値に、unexport がプロセス終了時の自動解放に対応する、と対応づけて捉えると移行がスムーズです。echo out → gpioset、cat value → gpioget、という大づかみの対応を頭に入れておくとよいでしょう。
新しいカーネルでもsysfsインターフェース自体はしばらく残されている場合がありますが、deprecated(非推奨)扱いであり、いつ削除されてもおかしくありません。したがって、新しく書くコードや教材では迷わずlibgpiodを選び、sysfs方式は「歴史的経緯と、既存スクリプトを読むための知識」として位置づけるのが、現在の妥当な向き合い方です。幸い、GPIO・プルアップ/プルダウンといった電気的・概念的な土台はどちらの方式でも共通なので、方式が変わっても本質的な理解はそのまま引き継げます。古い資産を読み解く力と、新しい標準で書く力の両方を持っておくのが、現場での強みになります。