GPIO 應用:
√ Input
- 用來讀取 Input 資料 (通常為 high or low, 對接的可能為 push button 這類設備)
√ Output
- 可讀寫 output 之值 (對接的可能為 LED, Buzzer, Power PIN 這類設備)
note: 因為電路設計的關係, GPO 不一定為 active – high (“1″ 代表 “active", 預設值), 有可能為 active-low (“0″ 代表 “active"). 所以這邊需要根據電路設計將設定寫入 device tree 中. 可參考include/dt-bindings/gpio/gpio.h 中的定義
√ IRQ
- 用來處理 IRQs 相關 (通常為 wakeup 事件)
√ 其他
- bit banging – 用軟體來模擬硬體的行為. 也就是透過程式來控制 GPIO 以模擬 I2C, SPI 等等硬體訊號
- 設定成 特定裝置的 write protect PIN
詳情可見下表
提供 GPIO 介面的裝置:
√ System-on-Chip (SOC) processors
- SoC 上的 PIN 通常都是 multi-function PIN, 而其中大部份都能夠設定成 GPIO 來使用
√ Programmable logic devices (like FPGAs)
√ Peripheral module
- PMIC
- Audio codecs
- watchdog
√ Expanders
- 透過 I2C or SPI 介面來外接 expanders 以拓展 GPIO 數量
GPIO User Space Subsystem in Linux
√ GPIO numbers – /sys/class/gpio (傳統方法, 不建議使用)
過往傳統都是使用 sysfs 來對 GPIO 操作, 一般使用方式如下:
1. 先算好 GPIO number
2. 開啟 GPIO
- echo {number} >/sys/class/gpio/export
3. 設定 GPIO direction
- echo “out” > /sys/class/gpio/gpio{number} /direction
4. 設定 Output value
- echo 1 > /sys/class/gpio/gpio{number}/value
5. 關閉 GPIO
- echo {number} >/sys/class/gpio/unexport
但以上操作容易造成下列問題:
- 多個程式可同時存取 sysfs 底下的 GPIO 相關操作
- 若程式不正常結束, GPIO 不會被關閉
- GPIO 的 number 會因為開機順序而有所變動
- 此外, 由下圖可知, 單一 GPIO 下的屬性多又雜, 除了權限皆固定外, 存取 value or event 方式也很麻煩 – 需要以 polling 方式來搭配 lseek or reopen
√ GPIO descriptors – /dev/gpiochipN (建議使用) – kernel 4.8 開始支援

基於不重新造輪子的概念, 現在想要在新架構下存取 GPIO, 可透過 libgpiod [7].

- gpiodetect – 確認系統上有哪些 GPIO 裝置, 並列出 label 以及 GPIO line 數量
- gpiofind – 依照名稱來找尋 GPIO line
- gpioget – 從 GPIO 裝置上讀取 line 的值
- gpioset – 從 GPIO 裝置上設定 line 的值
- gpioinfo – 列出指定的 GPIO 裝置上所有 GPIO line 資訊. 若不指定, 則列出所有 GPIO 裝置資訊
- gpiomon – 監控 GPIO line 上的事件 (使用 poll 函式)
心得:
References:
[1]: Learn More About Linux’s New GPIO User Space Subsystem & Libgpiod
[2]: New GPIO Interface for User Space
https://schd.ws/hosted_files/osseu17/88/elce2017_new_GPIO_interface.pdf
[3] General purpose input/output
https://en.wikipedia.org/wiki/General-purpose_input/output
[4] Bit banging
https://en.wikipedia.org/wiki/Bit_banging
[5] https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt
[6] https://www.kernel.org/doc/Documentation/gpio/
[7] https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/
[8] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=61f922db72216b00386581c851db9c9095961522
[9] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/gpio/lsgpio.c
[10] https://packages.debian.org/sid/gpiod