Merge branch 'feat/pm_components_ram_optimize' into 'master'

feat(pm): pm components ram optimize

Closes PM-840

See merge request espressif/esp-idf!51672
This commit is contained in:
Jiang Jiang Jian
2026-09-04 10:32:26 +08:00
43 changed files with 210 additions and 166 deletions
@@ -17,7 +17,7 @@ extern "C" {
#include "esp_regdma.h"
#include "soc/retention_periph_defs.h"
#define SLEEP_RETENTION_MODULE_BITMAP_SZ ((SLEEP_RETENTION_MODULE_MAX >> 5) + 1)
#define SLEEP_RETENTION_MODULE_BITMAP_SZ (((SLEEP_RETENTION_MODULE_MAX - 1) >> 5) + 1)
/**
* @file sleep_retention.h
+7 -1
View File
@@ -47,7 +47,13 @@ entries:
pmu_init (noflash)
pmu_param (noflash)
if SOC_LIGHT_SLEEP_SUPPORTED = y:
pmu_sleep (noflash)
if SPIRAM_FLASH_LOAD_TO_PSRAM = y || PM_SLP_IRAM_OPT = y:
pmu_sleep (noflash)
else:
if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE != y:
pmu_sleep:pmu_sleep_start (noflash)
pmu_sleep:pmu_sleep_finish (noflash)
pmu_sleep:pmu_sleep_get_wakup_retention_cost (noflash)
if PM_SLEEP_CLK_ICG_ENABLE = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP != y:
pmu_sleep_clock_icg:pmu_sleep_clock_icg_config (noflash)
if IDF_TARGET_ESP32H4 = y && BT_LE_MODEM_STATE_ENABLED = y:
@@ -3,6 +3,8 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <string.h>
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
@@ -53,7 +55,7 @@ static esp_err_t sleep_phy_retention_init(void *arg)
{
#define PHY_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_PHY))
static sleep_retention_entries_config_t phy_modem_config[] = {
static const sleep_retention_entries_config_t phy_modem_config_template[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x00), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = PHY_ENTRY() }, /* I2C MST enable */
/* Reset SET_FREQ fsm */
@@ -94,10 +96,17 @@ static esp_err_t sleep_phy_retention_init(void *arg)
[26] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = PHY_ENTRY() },
[27] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = PHY_ENTRY() }
};
sleep_retention_entries_config_t *phy_modem_config = malloc(sizeof(phy_modem_config_template));
if (phy_modem_config == NULL) {
return ESP_ERR_NO_MEM;
}
memcpy(phy_modem_config, phy_modem_config_template, sizeof(phy_modem_config_template));
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
phy_modem_config[5].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
phy_modem_config[17].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
esp_err_t err = sleep_retention_entries_create(phy_modem_config, ARRAY_SIZE(phy_modem_config), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
esp_err_t err = sleep_retention_entries_create(phy_modem_config, ARRAY_SIZE(phy_modem_config_template), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
free(phy_modem_config);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link");
return ESP_OK;
}
@@ -3,6 +3,8 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <string.h>
#include "esp_attr.h"
#include "soc/soc_caps.h"
@@ -51,7 +53,7 @@ esp_err_t sleep_phy_link_init(void **link_context)
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_MODEM
static regdma_link_config_t phy_modem_config[] = {
static const regdma_link_config_t phy_modem_config_template[] = {
[0] = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_FE_LINK(0), MODEM_FE_DATA_BASE, MODEM_FE_DATA_BASE, 41, 0, 0),
[1] = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_FE_LINK(1), MODEM_FE_CTRL_BASE, MODEM_FE_CTRL_BASE, 87, 0, 0),
@@ -106,12 +108,18 @@ esp_err_t sleep_phy_link_init(void **link_context)
[39] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x25), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
[40] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x26), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
};
regdma_link_config_t *phy_modem_config = malloc(sizeof(phy_modem_config_template));
if (phy_modem_config == NULL) {
return ESP_ERR_NO_MEM;
}
memcpy(phy_modem_config, phy_modem_config_template, sizeof(phy_modem_config_template));
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
phy_modem_config[8].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
phy_modem_config[24].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
void *link = NULL;
for (int i = ARRAY_SIZE(phy_modem_config) - 1; (err == ESP_OK) && (i >= 0); i--) {
for (int i = ARRAY_SIZE(phy_modem_config_template) - 1; (err == ESP_OK) && (i >= 0); i--) {
void *next = regdma_link_init_safe(&phy_modem_config[i], false, 0, link);
if (next) {
link = next;
@@ -120,6 +128,7 @@ esp_err_t sleep_phy_link_init(void **link_context)
err = ESP_ERR_NO_MEM;
}
}
free(phy_modem_config);
if (err == ESP_OK) {
pau_regdma_set_modem_link_addr(link);
@@ -3,6 +3,8 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <string.h>
#include "esp_attr.h"
#include "soc/soc_caps.h"
@@ -48,7 +50,7 @@ esp_err_t sleep_phy_link_init(void **link_context)
esp_err_t err = ESP_OK;
#if SOC_PM_PAU_REGDMA_LINK_MODEM
static regdma_link_config_t phy_modem_config[] = {
static const regdma_link_config_t phy_modem_config_template[] = {
[0] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x00), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), /* I2C MST enable */
/* Reset SET_FREQ fsm */
@@ -101,12 +103,18 @@ esp_err_t sleep_phy_link_init(void **link_context)
[36] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x24), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
[37] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x25), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
};
regdma_link_config_t *phy_modem_config = malloc(sizeof(phy_modem_config_template));
if (phy_modem_config == NULL) {
return ESP_ERR_NO_MEM;
}
memcpy(phy_modem_config, phy_modem_config_template, sizeof(phy_modem_config_template));
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
phy_modem_config[5].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
phy_modem_config[21].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
void *link = NULL;
for (int i = ARRAY_SIZE(phy_modem_config) - 1; (err == ESP_OK) && (i >= 0); i--) {
for (int i = ARRAY_SIZE(phy_modem_config_template) - 1; (err == ESP_OK) && (i >= 0); i--) {
void *next = regdma_link_init_safe(&phy_modem_config[i], false, 0, link);
if (next) {
link = next;
@@ -115,6 +123,7 @@ esp_err_t sleep_phy_link_init(void **link_context)
err = ESP_ERR_NO_MEM;
}
}
free(phy_modem_config);
if (err == ESP_OK) {
pau_regdma_set_modem_link_addr(link);
@@ -42,7 +42,7 @@ static int16_t s_sleep_clock_icg_refs[ESP_SLEEP_CLOCK_MAX];
#define RETENTION_COMMON PMU_CLK_ICGS( REGDMA, HPCORE ) | RETENTION_SYS_CLK
static const uint32_t s_retention_module_retention_clocks[SLEEP_RETENTION_MODULE_MAX + 1] = {
static const uint32_t s_retention_module_retention_clocks[SLEEP_RETENTION_MODULE_MAX] = {
[SLEEP_RETENTION_MODULE_NULL] = 0,
[SLEEP_RETENTION_MODULE_CLOCK_SYSTEM] = RETENTION_COMMON,
[SLEEP_RETENTION_MODULE_SYS_PERIPH] = RETENTION_COMMON | PMU_CLK_ICGS( IOMUX, SYSTIMER, SEC, MSPI ) | RETENTION_CONSOLE_UART,
@@ -85,7 +85,7 @@ void sleep_clock_icg_retention_clock_config(sleep_retention_module_bitmap_t *mod
/* Check if the last word holds bit above MODULE_MAX. */
assert(!module_bitmap->bitmap[SLEEP_RETENTION_MODULE_BITMAP_SZ - 1] ||
((31 - __builtin_clz(module_bitmap->bitmap[SLEEP_RETENTION_MODULE_BITMAP_SZ - 1])) +
((SLEEP_RETENTION_MODULE_BITMAP_SZ - 1) << 5)) <= SLEEP_RETENTION_MODULE_MAX);
((SLEEP_RETENTION_MODULE_BITMAP_SZ - 1) << 5)) < SLEEP_RETENTION_MODULE_MAX);
uint32_t clocks_mask = 0;
sleep_retention_module_t module = 0;
@@ -42,7 +42,7 @@ static int16_t s_sleep_clock_icg_refs[ESP_SLEEP_CLOCK_MAX];
#define RETENTION_COMMON PMU_CLK_ICGS( HPCORE ) | RETENTION_SYS_CLK
static const uint32_t s_retention_module_retention_clocks[SLEEP_RETENTION_MODULE_MAX + 1] = {
static const uint32_t s_retention_module_retention_clocks[SLEEP_RETENTION_MODULE_MAX] = {
[SLEEP_RETENTION_MODULE_NULL] = 0,
[SLEEP_RETENTION_MODULE_CLOCK_SYSTEM] = RETENTION_COMMON,
[SLEEP_RETENTION_MODULE_SYS_PERIPH] = RETENTION_COMMON | PMU_CLK_ICGS( IOMUX, SYSTIMER, SEC, MSPI ) | RETENTION_CONSOLE_UART,
@@ -90,7 +90,7 @@ void sleep_clock_icg_retention_clock_config(sleep_retention_module_bitmap_t *mod
/* Check if the last word holds bit above MODULE_MAX. */
assert(!module_bitmap->bitmap[SLEEP_RETENTION_MODULE_BITMAP_SZ - 1] ||
((31 - __builtin_clz(module_bitmap->bitmap[SLEEP_RETENTION_MODULE_BITMAP_SZ - 1])) +
((SLEEP_RETENTION_MODULE_BITMAP_SZ - 1) << 5)) <= SLEEP_RETENTION_MODULE_MAX);
((SLEEP_RETENTION_MODULE_BITMAP_SZ - 1) << 5)) < SLEEP_RETENTION_MODULE_MAX);
uint32_t clocks_mask = 0;
sleep_retention_module_t module = 0;
@@ -46,7 +46,7 @@ static int16_t s_sleep_clock_icg_refs[ESP_SLEEP_CLOCK_MAX];
#define RETENTION_COMMON PMU_CLK_ICGS( REGDMA, HPCORE0, HPCORE1 ) | RETENTION_SYS_CLK
static const uint64_t s_retention_module_retention_clocks[SLEEP_RETENTION_MODULE_MAX + 1] = {
static const uint64_t s_retention_module_retention_clocks[SLEEP_RETENTION_MODULE_MAX] = {
[SLEEP_RETENTION_MODULE_NULL] = 0,
[SLEEP_RETENTION_MODULE_CLOCK_SYSTEM] = RETENTION_COMMON,
[SLEEP_RETENTION_MODULE_SYS_PERIPH] = RETENTION_COMMON | PMU_CLK_ICGS( IOMUX, SYSTIMER, SEC, MSPI_FLASH, MSPI_PSRAM ) | RETENTION_CONSOLE_UART,
@@ -112,7 +112,7 @@ void sleep_clock_icg_retention_clock_config(sleep_retention_module_bitmap_t *mod
/* Check if the last word holds bit above MODULE_MAX. */
assert(!module_bitmap->bitmap[SLEEP_RETENTION_MODULE_BITMAP_SZ - 1] ||
((31 - __builtin_clz(module_bitmap->bitmap[SLEEP_RETENTION_MODULE_BITMAP_SZ - 1])) +
((SLEEP_RETENTION_MODULE_BITMAP_SZ - 1) << 5)) <= SLEEP_RETENTION_MODULE_MAX);
((SLEEP_RETENTION_MODULE_BITMAP_SZ - 1) << 5)) < SLEEP_RETENTION_MODULE_MAX);
uint64_t clocks_mask = 0;
sleep_retention_module_t module = 0;
@@ -3,6 +3,8 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <string.h>
#include "esp_log.h"
#include "esp_check.h"
#include "esp_attr.h"
@@ -50,7 +52,7 @@ static esp_err_t sleep_phy_retention_init(void *arg)
{
#define PHY_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_PHY))
static sleep_retention_entries_config_t phy_modem_config[] = {
static const sleep_retention_entries_config_t phy_modem_config_template[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x00), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = PHY_ENTRY() }, /* I2C MST enable */
/* PMU or software to trigger enable RF PHY */
@@ -88,10 +90,17 @@ static esp_err_t sleep_phy_retention_init(void *arg)
[24] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = PHY_ENTRY() },
[25] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = PHY_ENTRY() }
};
sleep_retention_entries_config_t *phy_modem_config = malloc(sizeof(phy_modem_config_template));
if (phy_modem_config == NULL) {
return ESP_ERR_NO_MEM;
}
memcpy(phy_modem_config, phy_modem_config_template, sizeof(phy_modem_config_template));
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
phy_modem_config[4].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
phy_modem_config[15].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
esp_err_t err = sleep_retention_entries_create(phy_modem_config, ARRAY_SIZE(phy_modem_config), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
esp_err_t err = sleep_retention_entries_create(phy_modem_config, ARRAY_SIZE(phy_modem_config_template), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
free(phy_modem_config);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link");
return ESP_OK;
}
@@ -57,7 +57,7 @@ void pmu_sleep_enable_regdma_backup(void)
pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal);
}
void pmu_sleep_disable_regdma_backup(void)
IRAM_ATTR void pmu_sleep_disable_regdma_backup(void)
{
assert(PMU_instance()->hal);
pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal);
@@ -341,7 +341,7 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp)
pmu_sleep_param_init(PMU_instance(), &config->param, dslp);
}
IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{
if (!dslp) {
#if !BOOTLOADER_BUILD && CONFIG_SPIRAM
@@ -381,7 +381,7 @@ IRAM_ATTR uint32_t pmu_sleep_get_reject_cause(void)
return pmu_ll_hp_get_reject_cause(PMU_instance()->hal->dev);
}
IRAM_ATTR bool pmu_sleep_finish(bool dslp)
bool pmu_sleep_finish(bool dslp)
{
#ifndef CONFIG_IDF_ENV_FPGA
// Wait eFuse memory update done.
+120 -72
View File
@@ -170,6 +170,7 @@ static inline bool module_runtime_attach(struct sleep_retention_module_object *
static inline bool module_is_passive(struct sleep_retention_module_object * const self)
{
assert(self);
return (get_attributes(self) & SLEEP_RETENTION_MODULE_ATTR_PASSIVE) ? true : false;
}
@@ -180,7 +181,7 @@ struct module_sleep_retention_context {
#define SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES (8u)
#define SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY (0)
#define SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY (SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES - 1)
#define SLEEP_RETENTION_MODULE_INVALID ((sleep_retention_module_t)(-1)) /* the final node does not belong to any module */
#define SLEEP_RETENTION_MODULE_INVALID ((sleep_retention_module_t)(SLEEP_RETENTION_MODULE_MAX)) /* the final node does not belong to any module */
struct {
sleep_retention_entries_t entries;
uint32_t entries_bitmap: REGDMA_LINK_ENTRY_NUM;
@@ -258,7 +259,7 @@ typedef struct {
void *final_default;
struct sleep_retention_module_object instance[SLEEP_RETENTION_MODULE_MAX + 1];
struct sleep_retention_module_object *instance[SLEEP_RETENTION_MODULE_MAX];
#define EXTRA_LINK_NUM (REGDMA_LINK_ENTRY_NUM - 1)
} sleep_retention_t;
@@ -280,7 +281,27 @@ static void retention_entries_join(void);
static struct sleep_retention_module_object * instance(sleep_retention_module_t module)
{
return (module == SLEEP_RETENTION_MODULE_INVALID) ? NULL : &s_retention.instance[module];
return (module >= SLEEP_RETENTION_MODULE_MAX) ? NULL : s_retention.instance[module];
}
static esp_err_t instance_allocate(sleep_retention_module_t module)
{
if (s_retention.instance[module] != NULL) {
return ESP_ERR_INVALID_STATE;
}
struct sleep_retention_module_object *obj = (struct sleep_retention_module_object *)heap_caps_calloc(
1, sizeof(struct sleep_retention_module_object), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (obj == NULL) {
return ESP_ERR_NO_MEM;
}
s_retention.instance[module] = obj;
return ESP_OK;
}
static void instance_free(sleep_retention_module_t module)
{
heap_caps_free(s_retention.instance[module]);
s_retention.instance[module] = NULL;
}
static inline bool module_is_inited(sleep_retention_module_t module)
@@ -425,7 +446,7 @@ static void * entries_try_create_bonding(const regdma_link_config_t *config, uin
void sleep_retention_dump_modules(FILE *out)
{
for (int i = SLEEP_RETENTION_MODULE_MIN; i <= SLEEP_RETENTION_MODULE_MAX; i++) {
for (int i = SLEEP_RETENTION_MODULE_MIN; i < SLEEP_RETENTION_MODULE_MAX; i++) {
bool inited = sleep_retention_is_module_inited(i);
bool created = sleep_retention_is_module_created(i);
bool is_top = is_top_domain_module(i);
@@ -624,8 +645,10 @@ static void entries_do_destroy(sleep_retention_module_t module)
memset(&next_entries, 0, sizeof(sleep_retention_entries_t));
_lock_acquire_recursive(&s_retention.lock);
s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32);
s_retention.created_modules.bitmap[module >> 5] &= ~BIT(module % 32);
if (module < SLEEP_RETENTION_MODULE_MAX) {
s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32);
s_retention.created_modules.bitmap[module >> 5] &= ~BIT(module % 32);
}
int index = module_runtime_attach(instance(module)) ? 1 : 0;
struct module_sleep_retention_context *ctx = &s_retention.context[index];
regdma_link_priority_t priority = 0;
@@ -647,7 +670,7 @@ static void entries_do_destroy(sleep_retention_module_t module)
static void entries_destroy(sleep_retention_module_t module)
{
assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX);
assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_INVALID);
_lock_acquire_recursive(&s_retention.lock);
if (!module_runtime_attach(instance(module))) {
retention_entries_join();
@@ -660,7 +683,7 @@ static void entries_destroy(sleep_retention_module_t module)
static void sleep_retention_entries_destroy(sleep_retention_module_t module)
{
assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX);
assert(SLEEP_RETENTION_MODULE_MIN <= module && module < SLEEP_RETENTION_MODULE_MAX);
_lock_acquire_recursive(&s_retention.lock);
entries_destroy(module);
uint32_t created_modules = 0;
@@ -819,7 +842,7 @@ esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t
if (priority >= SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES) {
return ESP_ERR_INVALID_ARG;
}
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = check_and_create_final_default();
@@ -857,7 +880,7 @@ sleep_retention_module_bitmap_t IRAM_ATTR sleep_retention_get_retained_modules(v
bool sleep_retention_is_module_inited(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return false;
}
_lock_acquire_recursive(&s_retention.lock);
@@ -868,7 +891,7 @@ bool sleep_retention_is_module_inited(sleep_retention_module_t module)
bool sleep_retention_is_module_created(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return false;
}
_lock_acquire_recursive(&s_retention.lock);
@@ -879,7 +902,7 @@ bool sleep_retention_is_module_created(sleep_retention_module_t module)
bool sleep_retention_is_module_attached(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return false;
}
_lock_acquire_recursive(&s_retention.lock);
@@ -924,25 +947,28 @@ bool IRAM_ATTR sleep_retention_module_bitmap_eq(sleep_retention_module_bitmap_t
static void module_action(sleep_retention_module_t module, sleep_retention_module_t dep_module, int action)
{
assert(module_is_inited(dep_module));
struct sleep_retention_module_object *dep = instance(dep_module);
assert(dep);
switch (action)
{
case 0: break; /* Nothing to do */
case 1: { /* allocate */
set_reference(instance(dep_module), module);
if (module_is_passive(instance(dep_module)) && module_runtime_attach(instance(dep_module))) {
set_reference(dep, module);
if (module_is_passive(dep) && module_runtime_attach(dep)) {
assert(module_runtime_attach(instance(module)));
}
}
break;
case 2: { /* free */
clr_reference(instance(dep_module), module);
if (module_is_passive(instance(dep_module)) && module_runtime_attach(instance(dep_module))) {
clr_reference(dep, module);
if (module_is_passive(dep) && module_runtime_attach(dep)) {
assert(module_runtime_attach(instance(module)));
}
}
break;
case 3: refarray_set_bit(instance(dep_module), 1, module); break; /* attach */
case 4: refarray_clr_bit(instance(dep_module), 1, module); break; /* detach */
case 3: refarray_set_bit(dep, 1, module); break; /* attach */
case 4: refarray_clr_bit(dep, 1, module); break; /* detach */
default: break;
}
}
@@ -961,7 +987,7 @@ static esp_err_t module_action_wrapper(sleep_retention_module_t module, int arg,
#define action(x) ((x) & 0xf)
module_action(module, dep_module, action(arg));
if ((arg & BIT(31)) || module_is_passive(instance(dep_module))) {
if ((arg & BIT(31)) || (module_is_inited(dep_module) && module_is_passive(instance(dep_module)))) {
err = (*rec)(dep_module);
}
}
@@ -972,7 +998,7 @@ static esp_err_t module_action_wrapper(sleep_retention_module_t module, int arg,
esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
if (param == NULL || param->cbs.create.handle == NULL) {
@@ -994,10 +1020,14 @@ esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_ret
if (module_is_created(module) || module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
sleep_retention_module_object_ctor(instance(module), &param->cbs);
set_dependencies(instance(module), param->depends);
set_attributes(instance(module), param->attribute);
s_retention.inited_modules.bitmap[module >> 5] |= BIT(module % 32);
err = instance_allocate(module);
if (err == ESP_OK) {
struct sleep_retention_module_object *mod = instance(module);
sleep_retention_module_object_ctor(mod, &param->cbs);
set_dependencies(mod, param->depends);
set_attributes(mod, param->attribute);
s_retention.inited_modules.bitmap[module >> 5] |= BIT(module % 32);
}
}
_lock_release_recursive(&s_retention.lock);
return err;
@@ -1005,7 +1035,7 @@ esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_ret
esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
@@ -1015,9 +1045,11 @@ esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module)
if (module_is_created(module) || !module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
clr_attributes(instance(module));
clr_dependencies(instance(module));
sleep_retention_module_object_dtor(instance(module));
struct sleep_retention_module_object *mod = instance(module);
clr_attributes(mod);
clr_dependencies(mod);
sleep_retention_module_object_dtor(mod);
instance_free(module);
s_retention.inited_modules.bitmap[module >> 5] &= ~BIT(module % 32);
uint32_t inited_modules = 0;
for (int i = 0; i < SLEEP_RETENTION_MODULE_BITMAP_SZ; i++) {
@@ -1036,18 +1068,19 @@ esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module)
static esp_err_t passive_module_allocate(sleep_retention_module_t module)
{
assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX);
assert(module >= SLEEP_RETENTION_MODULE_MIN && module < SLEEP_RETENTION_MODULE_MAX);
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
assert(module_is_passive(instance(module)) && "Illegal dependency");
assert(module_is_inited(module) && "All passive module must be inited first!");
struct sleep_retention_module_object *mod = instance(module);
assert(module_is_passive(mod) && "Illegal dependency");
if (!module_is_created(module)) {
err = module_action_wrapper(module, (BIT(31) | action(1)), passive_module_allocate);
if (err == ESP_OK) {
sleep_retention_callback_t fn = instance(module)->cbs.create.handle;
sleep_retention_callback_t fn = mod->cbs.create.handle;
if (fn) {
err = (*fn)(instance(module)->cbs.create.arg);
err = (*fn)(mod->cbs.create.arg);
}
}
}
@@ -1057,26 +1090,29 @@ static esp_err_t passive_module_allocate(sleep_retention_module_t module)
esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (!module_is_passive(instance(module))) {
if (module_is_inited(module) && !module_is_created(module)) {
if (!module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
struct sleep_retention_module_object *mod = instance(module);
if (module_is_passive(mod)) {
err = ESP_ERR_NOT_ALLOWED;
} else if (!module_is_created(module)) {
err = module_action_wrapper(module, action(1), passive_module_allocate);
if (err == ESP_OK) {
sleep_retention_callback_t fn = instance(module)->cbs.create.handle;
sleep_retention_callback_t fn = mod->cbs.create.handle;
if (fn) {
err = (*fn)(instance(module)->cbs.create.arg);
err = (*fn)(mod->cbs.create.arg);
}
}
} else {
err = ESP_ERR_INVALID_STATE;
}
} else {
err = ESP_ERR_NOT_ALLOWED;
}
_lock_release_recursive(&s_retention.lock);
return err;
@@ -1084,18 +1120,19 @@ esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module)
static esp_err_t passive_module_free(sleep_retention_module_t module)
{
assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX);
assert(module >= SLEEP_RETENTION_MODULE_MIN && module < SLEEP_RETENTION_MODULE_MAX);
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
assert(module_is_passive(instance(module)) && "Illegal dependency");
assert(module_is_inited(module) && "All passive module must be inited first!");
struct sleep_retention_module_object *mod = instance(module);
assert(module_is_passive(mod) && "Illegal dependency");
if (module_is_created(module)) {
if (!references_exist(instance(module))) {
if (!references_exist(mod)) {
if (!module_is_retained(module)) {
sleep_retention_entries_destroy(module);
if (instance(module)->cbs.destroy.handle) {
err = instance(module)->cbs.destroy.handle(instance(module)->cbs.destroy.arg);
if (mod->cbs.destroy.handle) {
err = mod->cbs.destroy.handle(mod->cbs.destroy.arg);
}
if (err == ESP_OK) {
err = module_action_wrapper(module, (BIT(31) | action(2)), passive_module_free);
@@ -1111,17 +1148,22 @@ static esp_err_t passive_module_free(sleep_retention_module_t module)
esp_err_t sleep_retention_module_free(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (!module_is_passive(instance(module))) {
if (module_is_inited(module) && module_is_created(module) && !module_is_retained(module)) {
if (!module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
struct sleep_retention_module_object *mod = instance(module);
if (module_is_passive(mod)) {
err = ESP_ERR_NOT_ALLOWED;
} else if (module_is_created(module) && !module_is_retained(module)) {
sleep_retention_entries_destroy(module);
if (instance(module)->cbs.destroy.handle) {
err = instance(module)->cbs.destroy.handle(instance(module)->cbs.destroy.arg);
if (mod->cbs.destroy.handle) {
err = mod->cbs.destroy.handle(mod->cbs.destroy.arg);
}
if (err == ESP_OK) {
err = module_action_wrapper(module, action(2), passive_module_free);
@@ -1129,8 +1171,6 @@ esp_err_t sleep_retention_module_free(sleep_retention_module_t module)
} else {
err = ESP_ERR_INVALID_STATE;
}
} else {
err = ESP_ERR_NOT_ALLOWED;
}
_lock_release_recursive(&s_retention.lock);
return err;
@@ -1161,14 +1201,15 @@ static void module_entries_move(sleep_retention_module_t module, struct module_s
static esp_err_t passive_module_attach(sleep_retention_module_t module)
{
assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX);
assert(module >= SLEEP_RETENTION_MODULE_MIN && module < SLEEP_RETENTION_MODULE_MAX);
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
assert(module_is_passive(instance(module)) && "Illegal dependency");
assert(module_runtime_attach(instance(module)) && "Illegal dependency");
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)) {
__attribute__((unused)) struct sleep_retention_module_object *mod = instance(module);
assert(module_is_passive(mod) && "Illegal dependency");
assert(module_runtime_attach(mod) && "Illegal dependency");
if (module_is_created(module) && !module_is_retained(module)) {
s_retention.attached_modules.bitmap[module >> 5] |= BIT(module % 32);
s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32);
module_entries_move(module, &s_retention.context[1], &s_retention.retention);
@@ -1180,15 +1221,20 @@ static esp_err_t passive_module_attach(sleep_retention_module_t module)
esp_err_t sleep_retention_module_attach(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (!module_is_passive(instance(module))) {
if (module_is_inited(module) && module_is_created(module) && !module_is_retained(module)) {
if (module_runtime_attach(instance(module))) {
if (!module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
struct sleep_retention_module_object *mod = instance(module);
if (module_is_passive(mod)) {
err = ESP_ERR_NOT_ALLOWED;
} else if (module_is_created(module) && !module_is_retained(module)) {
if (module_runtime_attach(mod)) {
s_retention.attached_modules.bitmap[module >> 5] |= BIT(module % 32);
s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32);
module_entries_move(module, &s_retention.context[1], &s_retention.retention);
@@ -1199,8 +1245,6 @@ esp_err_t sleep_retention_module_attach(sleep_retention_module_t module)
} else {
err = ESP_ERR_INVALID_STATE;
}
} else {
err = ESP_ERR_NOT_ALLOWED;
}
_lock_release_recursive(&s_retention.lock);
return err;
@@ -1208,15 +1252,16 @@ esp_err_t sleep_retention_module_attach(sleep_retention_module_t module)
static esp_err_t passive_module_detach(sleep_retention_module_t module)
{
assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX);
assert(module >= SLEEP_RETENTION_MODULE_MIN && module < SLEEP_RETENTION_MODULE_MAX);
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
assert(module_is_passive(instance(module)) && "Illegal dependency");
assert(module_runtime_attach(instance(module)) && "Illegal dependency");
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)) {
if (refarray_zero(instance(module), 1)) {
struct sleep_retention_module_object *mod = instance(module);
assert(module_is_passive(mod) && "Illegal dependency");
assert(module_runtime_attach(mod) && "Illegal dependency");
if (module_is_created(module) && module_is_retained(module)) {
if (refarray_zero(mod, 1)) {
s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32);
s_retention.attached_modules.bitmap[module >> 5] &= ~BIT(module % 32);
module_entries_move(module, &s_retention.retention, &s_retention.context[1]);
@@ -1229,15 +1274,20 @@ static esp_err_t passive_module_detach(sleep_retention_module_t module)
esp_err_t sleep_retention_module_detach(sleep_retention_module_t module)
{
if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) {
if (module < SLEEP_RETENTION_MODULE_MIN || module >= SLEEP_RETENTION_MODULE_MAX) {
return ESP_ERR_INVALID_ARG;
}
esp_err_t err = ESP_OK;
_lock_acquire_recursive(&s_retention.lock);
if (!module_is_passive(instance(module))) {
if (module_is_inited(module) && module_is_created(module) && module_is_retained(module)) {
if (module_runtime_attach(instance(module))) {
if (!module_is_inited(module)) {
err = ESP_ERR_INVALID_STATE;
} else {
struct sleep_retention_module_object *mod = instance(module);
if (module_is_passive(mod)) {
err = ESP_ERR_NOT_ALLOWED;
} else if (module_is_created(module) && module_is_retained(module)) {
if (module_runtime_attach(mod)) {
s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32);
s_retention.attached_modules.bitmap[module >> 5] &= ~BIT(module % 32);
module_entries_move(module, &s_retention.retention, &s_retention.context[1]);
@@ -1248,8 +1298,6 @@ esp_err_t sleep_retention_module_detach(sleep_retention_module_t module)
} else {
err = ESP_ERR_INVALID_STATE;
}
} else {
err = ESP_ERR_NOT_ALLOWED;
}
_lock_release_recursive(&s_retention.lock);
return err;