新式待机平台的音频子系统电源管理

每台 Windows 电脑都有一个音频子系统,使用户能够实时侦听和录制高质量的声音。 支持连接待机电源模型的硬件平台通常围绕片上系统 (SoC) 集成电路构建,其中内置了低功耗音频处理单位。

音频处理单元从 SoC 上的一个或多个主处理器卸载音频处理。 由于这些单元无需使用主处理器即可处理音频数据,因此即使在主处理器进入低功率状态以节省电池电量后,用户也可以继续收听音频。

此视频演示如何使用 Windows Performance Analyzer (WPA) 验证计算机在屏幕关闭音频播放(也称为低功率音频或 LPA)期间是否进入低功率状态。

以下文章讨论连接待机平台的音频子系统电源管理。 在下面的讨论中,术语“SoC 内部组件”描述的是集成到 SoC 芯片中的组件。 “SoC 外部组件”位于 SoC 芯片外部

音频子系统概述

除了执行卸载音频处理的 SoC 功能块之外,每个连接待机平台还包括一个称为编解码器的 SoC 外部组件,该组件执行以下操作

  • 将解码的数字流转换为模拟声音。
  • 驱动内置扬声器。
  • 驱动外部连接的模拟耳机。

摄像头子系统一样,音频子系统同时具有 SoC 内部和 SoC 外部组件。 但是,Windows 需要单个音频驱动程序来管理 SoC 内部音频处理引擎和 SoC 外部编解码器。 此单个音频驱动程序负责管理集成到 SoC 中的组件以及系统集成商可以选择的 SoC 外部组件。 因此,系统集成商应在音频子系统集成和电源管理方面与 SoC 芯片供应商密切合作。

音频硬件供应商必须将音频驱动程序作为端口类实现 (Portcls) 微型驱动程序进行实现。 音频驱动程序与 Portcls 系统驱动程序 Portcls.sys(Windows 的内置组件)配合工作。

与其他设备类相比,音频子系统在平台处于连接待机电源状态时(即屏幕关闭时)采用独特的方式进行电源管理。 当平台处于连接待机时,系统可以生成音频声音以实时地向用户通知事件(例如,新电子邮件到达)。 此外,用户可以关闭系统显示器,然后继续收听应用程序播放的音频。 这些功能不能通过简单电源管理策略来实现,在这种策略中,当系统处于连接待机状态时必须关闭音频子系统。 相反,音频子系统的电源管理必须始终基于运行时空闲(以便它仅在需要时才会打开)来执行,除非系统处于 ACPI 关闭 (S5) 状态时。

音频驱动程序与 Windows 音频基础结构和 PortCls 系统驱动程序紧密协作,来执行运行时空闲电源管理。 PortCls 会监视音频设备的任何访问(如 I/O 和属性访问),并在每次访问时重置空闲计时器。 如果空闲计时器过期,则 PortCls 会将音频设备转换为(在音频驱动程序的帮助下)低功率睡眠 (D3) 状态。 PortCls 会在出现新访问活动时将音频设备恢复为活动 (D0) 状态。

PortCls 还会注册到 Windows 电源框架 (PoFx),以便系统电源引擎插件 (PEP) 可以收到有关音频设备电源状态更改的通知。 这些通知使 PEP 可以知道何时可以安全地关闭可能在音频处理单元与其他 SoC 功能块之间共享的时钟和电源轨。

建议在未使用音频子系统时,它应处于睡眠状态,在该状态下,音频子系统的总功耗不到 1 毫瓦。 此总功耗包括音频处理单元、SoC 外部编解码器以及任何其他音频电路(例如,用于扬声器和耳机的放大器)的功耗。

音频子系统硬件拓扑

音频子系统由多个 SoC 内部和 SoC 外部组件组成,不过在 ACPI 命名空间中作为单个设备呈现给 Windows。

音频处理单元位于 SoC 上。 不同供应商的 SoC 的音频处理单元具有不同的功能、功耗和性能。 音频处理单元会执行音频卸载 — 它们在不使用主处理器的情况下处理音频流(例如,混合并应用音频效果)。 对于对延迟不敏感的音频播放,最好从主处理器卸载音频,因为音频处理单元使用的功率比主处理器更少。

