mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'feat/support_get_pm_lock_aquired_counts_v6.0' into 'release/v6.0'
feat(esp_pm): add APIs to get PM lock statistics / add light sleep tick overflow protection configuration (v6.0) See merge request espressif/esp-idf!45885
This commit is contained in:
@@ -92,6 +92,43 @@ Light-sleep duration is chosen to wake up the chip before the nearest event (tas
|
||||
|
||||
To skip unnecessary wake-up, you can consider initializing an ``esp_timer`` with the ``skip_unhandled_events`` option as ``true``. Timers with this flag will not wake up the system and it helps to reduce consumption.
|
||||
|
||||
Automatic Light-sleep Time Compensation Mechanism
|
||||
-------------------------------------------------
|
||||
|
||||
ESP-IDF uses a predictive time compensation mechanism for automatic Light-sleep. The system measures the actual wakeup overhead after each Light-sleep cycle and uses this measurement to predict the wakeup overhead for the next sleep cycle.
|
||||
|
||||
The system calculates sleep duration based on the next scheduled event and subtracts the predicted wakeup overhead (from the previous cycle) to set the wakeup timer. After wakeup, since FreeRTOS systick interrupts are suspended during sleep, the system needs to call :cpp:func:`vTaskStepTick()` to compensate for the ticks elapsed during sleep, maintaining the accuracy of FreeRTOS tick count. Meanwhile, it measures the actual overhead and stores it for the next prediction, creating a feedback loop that adapts to system behavior.
|
||||
|
||||
However, actual overhead can vary due to cache misses, CPU frequency changes, flash latency variations, or hardware state restoration time. When actual overhead exceeds prediction, the actual sleep time may exceed the expected value, causing :cpp:func:`vTaskStepTick()` to receive an excessive tick compensation value, triggering assertion failure.
|
||||
|
||||
The :ref:`CONFIG_PM_LIGHTSLEEP_TICK_OVERFLOW_PROTECTION` option provides a safety mechanism to prevent assertion failures when wakeup overhead exceeds prediction. When enabled, the system limits the tick compensation value to prevent overflow. This option can be enabled in menuconfig via ``Component config`` > ``Power Management`` > ``Enable light sleep tick overflow protection``.
|
||||
|
||||
When enabled, this option handles oversleep as follows:
|
||||
- If oversleep is within tolerance (configurable via :ref:`CONFIG_PM_LIGHTSLEEP_TICK_OVERFLOW_TOLERANCE`, default: 2 ticks), the system silently limits ``slept_ticks`` to ``xExpectedIdleTime``, preventing assertion failure
|
||||
- If oversleep exceeds tolerance (may indicate a bug), the system does not limit ticks, logs an error message, and assertion failure will occur
|
||||
- In rare edge cases, it may lose ticks, causing FreeRTOS tick count (``xTickCount``) to lag behind real time (``esp_timer``). Tasks using :cpp:func:`vTaskDelay()` may experience slightly longer delays than expected, and FreeRTOS software timers may have reduced accuracy.
|
||||
|
||||
When disabled (default), the system provides accurate tick compensation with better precision for time-critical applications. In edge cases, if wakeup overhead estimation is insufficient causing Light-sleep oversleep, assertion failure and system crash may occur.
|
||||
|
||||
It is recommended to keep this option disabled by default to maintain tick accuracy. Enable it only when you experience assertion failures related to :cpp:func:`vTaskStepTick()` and can accept slight inaccuracy of RTOS tick time compared to real time.
|
||||
|
||||
Debugging and Profiling
|
||||
-----------------------
|
||||
|
||||
The power management subsystem provides several functions to help debug and profile power management lock usage in applications:
|
||||
|
||||
- :cpp:func:`esp_pm_dump_locks` - Dumps a list of all currently created locks to a specified stream, showing their types, names, and current acquisition status.
|
||||
- :cpp:func:`esp_pm_get_lock_stats_all` - Retrieves statistics for all PM lock types, including the number of locks created and the number currently acquired.
|
||||
- :cpp:func:`esp_pm_lock_get_stats` - Gets detailed statistics for a specific lock instance, including acquisition count and (if profiling is enabled) the number of times taken and total time held.
|
||||
|
||||
These functions are particularly useful for:
|
||||
|
||||
1. Identifying leaks where locks are acquired but never released
|
||||
2. Understanding which components are preventing power savings
|
||||
3. Optimizing power consumption by analyzing lock usage patterns
|
||||
4. Debugging issues related to lock management in applications
|
||||
|
||||
To enable profiling features (timing information for individual locks), enable the :ref:`CONFIG_PM_PROFILING` option in menuconfig.
|
||||
|
||||
Dynamic Frequency Scaling and Peripheral Drivers
|
||||
------------------------------------------------
|
||||
|
||||
@@ -92,6 +92,43 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
|
||||
|
||||
为了跳过不必要的唤醒,可以将 ``skip_unhandled_events`` 选项设置为 ``true`` 来初始化 ``esp_timer``。带有此标志的定时器不会唤醒系统,有助于减少功耗。
|
||||
|
||||
自动 Light-sleep 时间补偿机制
|
||||
---------------------------------------
|
||||
|
||||
ESP-IDF 使用预测性时间补偿机制来实现自动 Light-sleep。系统会在每次 Light-sleep 周期后测量实际的唤醒开销,并使用该测量值来预测下一次睡眠周期的唤醒开销。
|
||||
|
||||
系统根据下一个计划事件计算睡眠持续时间,并减去预测的唤醒开销(来自上一周期)来设置唤醒定时器。唤醒后,由于睡眠期间 FreeRTOS systick 中断被暂停,系统需要调用 :cpp:func:`vTaskStepTick()` 来补偿睡眠期间经过的 tick 数,以保持 FreeRTOS tick 计数的准确性。同时,系统测量实际开销并记录,用于下次预测,形成自适应系统行为的反馈循环。
|
||||
|
||||
但实际开销可能因缓存未命中、CPU 频率变化、Flash 延迟变化或硬件状态恢复时间而有所不同。当实际开销超过预测值时,实际睡眠时间可能超过预期,导致 :cpp:func:`vTaskStepTick()` 接收到的 tick 补偿值过大,触发断言失败。
|
||||
|
||||
:ref:`CONFIG_PM_LIGHTSLEEP_TICK_OVERFLOW_PROTECTION` 选项提供了一个安全机制,用于在唤醒开销超过预测时防止断言失败。启用后,系统会限制 tick 补偿值以防止溢出。在 menuconfig 中可通过 ``Component config`` > ``Power Management`` > ``Enable light sleep tick overflow protection`` 启用此选项。
|
||||
|
||||
启用该选项时,系统对睡过超时情况的处理如下:
|
||||
- 如果睡过超时在容忍范围内(可通过 :ref:`CONFIG_PM_LIGHTSLEEP_TICK_OVERFLOW_TOLERANCE` 配置,默认:2 个 tick),系统会静默地将 ``slept_ticks`` 限制为 ``xExpectedIdleTime``,防止断言失败
|
||||
- 如果睡过超时超过容忍范围(可能存在 bug),系统不会限制 tick,会抛出错误日志,并触发断言失败
|
||||
- 在极少数边缘场景下可能会丢失 tick,导致 FreeRTOS tick 计数(``xTickCount``)落后于真实时间(``esp_timer``),使用 :cpp:func:`vTaskDelay()` 的任务可能比预期延迟稍长,FreeRTOS 软件定时器精度可能降低。
|
||||
|
||||
禁用该选项时(默认),可以获得准确的 tick 补偿,对时间关键应用具有更好的精度。在边缘情况下, 如果唤醒开销估算不足导致 Light-sleep 睡过超时时,可能会触发断言失败导致系统崩溃。
|
||||
|
||||
建议默认保持禁用状态以维持 tick 精度。仅在遇到与 :cpp:func:`vTaskStepTick()` 相关的断言失败,且可以接受 RTOS tick 时间相较于真实时间轻微不准时启用。
|
||||
|
||||
调试和性能分析
|
||||
-----------------------
|
||||
|
||||
电源管理子系统提供了几个函数来帮助调试和分析应用程序中的电源管理锁使用情况:
|
||||
|
||||
- :cpp:func:`esp_pm_dump_locks` - 将所有当前创建的锁列表转储到指定流,显示其类型、名称和当前获取状态。
|
||||
- :cpp:func:`esp_pm_get_lock_stats_all` - 获取所有 PM 锁类型的统计信息,包括创建的锁数量和当前持有数。
|
||||
- :cpp:func:`esp_pm_lock_get_stats` - 获取特定锁实例的详细统计信息,包括获取计数(如果启用性能分析)和总占用时间。
|
||||
|
||||
这些函数特别适用于:
|
||||
|
||||
1. 识别获取但从未释放的锁导致的泄漏
|
||||
2. 了解哪些组件阻止了节能
|
||||
3. 通过分析锁使用模式来优化功耗
|
||||
4. 调试与应用程序中锁管理相关的问题
|
||||
|
||||
要启用性能分析功能(单个锁的计时信息),请在 menuconfig 中启用 :ref:`CONFIG_PM_PROFILING` 选项。
|
||||
|
||||
动态调频和外设驱动
|
||||
------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user