feat(core-system/wdt): added support for watchdogs on P4

This commit is contained in:
Marius Vikhammer 2023-08-28 08:54:13 +08:00
parent 9552ef012d
commit 8ecbd1f59b
7 changed files with 118 additions and 115 deletions

View File

@ -17,6 +17,7 @@ extern "C" {
#include <stdbool.h>
#include "soc/timer_periph.h"
#include "soc/timer_group_struct.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "hal/wdt_types.h"
#include "hal/assert.h"
#include "esp_attr.h"
@ -24,24 +25,23 @@ extern "C" {
#include "hal/misc.h"
/* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */
#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000
#define MWDT_LL_DEFAULT_CLK_PRESCALER 20000
//TODO: IDF-6516
// //Type check wdt_stage_action_t
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == TIMG_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
// ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == TIMG_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
// //Type check wdt_reset_sig_length_t
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == TIMG_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == TIMG_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == TIMG_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == TIMG_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == TIMG_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == TIMG_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == TIMG_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
// ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == TIMG_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == TIMG_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
//Type check wdt_reset_sig_length_t
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == TIMG_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == TIMG_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == TIMG_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == TIMG_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == TIMG_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == TIMG_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == TIMG_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
/**
* @brief Enable the MWDT
@ -50,8 +50,7 @@ extern "C" {
*/
FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
{
// hw->wdt_config0.en = 1;
abort();
hw->wdtconfig0.wdt_en = 1;
}
/**
@ -64,8 +63,7 @@ FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
*/
FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
{
// hw->wdt_config0.en = 0;
abort();
hw->wdtconfig0.wdt_en = 0;
}
/**
@ -76,8 +74,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
*/
FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
{
// return (hw->wdt_config0.en) ? true : false;
abort();
return (hw->wdtconfig0.wdt_en) ? true : false;
}
/**
@ -90,30 +87,29 @@ FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
*/
FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, uint32_t timeout, wdt_stage_action_t behavior)
{
// switch (stage) {
// case WDT_STAGE0:
// hw->wdt_config0.stg0 = behavior;
// hw->wdt_config2 = timeout;
// break;
// case WDT_STAGE1:
// hw->wdt_config0.stg1 = behavior;
// hw->wdt_config3 = timeout;
// break;
// case WDT_STAGE2:
// hw->wdt_config0.stg2 = behavior;
// hw->wdt_config4 = timeout;
// break;
// case WDT_STAGE3:
// hw->wdt_config0.stg3 = behavior;
// hw->wdt_config5 = timeout;
// break;
// default:
// HAL_ASSERT(false && "unsupported WDT stage");
// break;
// }
// //Config registers are updated asynchronously
// //hw->wdt_config0.wdt_conf_update_en = 1;
abort();
switch (stage) {
case WDT_STAGE0:
hw->wdtconfig0.wdt_stg0 = behavior;
hw->wdtconfig2.wdt_stg0_hold = timeout;
break;
case WDT_STAGE1:
hw->wdtconfig0.wdt_stg1 = behavior;
hw->wdtconfig3.wdt_stg1_hold = timeout;
break;
case WDT_STAGE2:
hw->wdtconfig0.wdt_stg2 = behavior;
hw->wdtconfig4.wdt_stg2_hold = timeout;
break;
case WDT_STAGE3:
hw->wdtconfig0.wdt_stg3 = behavior;
hw->wdtconfig5.wdt_stg3_hold = timeout;
break;
default:
HAL_ASSERT(false && "unsupported WDT stage");
break;
}
//Config registers are updated asynchronously
hw->wdtconfig0.wdt_conf_update_en = 1;
}
/**
@ -124,26 +120,25 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
*/
FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
{
// switch (stage) {
// case WDT_STAGE0:
// hw->wdt_config0.stg0 = WDT_STAGE_ACTION_OFF;
// break;
// case WDT_STAGE1:
// hw->wdt_config0.stg1 = WDT_STAGE_ACTION_OFF;
// break;
// case WDT_STAGE2:
// hw->wdt_config0.stg2 = WDT_STAGE_ACTION_OFF;
// break;
// case WDT_STAGE3:
// hw->wdt_config0.stg3 = WDT_STAGE_ACTION_OFF;
// break;
// default:
// HAL_ASSERT(false && "unsupported WDT stage");
// break;
// }
// //Config registers are updated asynchronously
// //hw->wdt_config0.wdt_conf_update_en = 1;
abort();
switch (stage) {
case WDT_STAGE0:
hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF;
break;
case WDT_STAGE1:
hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF;
break;
case WDT_STAGE2:
hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF;
break;
case WDT_STAGE3:
hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
break;
default:
HAL_ASSERT(false && "unsupported WDT stage");
break;
}
//Config registers are updated asynchronously
hw->wdtconfig0.wdt_conf_update_en = 1;
}
/**
@ -154,10 +149,9 @@ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
*/
FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{
// hw->wdt_config0.cpu_reset_length = length;
// //Config registers are updated asynchronously
// //hw->wdt_config0.wdt_conf_update_en = 1;
abort();
hw->wdtconfig0.wdt_cpu_reset_length = length;
//Config registers are updated asynchronously
hw->wdtconfig0.wdt_conf_update_en = 1;
}
/**
@ -168,10 +162,9 @@ FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_si
*/
FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{
// hw->wdt_config0.sys_reset_length = length;
// //Config registers are updated asynchronously
// //hw->wdt_config0.wdt_conf_update_en = 1;
abort();
hw->wdtconfig0.wdt_sys_reset_length = length;
//Config registers are updated asynchronously
hw->wdtconfig0.wdt_conf_update_en = 1;
}
/**
@ -186,10 +179,9 @@ FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_si
*/
FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
{
// hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0;
// //Config registers are updated asynchronously
// //hw->wdt_config0.wdt_conf_update_en = 1;
abort();
hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0;
//Config registers are updated asynchronously
hw->wdtconfig0.wdt_conf_update_en = 1;
}
/**
@ -200,12 +192,11 @@ FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
*/
FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
{
// // In case the compiler optimise a 32bit instruction (e.g. s32i) into 8/16bit instruction (e.g. s8i, which is not allowed to access a register)
// // We take care of the "read-modify-write" procedure by ourselves.
// HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdt_config1, clk_prescale, prescaler);
// //Config registers are updated asynchronously
// //hw->wdt_config0.wdt_conf_update_en = 1;
abort();
// In case the compiler optimise a 32bit instruction (e.g. s32i) into 8/16bit instruction (e.g. s8i, which is not allowed to access a register)
// We take care of the "read-modify-write" procedure by ourselves.
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wdtconfig1, wdt_clk_prescale, prescaler);
//Config registers are updated asynchronously
hw->wdtconfig0.wdt_conf_update_en = 1;
}
/**
@ -217,8 +208,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
*/
FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
{
// hw->wdt_feed = 1;
abort();
hw->wdtfeed.wdt_feed = 1;
}
/**
@ -230,8 +220,7 @@ FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
*/
FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
{
// hw->wdt_wprotect = 0;
abort();
hw->wdtwprotect.wdt_wkey = 0;
}
/**
@ -241,8 +230,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
*/
FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
{
// hw->wdt_wprotect = TIMG_WDT_WKEY_VALUE;
abort();
hw->wdtwprotect.wdt_wkey = TIMG_WDT_WKEY_VALUE;
}
/**
@ -252,8 +240,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
*/
FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
{
// hw->int_clr.wdt = 1;
abort();
hw->int_clr_timers.wdt_int_clr = 1;
}
/**
@ -264,10 +251,10 @@ FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
*/
FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
{
// hw->int_ena.wdt = (enable) ? 1 : 0;
abort();
hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
}
/**
* @brief Set the clock source for the MWDT.
*
@ -276,8 +263,17 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
/* We currently always use default clock source on P4: XTAL
If we update to be able to select a clock source then this function
needs to be protected with PERIPH_RCC_ATOMIC as it touches shared registers.
*/
(void)hw;
(void)clk_src;
HAL_ASSERT(clk_src == MWDT_CLK_SRC_XTAL);
}
/**
* @brief Enable MWDT module clock
*
@ -287,10 +283,15 @@ FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_sourc
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
/* The clock always defaults to enabled on P4.
If we update to be able to enable/disable the clock then this function
needs to be protected with PERIPH_RCC_ATOMIC as it touches shared registers.
*/
(void)hw;
(void)en;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -28,12 +28,6 @@ extern "C" {
#define TIMG_WDT_RESET_LENGTH_800_NS 5
#define TIMG_WDT_RESET_LENGTH_1600_NS 6
#define TIMG_WDT_RESET_LENGTH_3200_NS 7
/* Possible values for TIMG_WDT_STGx */
#define TIMG_WDT_STG_SEL_OFF 0
#define TIMG_WDT_STG_SEL_INT 1
#define TIMG_WDT_STG_SEL_RESET_CPU 2
#define TIMG_WDT_STG_SEL_RESET_SYSTEM 3
/** TIMG_T0CONFIG_REG register
* Timer 0 configuration register

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -28,12 +28,6 @@ extern "C" {
#define TIMG_WDT_RESET_LENGTH_800_NS 5
#define TIMG_WDT_RESET_LENGTH_1600_NS 6
#define TIMG_WDT_RESET_LENGTH_3200_NS 7
/* Possible values for TIMG_WDT_STGx */
#define TIMG_WDT_STG_SEL_OFF 0
#define TIMG_WDT_STG_SEL_INT 1
#define TIMG_WDT_STG_SEL_RESET_CPU 2
#define TIMG_WDT_STG_SEL_RESET_SYSTEM 3
/** TIMG_T0CONFIG_REG register
* Timer 0 configuration register

View File

@ -338,7 +338,6 @@ typedef enum {
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
//TODO: IDF-6516
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
@ -351,7 +350,7 @@ typedef enum {
MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MWDT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the source clock */
MWDT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RTC fast as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the default clock choice */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL 40 MHz as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////

View File

@ -11,6 +11,24 @@
extern "C" {
#endif
/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */
#define TIMG_WDT_WKEY_VALUE 0x50D83AA1
/* Possible values for TIMG_WDT_STGx */
#define TIMG_WDT_STG_SEL_OFF 0
#define TIMG_WDT_STG_SEL_INT 1
#define TIMG_WDT_STG_SEL_RESET_CPU 2
#define TIMG_WDT_STG_SEL_RESET_SYSTEM 3
#define TIMG_WDT_RESET_LENGTH_100_NS 0
#define TIMG_WDT_RESET_LENGTH_200_NS 1
#define TIMG_WDT_RESET_LENGTH_300_NS 2
#define TIMG_WDT_RESET_LENGTH_400_NS 3
#define TIMG_WDT_RESET_LENGTH_500_NS 4
#define TIMG_WDT_RESET_LENGTH_800_NS 5
#define TIMG_WDT_RESET_LENGTH_1600_NS 6
#define TIMG_WDT_RESET_LENGTH_3200_NS 7
/** TIMG_T0CONFIG_REG register
* Timer 0 configuration register
*/

View File

@ -183,7 +183,6 @@ api-reference/system/freertos_additions.rst
api-reference/system/himem.rst
api-reference/system/power_management.rst
api-reference/system/mem_alloc.rst
api-reference/system/wdts.rst
api-reference/system/misc_system_api.rst
api-reference/system/bootloader_image_format.rst
api-reference/system/inc/espefuse_summary_ESP32-P4.rst

View File

@ -57,9 +57,7 @@ Neither critical sections or interrupt handlers should ever block waiting for an
Task Watchdog Timer (TWDT)
--------------------------
{IDF_TARGET_IDLE_TASKS:default="Idle task", esp32="Idle Tasks of each CPU", esp32s3="Idle Tasks of each CPU"}
The Task Watchdog Timer (TWDT) is used to monitor particular tasks, ensuring that they are able to execute within a given timeout period. The TWDT primarily watches the {IDF_TARGET_IDLE_TASKS}, however any task can subscribe to be watched by the TWDT. By watching the {IDF_TARGET_IDLE_TASKS}, the TWDT can detect instances of tasks running for a prolonged period of time wihtout yielding. This can be an indicator of poorly written code that spinloops on a peripheral, or a task that is stuck in an infinite loop.
The Task Watchdog Timer (TWDT) is used to monitor particular tasks, ensuring that they are able to execute within a given timeout period. The TWDT primarily watches the Idle Tasks of each CPU, however any task can subscribe to be watched by the TWDT. By watching the Idle Tasks of each CPU, the TWDT can detect instances of tasks running for a prolonged period of time wihtout yielding. This can be an indicator of poorly written code that spinloops on a peripheral, or a task that is stuck in an infinite loop.
.. only:: not esp32c2
@ -103,7 +101,7 @@ The default timeout period for the TWDT is set using config item :ref:`CONFIG_ES
The following config options control TWDT configuration. They are all enabled by default:
{IDF_TARGET_IDLE_TASK:default="Idle task", esp32="CPU0 Idle task", esp32s3="CPU0 Idle task"}
{IDF_TARGET_IDLE_TASK:default="Idle task", esp32="CPU0 Idle task", esp32s3="CPU0 Idle task", esp32p4="CPU0 Idle task"}
.. list::