有关卸载音频的详细信息,请参阅硬件卸载的音频的处理

系统还包含 SoC 外部音频编解码器,可将数字音频流转换为模拟输出,以驱动内置扬声器或外部耳机。 编解码器可能包含用于扬声器和耳机的集成模拟放大器。 或者,可以改为使用离散放大器。 典型编解码器会与 SoC 内部音频处理单元建立以下连接:

  • 数字音频接口(I2S 或类似串行总线)。
  • 控制接口(通常为 I2C 或类似串行总线)。
  • 一个或多个 GPIO 引脚,用于控制电源管理电路,以及在编解码器状态更改时中断 SoC。

这些连接显示在下面的块图中。

audio device

从 Windows 的角度来看,音频处理单元和音频编解码器共同构成了音频设备。 音频设备必须在 ACPI 命名空间中作为单个设备对象进行枚举。

尽管音频子系统应通过单个音频驱动程序向 Windows 公开,不过作为一种选择,SoC 供应商可能会采用驱动程序扩展模型,其中音频驱动程序会分解为两个或更多单独的驱动程序。 例如,直接管理音频编解码器的控制软件可能放置在独立于主音频驱动程序的编解码器驱动程序中。 于是主音频驱动程序通过与编解码器驱动程序通信来间接管理编解码器。 此驱动程序扩展模型的详细信息超出了本文档的范围,是 SoC 供应商音频驱动程序所专有的。 系统集成商应直接与 SoC 芯片供应商合作,以在音频子系统中实现此类专有功能。

电源管理模式

音频子系统必须支持以下两种电源管理模式:

  • 活动模式,在该模式下会主动为用户流式处理音频。
  • 低功率睡眠模式,在该模式下,音频处理单元处于关闭状态,SoC 外部编解码器处于低功率模式,组合的音频子系统组件的功耗小于 1 毫瓦。

下表介绍了这两种电源模式。

“模式” 说明 设备电源状态 (Dx) 平均功率消耗 退出延迟到活动状态 转换机制
活动(流式处理) 音频处理单元在主动流式处理音频,编解码器在向音频终结点(例如耳机、内置扬声器或远程 HDMI 输出设备)提供模拟或数字音频。 D0

<= 100 毫瓦

(音频处理 + 编解码器)

空值

由 Portcls 启动到 D0 的转换。

在应用程序或系统服务启动音频流式处理时发生。

睡眠状态 音频处理单元未流式处理音频,编解码器无法未运行,不过待机功率足以检测到插孔插入或移除。 D3

<= 1 毫瓦

(建议使用。)

<= 35 毫秒或 <= 300 毫秒,具体取决于系统方案。

(必选。)

由 Portcls 启动到 D3 的转换。

在所有应用程序完成音频流式处理且驱动程序提供或系统提供的空闲超时过期时发生。

在某些 SoC 设计中,音频处理单元是与视频解码和图形处理共享的多功能块。 对于这些设计,在某些情形中,音频未在进行流式处理时,音频处理单元会打开。

软件电源管理机制

音频子系统的主要软件电源管理机制是内置在 PortCls 中的运行时空闲检测。 运行时空闲检测使 PortCls 可以观察应用程序音频流式处理活动,以确定何时在活动模式与睡眠电源模式之间切换音频设备。 PortCls 还实现了音频驱动程序与 SoC 供应商提供的电源引擎插件 (PEP) 之间的专有扩展机制,以管理音频处理单元的性能状态。

运行时空闲检测

音频子系统中的组件会在音频子系统空闲时间达到指定超时间隔后进入低功率睡眠模式。

SoC 供应商提供的音频驱动程序必须注册以下两个默认空闲超时设置:

  • PerformanceIdleTime – 当硬件平台插入交流电源时,使用此超时间隔。
  • ConservationIdleTime – 当平台使用电池电源进行运行时,使用此超时间隔。

空闲超时设置存储在位于音频驱动程序 PowerSettings 注册表项下的注册表项中。 有关详细信息,请参阅音频设备类不活动计时器实现

必须使用以下 .inf 指令将 PerformanceIdleTime 超时设置为 1 秒,将 ConservationIdleTime 超时设置为 1 秒:

