虚拟 GPIO 消费者¶
虚拟 GPIO 消费者模块允许用户实例化请求 GPIO 的虚拟设备,然后通过 debugfs 控制它们的行为。虚拟消费者设备可以从设备树或通过 configfs 实例化。
虚拟消费者使用面向驱动程序的 GPIO API,并允许使用用户空间驱动的自动化测试来覆盖它。GPIO 是使用 gpiod_get_array()
请求的,因此我们支持每个连接器 ID 多个 GPIO。
创建 GPIO 消费者¶
gpio-consumer 模块注册一个名为 'gpio-virtuser'
的 configfs 子系统。有关 configfs 文件系统的详细信息,请参阅 configfs 文档。
用户可以创建 configfs 组和项的层次结构,以及修改公开属性的值。一旦消费者被实例化,此层次结构将被转换为适当的设备属性。一般结构是
组: /config/gpio-virtuser
这是 gpio-consumer configfs 树的顶层目录。
组: /config/gpio-consumer/example-name
属性: /config/gpio-consumer/example-name/live
属性: /config/gpio-consumer/example-name/dev_name
这是一个表示 GPIO 消费者设备的目录。
只读 dev_name
属性公开设备在平台总线上出现在系统中的名称。这对于在 /sys/kernel/debug/gpio-virtuser/$dev_name
下查找关联的 debugfs 目录非常有用。
'live'
属性允许在完全配置设备后触发设备的实际创建。接受的值为:'1'
以启用虚拟设备,'0'
以禁用和拆除它。
创建 GPIO 查找表¶
用户可以在设备组下创建多个 configfs 组
组: /config/gpio-consumer/example-name/con_id
'con_id'
目录表示单个 GPIO 查找,其值映射到 gpiod_get()
函数的 'con_id'
参数。例如:con_id
== 'reset'
映射到 reset-gpios
设备属性。
用户可以为每个查找分配多个 GPIO。每个 GPIO 都是 'con_id'
组下具有用户定义名称的子目录。
属性: /config/gpio-consumer/example-name/con_id/0/key
属性: /config/gpio-consumer/example-name/con_id/0/offset
属性: /config/gpio-consumer/example-name/con_id/0/drive
属性: /config/gpio-consumer/example-name/con_id/0/pull
属性: /config/gpio-consumer/example-name/con_id/0/active_low
属性: /config/gpio-consumer/example-name/con_id/0/transitory
这是一个描述 con_id-gpios
属性中单个 GPIO 的组。
对于使用 configfs 创建的虚拟消费者,我们使用机器查找表,因此此组可以被视为文件系统与 'struct gpiod_lookup'
中单个条目的字段之间的映射。
'key'
属性表示此 GPIO 所属的芯片的名称或 GPIO 线名称。这取决于 'offset'
属性的值:如果其值 >= 0,则 'key'
表示要查找的芯片的标签,而 'offset'
表示该芯片中线的偏移量。如果 'offset'
< 0,则 'key'
表示线的名称。
其余属性映射到 GPIO 查找结构的 'flags'
字段。前两个将字符串值作为参数
``'drive'``: 'push-pull'
, 'open-drain'
, 'open-source'
``'pull'``: 'pull-up'
, 'pull-down'
, 'pull-disabled'
, 'as-is'
'active_low'
和 'transitory'
是布尔属性。
激活 GPIO 消费者¶
配置完成后,必须将 'live'
属性设置为 1 才能实例化消费者。可以将其设置回 0 以销毁虚拟设备。该模块将同步等待新的模拟设备成功探测,如果这种情况没有发生,写入 'live'
将导致错误。
设备树¶
虚拟 GPIO 消费者也可以在设备树中定义。兼容字符串必须是:"gpio-virtuser"
,并且至少有一个属性遵循标准化的 GPIO 模式。
定义虚拟 GPIO 消费者的设备树代码示例
gpio-virt-consumer {
compatible = "gpio-virtuser";
foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, <&gpio1 2 0>;
bar-gpios = <&gpio0 6 0>;
};
控制虚拟 GPIO 消费者¶
一旦设备激活,它将导出 debugfs 属性,用于控制 GPIO 数组以及每个请求的 GPIO 线。让我们考虑以下设备属性:foo-gpios = <&gpio0 0 0>, <&gpio0 4 0>;
。
将创建以下 debugfs 属性组
组: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/
此组将包含整个 GPIO 数组的属性。
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo/values_atomic
这两个属性都允许读取和设置 GPIO 值的数组。用户必须以字符串的形式传递数组中包含的确切数量的值,其中包含 0 和 1,分别表示非活动和活动的 GPIO 状态。在此示例中:echo 11 > values
。
values_atomic
属性的工作方式与 values
相同,但内核将在中断上下文中执行 GPIO 驱动程序回调。
组: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/
此组表示单个 GPIO,其中 $index
是其在数组中的偏移量。
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/consumer
允许设置和读取 GPIO 线的消费者标签。
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/debounce
允许设置和读取 GPIO 线的去抖动周期。
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/direction_atomic
这两个属性允许设置 GPIO 线的方向。它们接受 “input” 和 “output” 作为值。原子变体在中断上下文中执行驱动程序回调。
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/interrupts
如果在输入模式下请求该线,则向此属性写入 1
将使模块侦听 GPIO 上的边沿中断。写入 0
将禁用监视。读取此属性将返回当前注册的中断数(包括上升沿和下降沿)。
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value
属性: /sys/kernel/debug/gpio-virtuser/$dev_name/gpiod:foo:$index/value_atomic
这两个属性都允许读取和设置单个请求的 GPIO 线的数值。它们接受以下值:1
和 0
。