Merge branch 'fix/fix_esp32_int_wdt_workaround_break_sleep_process' into 'master'

fix(esp_system): disable esp32 cache livelock int_wdt workaround in ipc_isr_stall

Closes IDFCI-7791

See merge request espressif/esp-idf!45645
This commit is contained in:
Wu Zheng Hui
2026-03-18 19:07:17 +08:00
9 changed files with 315 additions and 89 deletions
@@ -540,9 +540,45 @@ flash 进入 deep power-down 模式
UART 输出处理
^^^^^^^^^^^^^^^^^^^^
在进入睡眠模式之前,调用函数 :cpp:func:`esp_deep_sleep_start` 会冲刷掉 UART FIFO 缓存。
进入睡眠前,睡眠流程会对**控制台 UART**(用于调试输出的 UART,由 :ref:`CONFIG_ESP_CONSOLE_UART_NUM` 选定)进行准备,以避免 APB 时钟变化或掉电导致输出乱码或未定义行为。所采用的策略可配置,会影响数据完整性、进入睡眠的时间以及功耗。
当使用函数 :cpp:func:`esp_light_sleep_start` 进入 Light-sleep 模式时,UART FIFO 将不会被冲刷。与之相反,UART 输出将被暂停,FIFO 中的剩余字符将在 Light-sleep 唤醒后被发送。
**默认行为(自动模式)**
若不调用 :cpp:func:`esp_sleep_set_console_uart_handling_mode`,则采用以下默认策略:
- **Deep-sleep**:始终等到控制台 UART FIFO 中的数据全部发完后再进入睡眠,确保所有调试输出被发送且不丢数据。
- **Light-sleep**:行为取决于 UART 所在电源域是否掉电:
- 若 UART 保持供电(例如 HP 外设域未掉电):在当前帧发完后挂起 UART 输出;唤醒后恢复发送,睡眠前 UART TX FIFO 中剩余数据会继续发出。
- 若 UART 电源域掉电:睡眠流程会等到控制台 UART TX FIFO 中的数据全部发完后再进入睡眠;其他 UART 中的数据会被丢弃以更快进入睡眠。
**配置控制台 UART 处理方式**
可通过调用 :cpp:func:`esp_sleep_set_console_uart_handling_mode` 覆盖默认行为,并选择下列模式之一(参见 :cpp:enum:`esp_sleep_uart_handling_mode_t`):
- :cpp:enumerator:`ESP_SLEEP_AUTO_FLUSH_SUSPEND_UART` (默认):根据睡眠类型和电源域自动选择冲刷或挂起,如上所述。
- :cpp:enumerator:`ESP_SLEEP_ALWAYS_FLUSH_UART` :进入睡眠前始终等待控制台 UART TX FIFO 中的数据全部发送完毕。适用于必须保证所有调试输出可见的场景;进入睡眠时间会更长,芯片处于 Active 状态的时间变长进而增加功耗。
- :cpp:enumerator:`ESP_SLEEP_ALWAYS_SUSPEND_UART` :等待当前 UART 帧发完后挂起 UART。若 Light-sleep 期间 UART 保持供电,唤醒后会继续发送;若 UART 电源域掉电,未发送的数据将丢失。
- :cpp:enumerator:`ESP_SLEEP_ALWAYS_DISCARD_UART` :丢弃控制台 UART FIFO 中所有未发送数据并立即进入睡眠。适用于追求最快进入睡眠和最低功耗、且可接受丢弃调试输出的场景。
- :cpp:enumerator:`ESP_SLEEP_NO_HANDLING` :进入睡眠前不对控制台 UART 做任何处理。仅在确认 UART 状态安全时使用(例如无待发数据或已禁用控制台 UART)。
.. note::
睡眠流程在临界区中执行,当使用会冲刷控制台 UART 的模式(如 :cpp:enumerator:`ESP_SLEEP_ALWAYS_FLUSH_UART` ,或 HP 外设域掉电时的 Light-sleep/Deep-sleep 默认行为)时,请将 :ref:`CONFIG_ESP_INT_WDT_TIMEOUT_MS` 配置为**大于** ``SOC_UART_FIFO_LEN`` ×(当前波特率下发送一个字符所需时间)。否则若 TX FIFO 中积压数据过多,冲刷时间可能超过中断看门狗超时,会在进入睡眠过程中触发看门狗复位。
示例:在每次睡眠前确保所有调试输出已发出::
.. code-block:: c
fflush(stdout);
esp_sleep_set_console_uart_handling_mode(ESP_SLEEP_ALWAYS_FLUSH_UART);
esp_light_sleep_start();
示例:尽量缩短进入睡眠时间并允许丢弃控制台输出::
.. code-block:: c
esp_sleep_set_console_uart_handling_mode(ESP_SLEEP_ALWAYS_DISCARD_UART);
esp_deep_sleep_start();
.. _wakeup_cause: