適用於使用者空間的 GPIO Sysfs 介面¶
警告
此 API 已被GPIO 字元裝置使用者空間 API廢棄,且 ABI 文件已移至ABI 檔案 obsolete/sysfs-gpio。
新的開發應使用GPIO 字元裝置使用者空間 API,並鼓勵現有開發儘快遷移,因為此 API 將來會被移除。
此介面在遷移期間將繼續維護,但新功能只會新增到新的 API 中。
廢棄的 sysfs ABI¶
使用“gpiolib”實現者框架的平臺可以選擇配置一個 sysfs 使用者介面來訪問 GPIO。這與 debugfs 介面不同,因為它提供對 GPIO 方向和值的控制,而不僅僅是顯示 GPIO 狀態摘要。此外,它可以在沒有除錯支援的生產系統上存在。
如果系統有適當的硬體文件,使用者空間例如可以知道 GPIO #23 控制用於保護快閃記憶體中引導載入器段的防寫線。系統升級過程可能需要暫時移除該保護,首先匯入一個 GPIO,然後改變其輸出狀態,接著更新程式碼,最後重新啟用防寫。在正常使用中,GPIO #23 永遠不會被觸及,核心也無需瞭解它。
同樣,根據適當的硬體文件,在某些系統上,使用者空間 GPIO 可以用於確定標準核心無法瞭解的系統配置資料。對於某些任務,簡單的使用者空間 GPIO 驅動程式可能就是系統真正所需的全部。
Sysfs 中的路徑¶
/sys/class/gpio 中有三種條目:
用於獲取使用者空間對 GPIO 控制的介面;
GPIO 本身;以及
GPIO 控制器(“gpio_chip”例項)。
這些是除了包括“device”符號連結在內的標準檔案之外的。
控制介面是隻寫(write-only)的
/sys/class/gpio/
- “export”...
使用者空間可以透過將 GPIO 號寫入此檔案來請求核心將 GPIO 的控制權匯出到使用者空間。
示例:“echo 19 > export”將為 GPIO #19 建立一個“gpio19”節點,如果核心程式碼尚未請求此節點。
- “unexport”...
撤銷匯出到使用者空間的效果。
示例:“echo 19 > unexport”將移除使用“export”檔案匯出的“gpio19”節點。
GPIO 訊號的路徑類似於 /sys/class/gpio/gpio42/(對於 GPIO #42),並具有以下讀/寫屬性:
/sys/class/gpio/gpioN/
- “direction”...
讀取時為“in”或“out”。此值通常可以寫入。寫入“out”時,預設將值初始化為低電平。為確保無毛刺操作,可以寫入“low”和“high”值,以將 GPIO 配置為具有該初始值的輸出。
請注意,如果核心不支援更改 GPIO 的方向,或者它是由未明確允許使用者空間重新配置此 GPIO 方向的核心程式碼匯出的,則此屬性將不存在。
- “value”...
讀取時為 0(非啟用)或 1(啟用)。如果 GPIO 配置為輸出,則可以寫入此值;任何非零值都被視為啟用。
如果引腳可以配置為中斷生成輸入,並且已配置為生成中斷(參見“edge”的描述),則可以對此檔案進行 poll(2) 操作,當中斷觸發時 poll(2) 將返回。如果使用 poll(2),請設定事件 POLLPRI 和 POLLERR。如果使用 select(2),請在 exceptfds 中設定檔案描述符。poll(2) 返回後,使用 pread(2) 讀取偏移量為零的值。或者,可以 lseek(2) 到 sysfs 檔案的開頭並讀取新值,或者關閉檔案並重新開啟以讀取值。
- “edge”...
讀取時為“none”、“rising”、“falling”或“both”。寫入這些字串以選擇在“value”檔案上進行 poll(2) 操作時將使其返回的訊號邊沿。
此檔案僅在引腳可以配置為中斷生成輸入引腳時存在。
- “active_low”...
讀取時為 0(假)或 1(真)。寫入任何非零值以反轉值屬性,無論是讀取還是寫入。現有和後續的 poll(2) 透過 edge 屬性對“上升”和“下降”邊沿的支援配置將遵循此設定。
GPIO 控制器的路徑類似於 /sys/class/gpio/gpiochip42/(用於實現從 #42 開始的 GPIO 的控制器),並具有以下只讀屬性:
/sys/class/gpio/gpiochipN/
- “base”...
與 N 相同,此晶片管理的第一個 GPIO
- “label”...
用於診斷(不總是唯一的)
- “ngpio”...
此晶片管理多少個 GPIO(N 到 N + ngpio - 1)
在大多數情況下,板級文件應該涵蓋 GPIO 的用途。然而,這些編號並不總是穩定的;子卡上的 GPIO 可能會因所使用的基板或堆疊中的其他卡而異。在這種情況下,您可能需要使用 gpiochip 節點(可能結合原理圖)來確定給定訊號應使用的正確 GPIO 編號。
從核心程式碼匯出¶
核心程式碼可以顯式管理已使用 gpio_request() 請求的 GPIO 的匯出。
/* export the GPIO to userspace */
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
/* reverse gpiod_export() */
void gpiod_unexport(struct gpio_desc *desc);
/* create a sysfs link to an exported GPIO node */
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
在核心驅動程式請求一個 GPIO 後,它只能透過gpiod_export()在 sysfs 介面中可用。驅動程式可以控制訊號方向是否可以改變。這有助於驅動程式防止使用者空間程式碼意外破壞重要的系統狀態。
這種顯式匯出有助於除錯(透過使某些實驗更容易),或者可以提供一個始終存在的介面,適合作為板級支援包的一部分進行文件化。
GPIO 匯出後,gpiod_export_link()允許從 sysfs 中的其他位置建立指向 GPIO sysfs 節點的符號連結。驅動程式可以使用此功能在 sysfs 中其自己的裝置下提供帶有描述性名稱的介面。