[MyAudioDevice.AddReg]
HKR,PowerSettings,ConservationIdleTime,1,01,00,00,00
HKR,PowerSettings,PerformanceIdleTime,1,01,00,00,00
HKR,PowerSettings,IdlePowerState,1,03,00,00,00

PortCls 与 Windows 内核电源管理器协作,以在平台在交流电源与电池电源之间转换时自动在 PerformanceIdleTime 与 ConservationIdleTime 超时值之间切换。

当系统处于连接待机(即屏幕关闭)且音频播放未启动时,PortCls 始终使用 1 秒的空闲超时,而不考虑适配器驱动程序在其 .inf 文件中指定的超时设置。

SoC 供应商提供的音频驱动程序还必须注册 IdlePowerState 设置,以指定在空闲超时过期时要转换到的电源状态。 在所有连接待机平台上,音频驱动程序都必须将 D3 注册为在空闲超时出现时要进入的状态。 为了指定 D3 状态,上面示例中的 AddReg 指令将 IdlePowerState 值设置为 03。

空闲超时过期时,PortCls 会调用音频驱动程序的 IAdapterPowerManagement3::PowerChangeState3 方法,来告知驱动程序准备音频设备以进入低功率睡眠模式 (NewPowerState = PowerDeviceD3)。 音频驱动程序必须为音频处理单元保存上下文,并将编解码器置于平均功耗小于 1 毫瓦的低功率睡眠模式。 在低功率睡眠模式下,编解码器必须继续有足够的功率来检测音频插孔插入/移除,并向 SoC 上的主处理器生成电平触发中断。

如果在连接待机期间由于应用程序流式处理、系统声音生成或音频通知而需要音频播放,则 PortCls 会调用音频驱动程序的 PowerChangeState3 方法,告知驱动程序将音频设备配置为在活动 (D0) 电源状态下运行 (NewPowerState = PowerDeviceD0)。 音频驱动程序必须为音频处理单元还原上下文并重新启用编解码器。

PortCls 会调用音频驱动程序的 IAdapterPowerManagement3::D3ExitLatencyChanged 方法,以向驱动程序通知在从睡眠 (D3) 状态转换为活动 (D0) 状态时可容忍的最大延迟发生更改。 PortCls 会调用音频驱动程序的 D3ExitLatencyChanged 方法,将最大延迟设置为 35 毫秒或 300 毫秒。 音频驱动程序必须遵守最大延迟容差,而不进入需要的恢复延迟大于 PortCls 在 D3ExitLatencyChanged 方法中指定的值的低功率状态

编解码器电源管理

SoC 供应商提供的音频驱动程序还负责对 SoC 外部音频编解码器进行配置和电源管理。 驱动程序通常通过 I²C 或来自 SoC 的其他简单外围总线 (SPB) 连接来控制音频编解码。 驱动程序还必须处理来自编解码器设备的中断。

音频子系统进入 D3(睡眠)模式时,音频驱动程序必须将编解码器转换为低功率睡眠模式。

音频子系统进入 D0(活动)模式时,音频驱动程序必须将编解码器转换为活动模式。

Windows 电源框架 (PoFx) 和电源引擎插件 (PEP)

PortCls 会注册到 Windows 电源管理框架,以便向 SoC 供应商提供的 PEP 通知活动 (D0) 与睡眠 (D3) 电源模式之间的音频设备转换。 在许多 SoC 设计中,音频处理单元的时钟和电源轨会与其他 SoC 内部功能块共享。 SoC 供应商提供的 PEP 了解特定于 SoC 的时钟和电源拓扑,会在处于睡眠模式时执行适当操作来停止时钟或关闭与音频处理单元关联的电源轨。

此外,PortCls 支持称为“上下文共享”的专用机制,该机制允许音频驱动程序直接与 PEP 通信,以执行精细电源管理。 例如,音频驱动程序可以使用上下文共享向 PEP 告知当前音频流内容类型和比特率。 PEP 使用此信息将音频处理单元的时钟频率缩小到处理当前音频流所需的最小频率,而不会出现故障。

上下文共享接口定义为具有 GUID 标识符的简单输入/输出缓冲区,与其他可扩展 Windows 电源管理接口类似。 有关微型端口驱动程序和 PEP 之间的上下文共享的详细信息,请参阅 PortCls 专用 PEP 上下文共享

