文章目录
前言
一.电源管理默认工作情况
启用电源管理器并使用 TI 驱动程序会导致自动节能处理器空闲。应用程序开发人员无需编写电源管理代码;包含 Power Manager 框架的应用程序减少了它们的功耗。 TI 驱动程序与电源管理器通信以启用和禁用外设资源和转换。从应用程序开发的角度来看,最少或不需要应用程序代码管理用电量。但是,应用程序可以使用 API 来根据需要自定义其电源使用情况。
1. Power Manager Initialization
应用程序必须在任何其他 Power API 之前调用 Power_init()。对于所有目标系列上的 SDK 应用程序,Power_init() 会自动调用,作为Board_initGeneral()。 此调用必须在其他驱动程序初始化调用之前,例如:
{
/* 调用板子初始化函数 */
Board_initGeneral();
GPIO_init();
UART_init();
…
要将 Power Manager 支持添加到空示例,在调用任何其他命令之前添加对 Power_init() 的调用。Power_init() 执行的操作因目标系列而异。 通常,此函数初始化 Power管理器并准备好供驱动使用。
2.Driver Initialization, Constraint Management, and Notifications
TI 驱动程序通过通信自动管理其依赖关系和功率限制直接用电源管理器。当您的应用程序初始化驱动程序时,该驱动程序会声明其对各种外围设备的依赖关系模块到电源管理器。当必须禁止特定的电源转换时,TI 驱动器也会设置约束。例如,当一个UART打开读取数据,它必须是清醒的并且能够接收数据,所以它设置了一个功率限制确保电源管理器不会采取会限制驱动程序接收数据能力的操作。另一个例子是 PWM 驱动器,它需要底层定时器处于活动状态才能生成 PWM输出。驱动程序声明了一个功率约束来确保这一点。下图显示了 TI 驱动程序向电源管理器注册时发生的典型操作,并且任务使用驱动程序。在这种情况下,发布了一个假设的温度报告任务 ReportTemp由其他一些“控制”线程。应用程序从 I2C 外设读取并写入 UART。I2C 和 UART 驱动程序控制电源管理器如何利用低功耗深度睡眠 (LPDS) 状态,可用于 CC32xx 器件。
在任务初始化期间,任务打开 UART 和 I2C 驱动程序。调用 Power Manager 以设置依赖关系、约束和注册通知AWAKE_LPDS 事件。TI 驱动程序向电源管理器注册以接收影响它们的电源事件通知。一个收到此类通知的驱动程序有机会保存其状态或发出其他信号(外部)设备根据需要在电源转换之前。通知可用于断电和电源了事件。在此示例中,当设备从 LPDS 唤醒时,两个驱动程序都会注册通知状态。
在打开 UART 后,Task 会发出一个 UART_control() 调用来告诉驱动程序它不会接收任何UART数据。这允许驱动程序在打开驱动程序时释放约束集禁止LPDS。默认情况下,UART 驱动程序可能需要接收数据,在这种情况下,设备必须禁止进入 LPDS,以便 UART 可以监听数据。由于数据只写入在这个例子中的 UART,RX 功能可以被禁用,这样 LPDS 就不会不必要了禁止。
ReportTemp 任务初始化后,最终调用 Semaphore_pend() 等待来自控制线程对温度进行采样(通过 I2C 外设)并将值报告给 UART港口。一旦触发,任务调用 I2C_transfer() 来获取温度。传输前,I2C驱动设置约束以在传输期间禁止 LPDS。传输完成后,I2C 驱动程序释放它为禁止 LPDS 而设置的约束。一旦 I2C 数据到达,Task 将处理数据以格式化输出字符串,然后调用UART_write() 将报告发送到 UART。UART 驱动程序通过在写入期间设置禁止 LPDS 的约束来开始写入过程。然后它将数据推出UART。写入完成后,需要对某些 UART 进行特殊处理,以确保数据得到在再次允许 LPDS 之前关闭芯片。这是因为 LPDS 完全关闭了 UART,这可以截断仍在 UART 的 FIFO 缓冲区中等待从总线输出的数据。去做这个,当最后一个字节被放入 FIFO 时,内核时钟对象被启动。当 Clock 对象到期时,Clock 函数会检查 UART 是否仍处于忙碌状态。如果不是,那么它调用 Power_releaseConstraint() 再次允许 LPDS。如果 UART 仍然忙,则启动 Clock 对象再次;它稍后会过期以重新检查 UART 的状态。同时,当 UART_write() 完成时,ReportTemp 任务返回到待处理状态信号量等待下一次触发读取温度。
3.Application Idle Time Management
当处理器空闲时,电源管理器会自动管理电源状态。电源策略运行并选择允许的最低电源状态。电源策略由内核的空闲循环运行。 电源策略计算最短时间,直到再次需要处理,并将其与转换进出省电状态。 根据这个计算,它会适当地选择最佳的省电状态。下图显示了在 TI-RTOS 内核空闲期间自动发生的典型操作在使用 I2C 驱动程序的应用程序中循环。 处理器进入低功耗深度睡眠 (LPDS)状态,但响应触发事件而被唤醒。 电源管理器通知 I2C 驱动程序,以便驱动程序可以恢复其状态。
电源策略调用 Power_sleep() API 来激活节能。处理器保持睡眠状态,直到发生唤醒事件。可用的唤醒因设备和睡眠状态而异,一般而言,处理器由于定时唤醒(从睡眠状态期间激活的定时器)或来自外部输入或网络协处理器的中断信号而唤醒。
例如,在 CC32xx 上,电源策略检查当前是否有任何约束不允许等待中断 (WFI)、空闲断电 (IDLE) 或待机状态。如果STANDBY 或 IDLE 状态为允许时,电源策略会计算时钟模块安排的下一次唤醒前的时间量。它将这个时间量与 STANDBY 状态的转换延迟(最低电源状态)。如果有足够的时间,它会安排一个唤醒事件(允许处理器在需要处理之前有足够的时间唤醒)并进入 STANDBY 状态。如果电源策略没有足够的时间进入 STANDBY 状态,它会关闭各种电源域并将 CPU 置于 IDLE(没有 STANDBY 状态那么深)。
在某些情况下,后台活动由电源管理器自动管理。例如,在 CC26xx/CC13xx 器件上,执行 RCOSC 校准、晶振启动和时钟源切换。
二.电源策略
默认情况下,SDK 示例应用程序(CC32xx 除外)启用电源管理器电源策略。他们通过将 enablePolicy 参数设置为 True 或通过从应用程序代码调用 Power_enablePolicy() API。
enablePolicy 参数的静态配置是板文件中 Power_Config 结构的一部分。此处配置的内容将在应用程序启动后立即生效。
应用程序可以调用以下 API 来控制电源策略的使用:
• Power_enablePolicy() 在运行时启用电源策略,如果它在任一静态中被禁用配置或调用 Power_disablePolicy()。
• Power_disablePolicy() 在运行时禁用电源策略。例如,应用程序可能调用这可以快速禁用所有节能转换,而不是通过设置多个电源限制。当应用程序准备就绪时,它可以通过调用 Power_enablePolicy() 重新启用策略。
• Power_setPolicy() 在运行时选择不同的电源策略函数。高级应用程序可以使用此 API 根据应用程序定义的标准或权衡之间更改电源策略节能和动态应用功能。例如:
/*
- ======== myPolicy ========
*/
void myPolicy(void)
{
…
}
…
Power_setPolicy(myPolicy);
…
对于 MSP432,电源管理器提供两种电源策略。默认电源策略 Power_sleepPolicy() 不使用 MSP432 的深度睡眠状态。 PowerMSP432_deepSleepPolicy(),
更积极的电源政策,导致更大的功率节省。但是,应该了解与深度睡眠期间时钟滴答停止相关的后果。
三.电源管理及调试
1.禁用到睡眠状态的转换
对于某些目标,您可能希望在调试期间禁用部分或全部电源管理:
• MSP432。对于 MSP432P401x 器件,默认情况下不启用深度睡眠状态,因为 DEEPSLEEP_0 和 DEEPSLEEP_1 禁用外围模块并导致时钟滴答在睡眠期间暂停。我们建议您使用重量较轻的 Power_sleepPolicy() 创建和调试应用程序。调试应用程序后,您可能希望选择更激进的 Power_deepSleepPolicy()。对于 MSP432P401x 器件,当您使用 Power_deepSleepPolicy() 时,时钟和外设在深度睡眠期间被强制进入时钟门控状态。当设备唤醒时,它们会恢复活动。
对于最近推出的 MSP432P4x1xl 器件,外设可以在深度睡眠状态下继续运行,因此 Power_deepSleepPolicy() 是默认电源策略。
• CC32xx。如果激活低功耗深度睡眠 (LPDS) 状态,则任何调试会话都会终止。
调试器无法重新连接,直到您重新启动 CC32xx。对于某些调试配置,即使是 Cortex M 等待中断 (WFI) 状态也会导致调试会话终止。
因此,CC32xx 默认禁用电源策略。我们建议您在没有电源管理的情况下创建和调试您的应用程序。调试应用程序后,启用电源管理,并使用有限的调试器功能进行进一步测试。
在调试 MSP432E4 和 CC13xx/CC26xx 器件期间无需禁用电源管理。
2.调整系统分析器时间刻度
系统分析器显示的时间刻度基于静态指定的频率。当 CPU 频率在运行时动态变化时,例如,如果电源驱动程序移动到特定的初始性能级别(请参阅第 3.1 节中的 initialPerfLevel),则系统分析器的时间刻度可能不准确。
如果频率在启动期间改变一次,纠正时间刻度的一种方法是在应用程序配置文件中指定启动期间建立的实际频率。例如,以下代码段表明应用程序启动后 CPU 和时间戳频率将为 48 MHz:
UIAMetaData = xdc.useModule(‘ti.uia.runtime.UIAMetaData’);
UIAMetaData.cpuFreq.lo = 48000000;
UIAMetaData.timestampFreq.lo = 48000000;
通知系统分析器不同 CPU 和时间戳频率的另一种方法是使用自定义 UIA 配置文件,该文件指示当前有效的频率。如果应用程序很少更改性能级别,并且在系统分析器会话期间将保持在特定的性能级别。请参阅系统分析仪用户指南 (SPRUH43) 以了解、创建和使用自定义 UIA 配置文件。
3.电源管理和输出到 UART
因为 LPDS 会终止 CC32xx 的任何调试会话,并且在不重置设备的情况下无法重新连接调试器,因此使用 UART 接收 printf 样式的消息是一种有用的策略。 使用 UART 允许在 CC32xx LPDS 激活后将一些信息发送到终端。
此策略也适用于所有其他受支持的目标。
有两种使用 UART 的方法:通过 Display 中间件驱动程序(简化设置)和直接使用 UART 驱动程序。
4.应用程序使用电源管理 API
应用程序可以选择调用以下 API。 这些 API 不是必需的,但可供应用程序开发人员。
• Power_enablePolicy() 和Power_disablePolicy() 控制策略在运行时何时处于活动状态。
• Power_setPolicy() 在运行时选择不同的电源策略。
• Power_setConstraint() 和 Power_releaseConstraint() 设置和释放特定的约束电源转换(除了驱动程序已经在管理的限制)。
• Power_setPerformanceLevel() 在可用操作之间缩放设备性能级别。
• Power_registerNotify() 注册一个应用程序回调函数,在特定情况下触发电源转换事件。
• Power_shutdown() 将设备置于最低功耗状态,这需要完全重新启动应用程序再次通电。
5.直接 I/O 的电源管理
一些应用程序无需使用 TI 驱动程序即可执行简单的直接 I/O:
• 启用外设时为外设调用Power_setDependency()。
• 不再使用外设时调用Power_releaseDependency()。
• 必要时调用Power_setConstraint() 以禁止某些睡眠状态。
• 一旦可以再次允许这些睡眠状态,就立即调用 Power_releaseConstraint()。
• 调用Power_registerNotify() 来注册回调函数,以处理睡眠转换事件。
• 如果不再需要此类回调,则在必要时调用 Power_unregisterNotify()。
5.优化电源管理
为获得最佳的节能效果,应用程序可以通过遵循以下这些常规来协助电源管理器指导方针:
• 避免对资源或条件“忙于等待”(重复检查以查看是否满足条件)。相反,使用中断、操作系统计时服务或操作系统同步服务(例如 Semaphore_pend() )阻止并允许其他代码运行。如果不需要运行其他代码,则可以在等待时进行省电转换。
• 如果应用程序不使用驱动程序,请不要打开驱动程序或让驱动程序处于打开状态。打开时,驱动程序可能会设置不必要地限制电源管理器操作的电源限制。相反,打开驱动程序,并在不需要时关闭它们。
• 如果可能,优化应用程序的速度(在某些情况下与内存相比)以减少活动周期。这允许在低功耗状态下花费更多周期。
• 注意精度和功耗之间的权衡。某些应用程序会过度计算结果,例如,通过使用比所需精度更高的数学或宽数据类型较小的类型就足够了。不必要的准确性或过度计算会增加应用程序占用空间并消耗更多 CPU 周期,从而减少 CPU 可以在睡眠状态。
以下项目是在您的应用中降低功耗的更具体建议:
• Clock.TickMode_PERIODIC。如果 Clock 模块与 Clock.TickMode_PERIODIC 一起使用,请考虑通过指定仍满足应用程序时序的最大周期来减慢滴答速率要求。默认的 Clock.tickPeriod 导致 Clock 每 1 毫秒滴答一次。取决于根据您的应用程序的时序要求,此分辨率可能会过高。例如,每 100 毫秒的一次系统滴答可以满足某些应用程序的计时需求。这么慢的滴答声速率可以显着减少时钟滴答的 CPU 唤醒次数,从而允许在睡眠状态下花费更多时间。此模式推荐用于 CC32xx、MSP432P401x、和 MSP432E4 器件。
• Clock.TickMode_DYNAMIC。如果 Clock 模块与 Clock.TickMode_DYNAMIC 一起使用,则会抑制不必要的计时器滴答声。定时器中断次数减至最少需要支持计划的超时。对于某些设备,如果未在应用程序配置中指定模式,则默认滴答模式为 TickMode_DYNAMIC。有关详细信息,请参阅有关时钟节拍抑制的 wiki 信息。此模式推荐用于 CC13xx/CC26xx 和 MSP432P4x1xl 器件,并且是默认模式。
一些 UART 驱动程序允许应用程序禁用接收模式并释放相应的功率限制。如果您仅将 UART 用于输出,这将很有用。
例如,UARTCC32XX 驱动程序允许使用 UART_CMD_RXDISABLE 调用 UART_control() API。此控制命令导致驱动程序释放PowerCC32XX_DISALLOW_LPDS 约束,因为驱动程序已被告知它不需要停留活动以能够接收数据。 同样,对于带有 MSP432P401x 设备的 UARTMSP432 驱动程序,使用 UART_CMD_RXDISABLE 调用 UART_control() 会释放 DISALLOW_DEEPSLEEP_0 和 DISALLOW_PERF_CHANGES 约束。如果没有设置这些约束,电源策略可以在适当的时候选择深度睡眠状态,并且可以允许更改性能级别。