feat(esp_hw_support): use dynamic memory allocation for retention module instances

This commit is contained in:
wuzhenghui
2026-08-25 21:11:05 +08:00
parent 3c2a0cb4f6
commit a9dee592d6

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;
}
@@ -258,7 +259,7 @@ typedef struct {
void *final_default;
struct sleep_retention_module_object instance[SLEEP_RETENTION_MODULE_MAX];
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)
@@ -926,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;
}
}
@@ -963,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);
}
}
@@ -996,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;
@@ -1017,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++) {
@@ -1042,14 +1072,15 @@ static esp_err_t passive_module_allocate(sleep_retention_module_t module)
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);
}
}
}
@@ -1065,20 +1096,23 @@ esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module)
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;
@@ -1090,14 +1124,15 @@ static esp_err_t passive_module_free(sleep_retention_module_t module)
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);
@@ -1119,11 +1154,16 @@ esp_err_t sleep_retention_module_free(sleep_retention_module_t module)
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);
@@ -1131,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;
@@ -1167,10 +1205,11 @@ static esp_err_t passive_module_attach(sleep_retention_module_t module)
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);
@@ -1188,9 +1227,14 @@ esp_err_t sleep_retention_module_attach(sleep_retention_module_t module)
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);
@@ -1201,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;
@@ -1214,11 +1256,12 @@ static esp_err_t passive_module_detach(sleep_retention_module_t module)
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]);
@@ -1237,9 +1280,14 @@ esp_err_t sleep_retention_module_detach(sleep_retention_module_t module)
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]);
@@ -1250,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;