支持的硬件电源配置

在连接待机平台中,Windows 对音频子系统支持单个硬件电源管理配置。

在期望配置中,音频处理单元位于 SoC 上,外部音频编解码器通过与 SoC 兼容的数字音频接口、简单外围总线 (SPB)(如 I²C)以及一个或多个 GPIO 引脚连接到 SoC。 建议音频编解码器和外部逻辑在睡眠电源模式下的功耗不超过 1 毫瓦。

下面的框图显示了期望硬件配置、音频设备驱动程序堆栈和用户模式组件

audio stack

音频子系统可以具有位于编解码器后面的组件,这些组件对操作系统及其驱动程序不可见。 例如,这些组件可能包括用于扬声器和耳机的放大器。 此类组件特定于平台,可以由系统集成商在 Windows 认证计划中概述的要求中进行选择。

系统集成商必须在 APCI 命名空间层次结构的根处枚举 SoC 音频设备。 音频处理单元和外部编解码器所需的所有内存、I/O、GPIO 和 I²C(或其他 SPB)资源都必须在命名空间中设备下的 _CRS 对象中列出。 系统集成商和 ACPI 固件开发人员必须与音频驱动程序开发人员沟通,以了解硬件资源(如GPIO 引脚)的排序约定。 例如,收到两个 GPIO 资源的驱动程序会按照它们在资源列表中的出现顺序来区分它们。 有关详细信息,请参阅基于 GPIO 的硬件资源

尽管 ACPI 驱动程序 (Acpi.sys) 可以在设备电源 IRP 流过音频堆栈时观察活动 (D0) 和睡眠 (D3) 转换,不过系统集成商不得将音频编解码器描述为电源资源的一部分,或使用 _PS0 和 _PS3 ACPI 控制方法来更改编解码器电源状态。 在睡眠模式下,编解码器应以足够低的功率运行,以便它可以始终保持打开状态来检测插孔插入和移除。

音频编解码器以及任何外部放大器必须放置在始终打开的电源轨上,除非系统处于 ACPI 关闭 (S5) 状态。 GPIO 引脚可用于按需启用或禁用放大器。 可以从编解码器或 SoC 使用 GPIO 引脚控制放大器。

一个关键要求是编解码器本身始终保持通电(即使它处于低功率睡眠模式时),以便可以检测插孔插入和移除。 编解码器必须生成可以将 SoC 从其最深空闲状态唤醒的中断,以处理耳机插孔插入和移除。

唤醒问题(耳机和麦克风插孔检测)

音频子系统必须处理随时可能发生的音频输出设备状态更改。 最常见的音频设备状态更改是将输出设备插入内置耳机插孔,以及将此设备从插孔中移除。 还必须为任何其他连接的音频端口(包括麦克风和数字信号端口)检测插孔插入和移除。

音频堆栈必须始终能够检测插孔插入和移除。 音频编解码器中的中断线路必须连接到始终通电且始终能够将 SoC 从最深空闲状态唤醒的 GPIO 引脚。 插孔检查使 Windows 可以实时维护有关音频输入和输出设备的最新信息,包括系统处于连接待机状态的所有时间。 例如,当用户将插头插入耳机插孔时,Windows 会立即收到通知。 为了响应此通知,任何将来的连接待机通知警报声音都会路由到耳机,而不是平台的内置扬声器。

如前所述,系统固件会将一组硬件资源分配给音频设备。 这些资源在 ACPI _CRS 对象中进行描述,操作系统会将这些资源的列表传递给音频驱动程序。 此资源列表包括用于检测音频输出设备状态更改(例如,耳机插入)的所有 GPIO 中断。 这些中断必须在系统 ACPI 固件中标记为“唤醒源”。 音频驱动程序应为其中每个唤醒中断添加中断处理程序。 中断处理程序必须基于发出相关信号的中断,根据情况更新音频设备、音频编解码器和音频驱动程序的状态。

_CRS 对象中的资源排序基于音频驱动程序开发人员定义的特定于设备的约定。 例如,如果驱动程序收到两个中断资源,则驱动程序会基于它们在资源列表中的出现顺序来区分它们。 ACPI 固件开发人员必须使用相同排序在 ACPI 固件中描述这些资源。

