mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat(esp_hw_support): use dynamic memory allocation for retention module instances
This commit is contained in:
@@ -163,6 +163,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;
|
||||
}
|
||||
|
||||
@@ -250,7 +251,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;
|
||||
@@ -271,7 +272,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)
|
||||
@@ -908,25 +929,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;
|
||||
}
|
||||
}
|
||||
@@ -945,7 +969,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);
|
||||
}
|
||||
}
|
||||
@@ -978,10 +1002,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), ¶m->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, ¶m->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;
|
||||
@@ -999,9 +1027,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++) {
|
||||
@@ -1024,14 +1054,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1047,20 +1078,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;
|
||||
@@ -1072,10 +1106,11 @@ 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);
|
||||
err = module_action_wrapper(module, (BIT(31) | action(2)), passive_module_free);
|
||||
@@ -1096,15 +1131,18 @@ 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);
|
||||
err = module_action_wrapper(module, action(2), passive_module_free);
|
||||
} else {
|
||||
err = ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
} else {
|
||||
err = ESP_ERR_NOT_ALLOWED;
|
||||
}
|
||||
_lock_release_recursive(&s_retention.lock);
|
||||
return err;
|
||||
@@ -1139,10 +1177,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)) {
|
||||
module_entries_move(module, &s_retention.context[1], &s_retention.retention);
|
||||
s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32);
|
||||
err = module_action_wrapper(module, (BIT(31) | action(3)), passive_module_attach);
|
||||
@@ -1159,9 +1198,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)) {
|
||||
module_entries_move(module, &s_retention.context[1], &s_retention.retention);
|
||||
s_retention.retention_modules.bitmap[module >> 5] |= BIT(module % 32);
|
||||
err = module_action_wrapper(module, action(3), passive_module_attach);
|
||||
@@ -1171,8 +1215,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;
|
||||
@@ -1184,11 +1226,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)) {
|
||||
module_entries_move(module, &s_retention.retention, &s_retention.context[1]);
|
||||
s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32);
|
||||
err = module_action_wrapper(module, (BIT(31) | action(4)), passive_module_detach);
|
||||
@@ -1206,9 +1249,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)) {
|
||||
module_entries_move(module, &s_retention.retention, &s_retention.context[1]);
|
||||
s_retention.retention_modules.bitmap[module >> 5] &= ~BIT(module % 32);
|
||||
err = module_action_wrapper(module, action(4), passive_module_detach);
|
||||
@@ -1218,8 +1266,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;
|
||||
|
||||
Reference in New Issue
Block a user