mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
feat(esp_hw_support): use dynamic memory allocation for retention module instances
This commit is contained in:
@@ -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), ¶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;
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user