多个硬件、固件和软件子系统必须进行协作,使音频插孔插入和移除检测正常工作。 系统集成商和音频驱动程序开发人员必须遵循以下实现准则:

硬件和 SoC

  • 音频编解码器硬件必须在系统处于开机状态的所有时间(包括系统处于连接待机状态时)检测耳机、麦克风和其他插孔插入和移除事件。
  • 音频编解码器硬件必须能够检测插孔插入和移除,同时消耗非常小的功率(平均小于 1 毫瓦)。
  • 音频编解码器中断必须连接到 SoC 上能够将 SoC 从最深电源状态唤醒的 GPIO 引脚。

ACPI 固件

  • 必须在 ACPI 命名空间中描述音频设备。
  • ACPI 固件必须将用于检测插孔插入的 GPIO 线路描述为独占式唤醒中断。 使用 GpioInt 描述符宏并将 Shared 参数设置为 ExclusiveAndWake
  • 音频设备的硬件资源必须按音频驱动程序的预期顺序列出。

音频驱动程序软件

  • 音频驱动程序必须将中断处理程序连接到 GPIO 唤醒中断。
  • 当音频驱动程序处理中断时,它会评估音频输入/输出设备的状态,并执行相应的操作。

测试和验证

系统集成商可以使用 Windows Performance Analyzer (WPA) 验证音频设备是否按预期在活动 (D0) 与睡眠 (D3) 状态之间正确执行运行时空闲电源管理和转换。 WPA 在 Microsoft Connect 网站上提供。 请联系 Microsoft 代表以帮助获取 WPA 和 WPA 电源管理扩展。 系统集成商还应获取 WPA 电源管理分析工具包。 此包中包含启用系统电源管理分析的 WPA 扩展。

WPA 依赖于内置在 Windows 内核中的 Windows 事件跟踪 (ETW) 检测和其他 Windows 组件(包括 PortCls)。 若要使用 ETW 跟踪,需启用一组跟踪提供程序,并在测试方案运行时将其事件记录到日志文件中。 方案完成后,跟踪提供程序会停止。 WPA 支持对受测方案生成的日志文件进行后期处理和可视化分析。

在安装了 WPA 的系统中,可以使用一组命令收集电源管理检测,以验证音频设备的电源管理。 Xperf.exe 工具安装在 \%Program Files%\Windows Kits\8.0\Windows Performance Analyzer 文件夹中。

若要启动电源管理 ETW 跟踪,请以管理员角色打开命令提示符窗口,更改到包含 WPA 的目录,然后运行以下命令:

>xperf -start powertracesession -on Microsoft-Windows-Kernel-Power
>xperf -capturestate powertracesession Microsoft-Windows-Kernel-Power

这些命令指示 Windows 启用 Microsoft-Windows-Kernel-Power ETW 事件提供程序,并从 Microsoft-Windows-Kernel-Power 提供程序捕获事件的初始状态。

ETW 跟踪启动后,开发人员应演练系统方案,以验证音频设备是否可在活动 (D0) 与睡眠 (D3) 电源模式之间正确转换。 开发人员应在以下方案中验证音频设备:

  • 启动将音频设备从 D3 状态转换为 D0 状态的应用程序。
  • 关闭所有音频应用程序一秒后,音频设备从 D0 状态转换为 D3。
  • 当系统处于连接待机状态时,音频设备保持 D3 状态。
  • 在连接待机期间生成音频通知时,音频设备从 D3 转换为 D0,播放音频,然后在一秒后恢复为 D3。

完成这些测试方案后,使用以下命令停止 ETW 跟踪收集:

>xperf -stop powertracesession -d trace.etl

使用 WPA 打开生成的 Trace.etl 文件。 若要从命令行启动 WPA,请输入命令 Wpa.exe

在 WPA 工具中,从“图像资源管理器”列表中选择“设备 Dstate”图,以下视图应出现

device d-state graph from the graph explorer list

在此视图中,设备按其 ACPI 名称标识(例如 \_SB.AUDI)或设备实例路径(例如 ACPI\MSFT0731\4%ffff367&2)进行标识。 ACPI 名称和设备实例路径都会在“设备 Dstate”图的摘要表中列出

