Merge branch 'bugfix/exception_lomem_heap_init' into 'master'
heap_caps: Allow for possibility a region is too small to register a heap See merge request !1024
This commit is contained in:
commit
b9f660524c
3 changed files with 37 additions and 15 deletions
|
@ -68,6 +68,11 @@ inline static uint32_t get_all_caps(const heap_t *heap)
|
||||||
return all_caps;
|
return all_caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool heap_caps_match(const heap_t *heap, uint32_t caps)
|
||||||
|
{
|
||||||
|
return heap->heap != NULL && ((get_all_caps(heap) & caps) == caps);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Routine to allocate a bit of memory with certain capabilities. caps is a bitfield of MALLOC_CAP_* bits.
|
Routine to allocate a bit of memory with certain capabilities. caps is a bitfield of MALLOC_CAP_* bits.
|
||||||
*/
|
*/
|
||||||
|
@ -91,6 +96,9 @@ IRAM_ATTR void *heap_caps_malloc( size_t size, uint32_t caps )
|
||||||
//Iterate over heaps and check capabilities at this priority
|
//Iterate over heaps and check capabilities at this priority
|
||||||
for (int heap_idx = 0; heap_idx < num_registered_heaps; heap_idx++) {
|
for (int heap_idx = 0; heap_idx < num_registered_heaps; heap_idx++) {
|
||||||
heap_t *heap = ®istered_heaps[heap_idx];
|
heap_t *heap = ®istered_heaps[heap_idx];
|
||||||
|
if (heap->heap == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ((heap->caps[prio] & caps) != 0) {
|
if ((heap->caps[prio] & caps) != 0) {
|
||||||
//Heap has at least one of the caps requested. If caps has other bits set that this prio
|
//Heap has at least one of the caps requested. If caps has other bits set that this prio
|
||||||
//doesn't cover, see if they're available in other prios.
|
//doesn't cover, see if they're available in other prios.
|
||||||
|
@ -136,7 +144,7 @@ IRAM_ATTR static heap_t *find_containing_heap(void *ptr )
|
||||||
intptr_t p = (intptr_t)ptr;
|
intptr_t p = (intptr_t)ptr;
|
||||||
for (size_t i = 0; i < num_registered_heaps; i++) {
|
for (size_t i = 0; i < num_registered_heaps; i++) {
|
||||||
heap_t *heap = ®istered_heaps[i];
|
heap_t *heap = ®istered_heaps[i];
|
||||||
if (p >= heap->start && p < heap->end) {
|
if (heap->heap != NULL && p >= heap->start && p < heap->end) {
|
||||||
return heap;
|
return heap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +218,7 @@ size_t heap_caps_get_free_size( uint32_t caps )
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
for (int i = 0; i < num_registered_heaps; i++) {
|
for (int i = 0; i < num_registered_heaps; i++) {
|
||||||
heap_t *heap = ®istered_heaps[i];
|
heap_t *heap = ®istered_heaps[i];
|
||||||
if ((get_all_caps(heap) & caps) == caps) {
|
if (heap_caps_match(heap, caps)) {
|
||||||
ret += multi_heap_free_size(heap->heap);
|
ret += multi_heap_free_size(heap->heap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +230,7 @@ size_t heap_caps_get_minimum_free_size( uint32_t caps )
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
for (int i = 0; i < num_registered_heaps; i++) {
|
for (int i = 0; i < num_registered_heaps; i++) {
|
||||||
heap_t *heap = ®istered_heaps[i];
|
heap_t *heap = ®istered_heaps[i];
|
||||||
if ((get_all_caps(heap) & caps) == caps) {
|
if (heap_caps_match(heap, caps)) {
|
||||||
ret += multi_heap_minimum_free_size(heap->heap);
|
ret += multi_heap_minimum_free_size(heap->heap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,7 +250,7 @@ void heap_caps_get_info( multi_heap_info_t *info, uint32_t caps )
|
||||||
|
|
||||||
for (int i = 0; i < num_registered_heaps; i++) {
|
for (int i = 0; i < num_registered_heaps; i++) {
|
||||||
heap_t *heap = ®istered_heaps[i];
|
heap_t *heap = ®istered_heaps[i];
|
||||||
if ((get_all_caps(heap) & caps) == caps) {
|
if (heap_caps_match(heap, caps)) {
|
||||||
multi_heap_info_t hinfo;
|
multi_heap_info_t hinfo;
|
||||||
multi_heap_get_info(heap->heap, &hinfo);
|
multi_heap_get_info(heap->heap, &hinfo);
|
||||||
|
|
||||||
|
@ -264,7 +272,7 @@ void heap_caps_print_heap_info( uint32_t caps )
|
||||||
printf("Heap summary for capabilities 0x%08X:\n", caps);
|
printf("Heap summary for capabilities 0x%08X:\n", caps);
|
||||||
for (int i = 0; i < num_registered_heaps; i++) {
|
for (int i = 0; i < num_registered_heaps; i++) {
|
||||||
heap_t *heap = ®istered_heaps[i];
|
heap_t *heap = ®istered_heaps[i];
|
||||||
if ((get_all_caps(heap) & caps) == caps) {
|
if (heap_caps_match(heap, caps)) {
|
||||||
multi_heap_get_info(heap->heap, &info);
|
multi_heap_get_info(heap->heap, &info);
|
||||||
|
|
||||||
printf(" At 0x%08x len %d free %d allocated %d min_free %d\n",
|
printf(" At 0x%08x len %d free %d allocated %d min_free %d\n",
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include <multi_heap.h>
|
#include <multi_heap.h>
|
||||||
|
#include <esp_heap_caps.h>
|
||||||
#include <soc/soc_memory_layout.h>
|
#include <soc/soc_memory_layout.h>
|
||||||
|
|
||||||
static const char *TAG = "heap_init";
|
static const char *TAG = "heap_init";
|
||||||
|
@ -26,8 +27,9 @@ size_t num_registered_heaps;
|
||||||
static void register_heap(heap_t *region)
|
static void register_heap(heap_t *region)
|
||||||
{
|
{
|
||||||
region->heap = multi_heap_register((void *)region->start, region->end - region->start);
|
region->heap = multi_heap_register((void *)region->start, region->end - region->start);
|
||||||
|
if (region->heap != NULL) {
|
||||||
ESP_EARLY_LOGD(TAG, "New heap initialised at %p", region->heap);
|
ESP_EARLY_LOGD(TAG, "New heap initialised at %p", region->heap);
|
||||||
assert(region->heap);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void heap_caps_enable_nonos_stack_heaps()
|
void heap_caps_enable_nonos_stack_heaps()
|
||||||
|
@ -38,10 +40,12 @@ void heap_caps_enable_nonos_stack_heaps()
|
||||||
heap_t *heap = ®istered_heaps[i];
|
heap_t *heap = ®istered_heaps[i];
|
||||||
if (heap->heap == NULL) {
|
if (heap->heap == NULL) {
|
||||||
register_heap(heap);
|
register_heap(heap);
|
||||||
|
if (heap->heap != NULL) {
|
||||||
multi_heap_set_lock(heap->heap, &heap->heap_mux);
|
multi_heap_set_lock(heap->heap, &heap->heap_mux);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Modify regions array to disable the given range of memory.
|
//Modify regions array to disable the given range of memory.
|
||||||
static void disable_mem_region(soc_memory_region_t *regions, intptr_t from, intptr_t to)
|
static void disable_mem_region(soc_memory_region_t *regions, intptr_t from, intptr_t to)
|
||||||
|
@ -132,7 +136,6 @@ void heap_caps_init()
|
||||||
|
|
||||||
Once we have a heap to copy it to, we will copy it to a heap buffer.
|
Once we have a heap to copy it to, we will copy it to a heap buffer.
|
||||||
*/
|
*/
|
||||||
multi_heap_handle_t first_heap = NULL;
|
|
||||||
heap_t temp_heaps[num_registered_heaps];
|
heap_t temp_heaps[num_registered_heaps];
|
||||||
size_t heap_idx = 0;
|
size_t heap_idx = 0;
|
||||||
|
|
||||||
|
@ -161,15 +164,24 @@ void heap_caps_init()
|
||||||
heap->heap = NULL;
|
heap->heap = NULL;
|
||||||
} else {
|
} else {
|
||||||
register_heap(heap);
|
register_heap(heap);
|
||||||
if (first_heap == NULL) {
|
|
||||||
first_heap = heap->heap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the permanent heap data that we'll use for runtime */
|
|
||||||
assert(heap_idx == num_registered_heaps);
|
assert(heap_idx == num_registered_heaps);
|
||||||
registered_heaps = multi_heap_malloc(first_heap, sizeof(heap_t) * num_registered_heaps);
|
|
||||||
|
/* Allocate the permanent heap data that we'll use for runtime */
|
||||||
|
registered_heaps = NULL;
|
||||||
|
for (int i = 0; i < num_registered_heaps; i++) {
|
||||||
|
if (heap_caps_match(&temp_heaps[i], MALLOC_CAP_8BIT)) {
|
||||||
|
/* use the first DRAM heap which can fit the data */
|
||||||
|
registered_heaps = multi_heap_malloc(temp_heaps[i].heap, sizeof(heap_t) * num_registered_heaps);
|
||||||
|
if (registered_heaps != NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(registered_heaps != NULL); /* if NULL, there's not enough free startup heap space */
|
||||||
|
|
||||||
memcpy(registered_heaps, temp_heaps, sizeof(heap_t)*num_registered_heaps);
|
memcpy(registered_heaps, temp_heaps, sizeof(heap_t)*num_registered_heaps);
|
||||||
|
|
||||||
/* Now the heap_mux fields live on the heap, assign them */
|
/* Now the heap_mux fields live on the heap, assign them */
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
/* Type for describing each registered heap */
|
/* Type for describing each registered heap */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t type;
|
size_t type;
|
||||||
uint32_t caps[SOC_MEMORY_TYPE_NO_PRIOS]; ///< Capabilities for the type of memory in this healp (as a prioritised set). Copied from soc_memory_types so it's in RAM not flash.
|
uint32_t caps[SOC_MEMORY_TYPE_NO_PRIOS]; ///< Capabilities for the type of memory in this heap (as a prioritised set). Copied from soc_memory_types so it's in RAM not flash.
|
||||||
intptr_t start;
|
intptr_t start;
|
||||||
intptr_t end;
|
intptr_t end;
|
||||||
portMUX_TYPE heap_mux;
|
portMUX_TYPE heap_mux;
|
||||||
|
@ -36,3 +36,5 @@ typedef struct {
|
||||||
extern heap_t *registered_heaps;
|
extern heap_t *registered_heaps;
|
||||||
extern size_t num_registered_heaps;
|
extern size_t num_registered_heaps;
|
||||||
|
|
||||||
|
bool heap_caps_match(const heap_t *heap, uint32_t caps);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue