GPIO 聚合器

GPIO 聚合器提供了一種聚合 GPIO 並將其作為新的 gpio_chip 公開的機制。這支援以下用例。

使用 Sysfs 聚合 GPIO

GPIO 控制器使用 /dev/gpiochip* 字元裝置匯出到使用者空間。 對這些裝置的訪問控制由標準的 UNIX 檔案系統許可權提供,以全有或全無為基礎:要麼使用者可以訪問 GPIO 控制器,要麼不能訪問。

GPIO 聚合器透過將一組或多個 GPIO 聚合到一個新的 gpio_chip 中來提供對 GPIO 的訪問控制,該 gpio_chip 可以使用標準的 UNIX 檔案所有權和許可權分配給組或使用者。此外,這簡化並加強了將 GPIO 匯出到虛擬機器,因為 VM 可以只獲取完整的 GPIO 控制器,不再需要關心要獲取哪些 GPIO 以及不獲取哪些 GPIO,從而減少了攻擊面。

聚合的 GPIO 控制器透過寫入 sysfs 中的只寫屬性檔案來例項化和銷燬。

/sys/bus/platform/drivers/gpio-aggregator/

“new_device” ...

使用者空間可以要求核心例項化一個聚合的 GPIO 控制器,方法是寫入一個字串,描述要聚合到 “new_device” 檔案中的 GPIO,使用以下格式

[<gpioA>] [<gpiochipB> <offsets>] ...

哪裡

“<gpioA>” ...

是 GPIO 線名稱,

“<gpiochipB>” ...

是一個 GPIO 晶片標籤,並且

“<offsets>” ...

是由破折號分隔的 GPIO 偏移量和/或 GPIO 偏移量範圍的逗號分隔列表。

示例:透過將 “e6052000.gpio” 的 GPIO 線 19 和 “e6050000.gpio” 的 GPIO 線 20-21 聚合到一個新的 gpio_chip 中來例項化一個新的 GPIO 聚合器

$ echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
“delete_device” ...

使用者空間可以要求核心在使用後透過將其裝置名稱寫入 “delete_device” 檔案來銷燬聚合的 GPIO 控制器。

示例:銷燬先前建立的聚合 GPIO 控制器,假設為 “gpio-aggregator.0”

$ echo gpio-aggregator.0 > delete_device

使用 Configfs 聚合 GPIO

組: /config/gpio-aggregator

這是 gpio-aggregator configfs 樹的根目錄。

組: /config/gpio-aggregator/<example-name>

此目錄表示 GPIO 聚合器裝置。您可以為 <example-name> 分配任何名稱(例如 agg0),除了以 _sysfs 字首開頭的名稱,這些名稱保留用於透過 Sysfs 建立的裝置自動生成的 configfs 條目。

屬性: /config/gpio-aggregator/<example-name>/live

live 屬性允許在完全配置裝置後觸發裝置的實際建立。接受的值是

  • 1, yes, true : 啟用虛擬裝置

  • 0, no, false : 停用虛擬裝置

屬性: /config/gpio-aggregator/<example-name>/dev_name

只讀 dev_name 屬性公開裝置在平臺上出現在系統中的名稱(例如 gpio-aggregator.0)。這對於識別新建立的聚合器的字元裝置很有用。如果它是 gpio-aggregator.0,則 /sys/devices/platform/gpio-aggregator.0/gpiochipX 路徑告訴您 GPIO 裝置 ID 是 X

您必須為您要例項化的每個虛擬行建立子目錄,精確命名為 line0, line1, ..., lineY,當您要例項化 Y+1 (Y >= 0) 行時。透過將 live 設定為 1,在啟用裝置之前配置所有行。

組: /config/gpio-aggregator/<example-name>/<lineY>/

此目錄表示要包含在聚合器中的 GPIO 線。

屬性: /config/gpio-aggregator/<example-name>/<lineY>/key

屬性: /config/gpio-aggregator/<example-name>/<lineY>/offset

建立 <lineY> 目錄後的預設值是

  • key : <empty>

  • offset : -1

key 必須始終顯式配置,而 offset 取決於情況。每個 <lineY> 存在兩種配置模式

(a). 對於透過 GPIO 線名稱查詢

  • key 設定為線名稱。

  • 確保 offset 保持 -1(預設值)。

(b). 對於透過 GPIO 晶片名稱和晶片內的線偏移量查詢

  • key 設定為晶片名稱。

  • offset 設定為線偏移量 (0 <= offset < 65535)。

屬性: /config/gpio-aggregator/<example-name>/<lineY>/name

name 屬性為 lineY 設定自定義名稱。如果未設定,則該行將保持未命名。

配置完成後,必須將 'live' 屬性設定為 1,以便例項化聚合器裝置。可以將其設定回 0 以銷燬虛擬裝置。該模組將同步等待新的聚合器裝置成功探測,如果未發生這種情況,寫入 'live' 將導致錯誤。這與使用 sysfs new_device 介面建立它時的行為不同。

注意

對於透過 Sysfs 建立的聚合器,configfs 條目是自動生成的,並顯示為 /config/gpio-aggregator/_sysfs.<N>/。您無法使用 mkdir(2)/rmdir(2) 新增或刪除行目錄。要修改行,您必須使用 “delete_device” 介面來拆除現有裝置並從頭開始重新配置它。但是,您仍然可以使用 live 屬性切換聚合器,並在手動將 live 設定為 0 時調整每行的 key, offsetname 屬性(即,它不等待延遲探測)。

示例配置命令

# Create a directory for an aggregator device
$ mkdir /sys/kernel/config/gpio-aggregator/agg0

# Configure each line
$ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0
$ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key
$ echo 6         > /sys/kernel/config/gpio-aggregator/agg0/line0/offset
$ echo test0     > /sys/kernel/config/gpio-aggregator/agg0/line0/name
$ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1
$ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key
$ echo 7         > /sys/kernel/config/gpio-aggregator/agg0/line1/offset
$ echo test1     > /sys/kernel/config/gpio-aggregator/agg0/line1/name

# Activate the aggregator device
$ echo 1         > /sys/kernel/config/gpio-aggregator/agg0/live

通用 GPIO 驅動程式

GPIO 聚合器也可以用作 DT 中描述的簡單 GPIO 操作裝置的通用驅動程式,而無需專用的核心驅動程式。這在工業控制中很有用,並且與例如 spidev 非常相似,它允許使用者從使用者空間與 SPI 裝置通訊。

將裝置繫結到 GPIO 聚合器可以透過修改 gpio-aggregator 驅動程式或寫入 Sysfs 中的 “driver_override” 檔案來執行。

示例:如果 “door” 是 DT 中描述的 GPIO 操作裝置,使用其自己的相容值

door {
        compatible = "myvendor,mydoor";

        gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>,
                <&gpio2 20 GPIO_ACTIVE_LOW>;
        gpio-line-names = "open", "lock";
};

可以透過以下任一方式將其繫結到 GPIO 聚合器

  1. 將其相容值新增到 gpio_aggregator_dt_ids[],

  2. 使用 “driver_override” 手動繫結

$ echo gpio-aggregator > /sys/bus/platform/devices/door/driver_override
$ echo door > /sys/bus/platform/drivers/gpio-aggregator/bind

之後,已建立一個新的 gpiochip “door”

$ gpioinfo door
gpiochip12 - 2 lines:
        line   0:       "open"       unused   input  active-high
        line   1:       "lock"       unused   input  active-high