若要查看音频设备进行的 D-state 转换,请在摘要表中找到设备名称,右键单击该名称,然后选择“按选定内容筛选”。 生成的图只显示音频设备的 D-state 转换,如以下屏幕截图所示。

d-state transitions

此示例跟踪显示音频设备在整个跟踪持续内都处于 D3 状态(由垂直轴上的坐标 3 指示),除了跟踪开始约 290 秒时的一个 5 秒时间段。

电源管理清单

系统集成商和 SoC 供应商应使用以下清单来确保其音频子系统电源管理设计与 Windows 8.1 兼容。

  • 系统集成商应与 SoC 供应商密切合作来集成音频子系统设备。

  • SoC 供应商开发的音频驱动程序必须执行以下操作:

    • 为系统采用交流电源和电池电源运行时设置运行时空闲超时。 音频驱动程序必须将 PerformanceIdleTime 值和 ConservationIdleTime 值都设置为 1 秒。

    • 将 IdlePowerState 值设置为 D3。

    • 在音频驱动程序的 .inf 文件中,将 IdlePowerState、PerformanceIdleTime 和 ConservationIdleTime 设置为以下值:

      [MyAudioDevice.AddReg]
      HKR,PowerSettings,ConservationIdleTime,1,01,00,00,00
      HKR,PowerSettings,PerformanceIdleTime,1,01,00,00,00
      HKR,PowerSettings,IdlePowerState,1,03,00,00,00
      
    • 当 PortCls 调用驱动程序的 IAdapterPowerManagement3::PowerChangeState3 方法且设备电源状态为 D3 时,音频驱动程序必须保存所有音频处理单元上下文并将编解码器置于低功率睡眠模式。

    • 当 PortCls 调用驱动程序的 PowerChangeState3 方法且设备电源状态为 D0 时,音频驱动程序必须还原所有音频处理单元上下文并重新启用编解码器。

    • 音频驱动程序不得使用违反 PortCls 在 IAdapterPowerManagement3:D3ExitLatencyChanged 方法中提供的 D3 退出延迟要求的电源状态。

    • 音频驱动程序必须处理外部编解码器的配置和电源管理。

    • 当编解码器检测到插孔插入或移除时,音频驱动程序必须处理来自外部编解码器的电平触发中断。

  • SoC 供应商必须提供执行以下操作的电源引擎插件 (PEP):

    • 当音频驱动程序转换为睡眠 (D3) 模式时,将音频处理单元置于低功率状态。
    • 当音频驱动程序转换为活动 (D0) 电源模式时,打开音频处理单元所需的任何时钟和电源轨。
    • 根据所需的处理活动级别(取决于音频格式、内容类型和比特率),正确缩放提供给音频处理单元的时钟和电压。
  • 若要开发音频子系统的硬件和固件平台,系统集成商必须执行以下操作:

    • 使用在睡眠模式下功耗小于 1 毫瓦,但仍可以检测插孔插入和移除事件的编解码器。
    • 将编解码器置于始终打开(除非系统处于 ACPI 关闭 (S5) 状态)的系统电源轨上。
    • 设计 ACPI 固件,以在 ACPI 命名空间层次结构的根处将音频子系统作为单个设备进行枚举。
    • 确定音频驱动程序所需的内存、中断、I/O、GPIO 和 I²C 资源排序约定,并确保在 ACPI _CRS 对象中以相同顺序列出资源。
  • 若要测试和验证音频子系统的电源管理,系统集成商必须执行以下操作:

    • 验证当没有任何应用程序在使用音频子系统或为用户生成音频时,音频驱动程序是否转换为 D3 电源状态。
    • 验证当应用程序或系统在生成音频时(包括在屏幕关闭时的音频播放期间),音频驱动程序是否转换为活动 (D0) 电源状态。
    • 使用 Windows 认证测试套件 (HCK) 中提供的测试,验证是否以无故障和无错误的方式执行音频播放。
    • 确保当系统处于连接待机状态时,插孔检测正常工作,并且当用户插入耳机插孔或从插孔中拔下插头时,音频可正确路由到耳机或扬声器。
    • 测量音频处理单元、外部编解码器以及任何其他模拟放大电路的功耗。 确保整个音频子系统在处于睡眠 (D3) 电源状态时的功耗小于 1 毫瓦。