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
, offset
和 name
属性(即,它不等待延迟探测)。
示例配置命令¶
# 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 聚合器
将其兼容值添加到
gpio_aggregator_dt_ids[]
,使用 “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