From 4011a4de745183e02f9cc2abe30a9b3c41bc2996 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 11 Jun 2026 11:32:31 +0800 Subject: [PATCH 1/4] feat(esp_hw_support): support sleep retention destroy callback --- .../include/esp_private/sleep_retention.h | 8 +++++++- components/esp_hw_support/sleep_retention.c | 19 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index aed019c1202..bd0f2a2d4bc 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -52,7 +52,13 @@ typedef struct { } sleep_retention_create_callback_t; typedef struct { - sleep_retention_create_callback_t create; /*!< A function handle is used to register the implementation of creating a sleep retention linked list and is executed when the corresponding module is created */ + sleep_retention_callback_t handle; + void *arg; +} sleep_retention_destroy_callback_t; + +typedef struct { + sleep_retention_create_callback_t create; /*!< A function handle is used to register the implementation of creating a sleep retention linked list and is executed when the corresponding module is created */ + sleep_retention_destroy_callback_t destroy; /*!< The callback function handle is invoked after the sleep retention linked list is destroyed */ } sleep_retention_module_callbacks_t; typedef enum { diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 54bad4f9901..c1423f88572 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -60,7 +60,10 @@ static inline void sleep_retention_module_object_ctor(struct sleep_retention_mod static inline void sleep_retention_module_object_dtor(struct sleep_retention_module_object * const self) { - self->cbs = (sleep_retention_module_callbacks_t) { .create = { .handle = NULL, .arg = NULL } }; + self->cbs = (sleep_retention_module_callbacks_t) { + .create = { .handle = NULL, .arg = NULL }, + .destroy = { .handle = NULL, .arg = NULL } + }; } static inline void set_dependencies(struct sleep_retention_module_object * const self, sleep_retention_module_bitmap_t depends) @@ -1075,7 +1078,12 @@ static esp_err_t passive_module_free(sleep_retention_module_t module) if (!references_exist(instance(module))) { if (!module_is_retained(module)) { sleep_retention_entries_destroy(module); - err = module_action_wrapper(module, (BIT(31) | action(2)), passive_module_free); + if (instance(module)->cbs.destroy.handle) { + err = instance(module)->cbs.destroy.handle(instance(module)->cbs.destroy.arg); + } + if (err == ESP_OK) { + err = module_action_wrapper(module, (BIT(31) | action(2)), passive_module_free); + } } else { err = ESP_ERR_INVALID_STATE; } @@ -1096,7 +1104,12 @@ esp_err_t sleep_retention_module_free(sleep_retention_module_t module) if (!module_is_passive(instance(module))) { if (module_is_inited(module) && module_is_created(module) && !module_is_retained(module)) { sleep_retention_entries_destroy(module); - err = module_action_wrapper(module, action(2), passive_module_free); + if (instance(module)->cbs.destroy.handle) { + err = instance(module)->cbs.destroy.handle(instance(module)->cbs.destroy.arg); + } + if (err == ESP_OK) { + err = module_action_wrapper(module, action(2), passive_module_free); + } } else { err = ESP_ERR_INVALID_STATE; } From e7fff9da43534b1c49a679e5b33c99e5356448ca Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 11 Jun 2026 11:41:40 +0800 Subject: [PATCH 2/4] change(esp_hw_support): rename retention_modules to attached_modules --- components/esp_hw_support/sleep_retention.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index c1423f88572..d2534d800f1 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -249,7 +249,7 @@ typedef struct { regdma_link_priority_t highpri; sleep_retention_module_bitmap_t inited_modules; sleep_retention_module_bitmap_t created_modules; - sleep_retention_module_bitmap_t retention_modules; + sleep_retention_module_bitmap_t attached_modules; void *final_default; @@ -262,7 +262,7 @@ static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = { .highpri = (uint8_t)-1, .inited_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, .created_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, - .retention_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, + .attached_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, .final_default = NULL }; @@ -836,7 +836,7 @@ sleep_retention_module_bitmap_t IRAM_ATTR sleep_retention_get_created_modules(vo sleep_retention_module_bitmap_t IRAM_ATTR sleep_retention_get_retained_modules(void) { - return s_retention.retention_modules; + return s_retention.attached_modules; } bool sleep_retention_is_module_inited(sleep_retention_module_t module) @@ -1154,7 +1154,7 @@ static esp_err_t passive_module_attach(sleep_retention_module_t module) assert(module_is_inited(module) && "All passive module must be inited first!"); if (module_is_inited(module) && module_is_created(module) && !module_is_retained(module)) { module_entries_move(module, &s_retention.context[1], &s_retention.retention); - s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32); + s_retention.attached_modules.bitmap[module >> 5] |= BIT(module % 32); err = module_action_wrapper(module, (BIT(31) | action(3)), passive_module_attach); } _lock_release_recursive(&s_retention.lock); @@ -1173,7 +1173,7 @@ esp_err_t sleep_retention_module_attach(sleep_retention_module_t module) if (module_is_inited(module) && module_is_created(module) && !module_is_retained(module)) { if (module_runtime_attach(instance(module))) { module_entries_move(module, &s_retention.context[1], &s_retention.retention); - s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32); + s_retention.attached_modules.bitmap[module >> 5] |= BIT(module % 32); err = module_action_wrapper(module, action(3), passive_module_attach); } else { err = ESP_ERR_NOT_SUPPORTED; @@ -1200,7 +1200,7 @@ static esp_err_t passive_module_detach(sleep_retention_module_t module) if (module_is_inited(module) && module_is_created(module) && module_is_retained(module)) { if (refarray_zero(instance(module), 1)) { module_entries_move(module, &s_retention.retention, &s_retention.context[1]); - s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32); + s_retention.attached_modules.bitmap[module >> 5] &= ~BIT(module % 32); err = module_action_wrapper(module, (BIT(31) | action(4)), passive_module_detach); } } @@ -1220,7 +1220,7 @@ esp_err_t sleep_retention_module_detach(sleep_retention_module_t module) if (module_is_inited(module) && module_is_created(module) && module_is_retained(module)) { if (module_runtime_attach(instance(module))) { module_entries_move(module, &s_retention.retention, &s_retention.context[1]); - s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32); + s_retention.attached_modules.bitmap[module >> 5] &= ~BIT(module % 32); err = module_action_wrapper(module, action(4), passive_module_detach); } else { err = ESP_ERR_NOT_SUPPORTED; From a9f278d9ba28a6ada0cacb0040e2cd0f708c05bd Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 11 Jun 2026 11:59:34 +0800 Subject: [PATCH 3/4] change(esp_hw_support): maintain runtime retention module information --- components/esp_hw_support/sleep_retention.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index d2534d800f1..2203adba39c 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -250,6 +250,7 @@ typedef struct { sleep_retention_module_bitmap_t inited_modules; sleep_retention_module_bitmap_t created_modules; sleep_retention_module_bitmap_t attached_modules; + sleep_retention_module_bitmap_t retention_modules; void *final_default; @@ -263,6 +264,7 @@ static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = { .inited_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, .created_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, .attached_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, + .retention_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } }, .final_default = NULL }; @@ -462,7 +464,10 @@ void * sleep_retention_find_link_by_id(int id) if (s_retention.highpri >= SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY && s_retention.highpri <= SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { for (int entry = 0; (link == NULL && entry < ARRAY_SIZE(s_retention.retention.lists[s_retention.highpri].entries)); entry++) { - link = regdma_find_link_by_id(s_retention.retention.lists[s_retention.highpri].entries[entry], entry, id); + link = regdma_find_link_by_id(s_retention.context[0].lists[s_retention.highpri].entries[entry], entry, id); + } + for (int entry = 0; (link == NULL && entry < ARRAY_SIZE(s_retention.retention.lists[s_retention.highpri].entries)); entry++) { + link = regdma_find_link_by_id(s_retention.context[1].lists[s_retention.highpri].entries[entry], entry, id); } } _lock_release_recursive(&s_retention.lock); @@ -631,6 +636,7 @@ static void entries_do_destroy(sleep_retention_module_t module) priority++; } } while (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES); + s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32); s_retention.created_modules.bitmap[module >> 5] &= ~BIT(module % 32); _lock_release_recursive(&s_retention.lock); } @@ -788,6 +794,7 @@ static esp_err_t entries_create_wrapper(const sleep_retention_entries_config_t r if(err) goto error; s_retention.created_modules.bitmap[module >> 5] |= BIT(module % 32); if (!module_runtime_attach(instance(module))) { + s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32); retention_entries_join(); } error: @@ -1155,6 +1162,7 @@ static esp_err_t passive_module_attach(sleep_retention_module_t module) if (module_is_inited(module) && module_is_created(module) && !module_is_retained(module)) { module_entries_move(module, &s_retention.context[1], &s_retention.retention); s_retention.attached_modules.bitmap[module >> 5] |= BIT(module % 32); + s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32); err = module_action_wrapper(module, (BIT(31) | action(3)), passive_module_attach); } _lock_release_recursive(&s_retention.lock); @@ -1174,6 +1182,7 @@ esp_err_t sleep_retention_module_attach(sleep_retention_module_t module) if (module_runtime_attach(instance(module))) { module_entries_move(module, &s_retention.context[1], &s_retention.retention); s_retention.attached_modules.bitmap[module >> 5] |= BIT(module % 32); + s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32); err = module_action_wrapper(module, action(3), passive_module_attach); } else { err = ESP_ERR_NOT_SUPPORTED; @@ -1200,6 +1209,7 @@ static esp_err_t passive_module_detach(sleep_retention_module_t module) if (module_is_inited(module) && module_is_created(module) && module_is_retained(module)) { if (refarray_zero(instance(module), 1)) { module_entries_move(module, &s_retention.retention, &s_retention.context[1]); + s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32); s_retention.attached_modules.bitmap[module >> 5] &= ~BIT(module % 32); err = module_action_wrapper(module, (BIT(31) | action(4)), passive_module_detach); } @@ -1220,6 +1230,7 @@ esp_err_t sleep_retention_module_detach(sleep_retention_module_t module) if (module_is_inited(module) && module_is_created(module) && module_is_retained(module)) { if (module_runtime_attach(instance(module))) { module_entries_move(module, &s_retention.retention, &s_retention.context[1]); + s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32); s_retention.attached_modules.bitmap[module >> 5] &= ~BIT(module % 32); err = module_action_wrapper(module, action(4), passive_module_detach); } else { From b624a348adf98b4befb34a502ad6a19764446ff5 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Fri, 26 Jun 2026 15:18:44 +0800 Subject: [PATCH 4/4] fix(esp_hw_support): apply some suggestions --- .../esp_hw_support/include/esp_private/sleep_retention.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index bd0f2a2d4bc..18eb64c8552 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -57,8 +57,8 @@ typedef struct { } sleep_retention_destroy_callback_t; typedef struct { - sleep_retention_create_callback_t create; /*!< A function handle is used to register the implementation of creating a sleep retention linked list and is executed when the corresponding module is created */ - sleep_retention_destroy_callback_t destroy; /*!< The callback function handle is invoked after the sleep retention linked list is destroyed */ + sleep_retention_create_callback_t create; /*!< A function handler is used to register the implementation of creating a sleep retention linked list and is executed when the corresponding module is created */ + sleep_retention_destroy_callback_t destroy; /*!< The callback function handler is invoked after the sleep retention linked list is destroyed */ } sleep_retention_module_callbacks_t; typedef enum {