概要
オンライン上にあるGPIOに関するドキュメントの多くは、ArduinoおよびRaspberry PiのようなSoCを対象にしている。
SoCとは異なり、GPIOのあるPCはGPIOピンをCPUに直接統合していないが、スーパーI/Oチップ (SIO) を使用している。
GPIOへのアクセス
多くのLinuxディストリビューションにおいて、GPIOを扱うことができる。
最近のLinuxでは、/dev/gpiochip[n]キャラクタデバイスをマウントするカーネルモジュールを通して、GPIOを公開している。
GPIOと対話するための推奨ユーティリティは、gpiodである。
これは、GPIOの値の列挙、読み取り、書き込みを行うための一連のCLIを提供するものである。
ただし、/dev/gpiochip[n]キャラクタデバイスが無い場合は、Linuxカーネルがハードウェアのドライバが読み込まれていない。
BIOS / UEFIの設定
BIOS / UEFIにおいて、GPIOへのアクセスを提供する必要がある。
- まず、BIOS / UEFIの画面から、[Advanced]タブにある[SIO MISC Configuration]メニューから、[WDT, CASE OPEN, GPIO, DEBUG...]を選択する。
- [WDT, CASE OPEN, GPIO, DEBUG...]画面では、ウォッチドッグタイマ、2つのCOMポートモード (RS232、RS485、RS422)、複数のGPIO設定へのアクセス可否の設定がある。
- GPIOの設定
- 各ピンはGPIO[n]という名前である。 (nは0以上の数値)
- モードは入力または出力で設定できる。
- [Output]に設定すると、出力値を
Low
またはHigh
に設定することができる。 - 使用する予定の全てのGPIOピンの機能をマッピングすること。
- GPIOの設定
例えば、以下に示すように、GPIOピンはPCケースに表示されているように、左から右に番号が付けられている。
以下の例では、上段は3.3[V]出力、GPIOピン 4本、GNDピン 2本、下段は3.3[V]出力、GPIOピン 4本、12[V]および5[V]出力がある。
1 2 3 4 5 6 7 3V3 7 6 5 4 GND GND --------------------------- 3V3 3 2 1 0 12V 5V 1 2 3 4 5 6 7
スーパーI/Oチップ名の確認
BIOS / UEFIには、どのスーパーI/Oチップが使用されているか表示されていない場合もある。
スーパーI/Oチップの名前を確認する場合は、PCケースを開けて、GPIOピンの付近にあるチップの表面に描かれているシルク等で確認する。
スーパーI/Oチップのカーネルモジュールの有効化
まず、付属しているスーパーI/Oチップのカーネルモジュールを知りたい場合は、Linux KernelのGithubにあるgit repoから、スーパーI/Oチップ名で検索する。
以下の例では、スーパーI/Oチップ名が"iTE IT8786E-I"の場合である。
repo:torvalds/linux iTE IT8786E-I
/* gpio-it78.c */
/*
* GPIO interface for IT87xx Super I/O chips
*
* Author: Diego Elio Pettenò <flameeyes@flameeyes.eu>
* Copyright (c) 2017 Google, Inc.
*
* Based on it87_wdt.c by Oliver Schuster
* gpio-it8761e.c by Denis Turischev
* gpio-stmpe.c by Rabin Vincent
*/
# Makefile
# ※ "CONFIG_GPIO_IT87"という部分の文字列を控えておくこと
obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
Kconfig snippet: config GPIO_IT87 tristate "IT87xx GPIO support" help Say yes here to support GPIO functionality of IT87xx Super I/O chips. This driver is tested with ITE IT8728 and IT8732 Super I/O chips, and supports the IT8761E, IT8613, IT8620E, and IT8628E Super I/O chips as well. To compile this driver as a module, choose M here: the module will be called gpio_it87.
スーパーI/Oチップ名を確認して、該当するカーネルモジュールが読み込まれているかどうかを確認する。
grep CONFIG_GPIO_IT87 /boot/config-$(uname -r) # 出力例: # mと出力される場合、そのカーネルモジュールがデフォルトでは無効であることを意味する CONFIG_GPIO_IT87=m
スーパーI/Oチップのカーネルモジュールを有効にする。
sudo modprobe gpio_it87
GPIOピンの入出力に関する設定はBIOS / UEFIを通してのみ変更可能であり、GPIOの値を設定 / 取得する場合はスーパーユーザ権限が必要である。
もし、gpiolibのピン番号がBIOS / UEFIのピン番号と一致しない場合は、各ピンをブレッドボード上のLEDに接続して、以下のようなシェルスクリプトを実行する。
以下の例では、チップセット0の全ピンを1秒間ごとにトグルしている。
ただし、実行前に、BIOS / UEFIにおいて、全てのGPIOピンを出力モードに割り当てること。
for i in $(seq 0 63)
do
echo -n "$i on "
sudo gpioset 0 "$i=1"
sleep 1
echo off
sudo gpioset 0 "$i=0"
done
エラー
GPIOピンの入力を開放する場合
GPIOピンを入力設定 (プルダウンオプションを付加) にして開放する場合、該当ピンの状態を確認するとHigh
を返す場合がある。
sudo gpioget -B pull-down 0 0 # 出力例: 1
これを解決するには、外付けのプルダウン抵抗を追加することである。
1[K]、10[K]、100[K]のプルダウン抵抗を試して、カット&トライすること。