基于 GPIO 的硬件资源

从 Windows 8 开始,受 GPIO 控制器驱动程序控制的常规用途 I/O (GPIO) 引脚可以作为系统管理的硬件资源供其他驱动程序使用。 GPIO I/O 的引脚是已配置为数据输入或数据输出的引脚,可以作为新的 Windows 资源类型(即 GPIO I/O 资源)使用。 另外,GPIO 中断引脚是已配置为中断请求输入的引脚,可以作为普通 Windows 中断资源使用。

GPIO I/O 资源表示外围设备的驱动程序可从中读取或写入的一个或多个 GPIO 引脚集。 Windows 隐藏有关 GPIO I/O 引脚基础实现的详细信息,以便可以编写外围设备驱动程序以操作抽象 GPIO I/O 资源。 使用这些抽象资源的外围设备驱动程序可以跨平台工作,而不考虑实现资源的 GPIO 控制器硬件。 GPIO I/O 资源由 WDFIOTARGET 句柄表示,该句柄将此资源与拥有基础 GPIO 引脚或引脚的特定 GPIO 控制器驱动程序相关联。

通常,GPIO 控制器上的 I/O 引脚可以配置为输入或输出,具体取决于控制器硬件的功能和物理连接到引脚的设备。 因此,驱动程序可以打开到此引脚的逻辑连接,以便执行写入或读取操作,但不能同时打开两者。 但是,此约束是由硬件施加的,而不是由 GPIO 框架扩展 (GpioClx) 施加的。 如果硬件允许为输入和输出配置 I/O 引脚,则 GpioClx 允许驱动程序打开与该引脚的逻辑连接,以便同时执行读取和写入操作。

对于配置为中断请求输入的 GPIO 引脚,中断请求由 GPIO 引脚而不是中断控制器或专用中断请求行实现的事实完全由操作系统抽象化。 GPIO 中断作为抽象中断资源提供给外围设备驱动程序。 GPIO 驱动程序堆栈和硬件抽象层支持这些资源的抽象 (HAL) 。 因此,使用中断资源的外围设备驱动程序在很大程度上可以忽略有关这些资源的基础实现的详细信息。 有关详细信息,请参阅 GPIO 中断

下图显示了将基于 GPIO 的资源分配到两个外围设备驱动程序的示例:

基于 gpio 的资源的示例分配。

在上图中,为以下三个基于 GPIO 的资源分配了外围设备驱动程序 A:

  • 两个数据输入引脚
  • 数据输出引脚
  • 中断输入引脚

以下两个基于 GPIO 的资源分配给外围设备驱动程序 B:

  • 数据输入引脚
  • 中断输入引脚

驱动程序 A 和 B 在其 EvtDevicePrepareHardware 回调函数中接收其分配的资源。 如果驱动程序作为资源收到一组或多根 GPIO I/O 引脚,则驱动程序可以打开与这些引脚的连接来访问它们。 驱动程序获取 WDFIOTARGET 句柄以标识连接,并将 I/O 请求发送到此句柄,以便从这些引脚读取或写入。

有关演示如何连接到一组 GPIO I/O 引脚并将 I/O 请求发送到此引脚的代码示例,请参阅以下主题:

将 KMDF 驱动程序连接到 GPIO I/O 管脚

在这两个主题中, IoRoutine 代码示例中的 函数打开 GPIO I/O 引脚资源,用于读取或写入,具体取决于 ReadOperation 参数值。 如果打开资源进行读取 (DesiredAccess = GENERIC_READ) ,则资源中的引脚将配置为输入,并且发送到引脚资源的 IOCTL_GPIO_READ_PINS 请求读取这些引脚上的输入值。 GpioClx 不允许向 IOCTL_GPIO_WRITE_PINS 请求发送一组输入引脚,并且会以STATUS_GPIO_OPERATION_DENIED错误状态完成此类请求。 同样,如果为写入打开引脚资源 (DesiredAccess = GENERIC_WRITE) ,则资源中的引脚将配置为输出,并且发送到引脚资源的 IOCTL_GPIO_WRITE_PINS 请求将设置驱动这些引脚的输出闩锁中的值。 通常,向一组输出引脚发送 IOCTL_GPIO_READ_PINS 请求只是读取写入输出闩锁的最后一个值。

若要使用中断资源接收中断,客户端驱动程序必须将中断服务例程 (ISR) 连接到中断。 通常,驱动程序通过调用 WdfInterruptCreate 方法 (或 IoConnectInterruptEx 例程) 建立此连接。 有关 KMDF 中断的详细信息,请参阅 创建中断对象

与可以动态连接到硬件平台并与其断开连接即插即用设备相比,GPIO 控制器设备是永久连接的。 此外,假定 GPIO 引脚与外围设备之间的连接是永久性的。 (或者,如果可从槽中拔出外围设备,则槽将专用于此设备。) 因此,可用的 GPIO 资源是固定的,可以在平台固件中指定。 同样,假定使用 GPIO 资源的外围设备驱动程序使用专用的 GPIO 资源集。 因此,可以在平台固件中指定这些设备驱动程序的资源要求。

当平台固件将一组 GPIO 引脚指定为 GPIO I/O 资源时,固件指示是否可以打开此资源中的引脚进行读取、写入或读取和写入。

如果外围设备驱动程序使用多个 GPIO I/O 资源,则此驱动程序必须知道 PnP 管理器枚举这些资源的顺序。 例如,如果驱动程序使用两个 GPIO I/O 引脚,但必须单独访问这些引脚并在不同的时间访问,则平台固件应将每个引脚描述为单独的 GPIO I/O 资源。 PnP 管理器按照平台固件中描述这些资源的顺序枚举这些资源,这必须与驱动程序预期的顺序匹配。

外围设备驱动程序打开与 GPIO I/O 资源的连接后,此驱动程序发送到此连接的 IOCTL_GPIO_READ_PINSIOCTL_GPIO_WRITE_PINS 请求将访问资源中的所有引脚。 如果驱动程序有时必须仅访问这些引脚的子集,则必须将此子集作为单独的资源分配给驱动程序。

有关 IOCTL_GPIO_READ_PINS 请求的详细信息,包括将数据输入引脚映射到请求输出缓冲区中的位,请参阅 IOCTL_GPIO_READ_PINS。 有关 IOCTL_GPIO_WRITE_PINS 请求的详细信息,包括将请求输入缓冲区中的位映射到数据输出引脚,请参阅 IOCTL_GPIO_WRITE_PINS