Setting Heap Management Scheme

Dutch66
Posts: 4
Joined: Mon May 03, 2021 4:46 pm

Setting Heap Management Scheme

Postby Dutch66 » Mon May 03, 2021 5:04 pm

Hello everybody,
I am new here so please forgive me if the answer to my question is really obvious. For me it is not :(

In a thread I allocate memory either with

Code: Select all

ptr = (char *)pvPortMalloc((digitc+1)*sizeof(char));
or with

Code: Select all

ptr = (char *)malloc(digitc*sizeof(char));
. This works OK and when I check the size of the heap it shows exactly what I expect.

But when I try to deallocate the memory with

Code: Select all

vPortFree(ptr);
or with

Code: Select all

free(ptr);
the problems begin. I get CORRUPT HEAP: multi_heap.c:172 detected at 0x3ffb6ddc and the program reboots.

The free rtos documentation mentions that one of heap_1.c, heap_2.c, heap_3.c, heap_4.c and heap_5.c must be included in the code and that heap_1.c does not allow to free the memory. Therefore I assume that I am using heap_1.c, but I don't know where to find the reference to this in my project.

Could someone be so nice and point me to the location of this file reference in the build process. Or in case someone knows a different reason for free to fail please let me know.

Thanks

rfleming
Posts: 62
Joined: Tue Oct 09, 2018 12:30 am

Re: Setting Heap Management Scheme

Postby rfleming » Tue May 04, 2021 12:25 am

This has only happened to me when ptr == NULL OR if the memory had already been freed as there is no checks inside free() on the memory you're trying to deallocate.

I use malloc heaps, personally havn't touched pvPortMalloc().

Dutch66
Posts: 4
Joined: Mon May 03, 2021 4:46 pm

Re: Setting Heap Management Scheme

Postby Dutch66 » Tue May 04, 2021 2:26 pm

Thanks for your help!
Unfortunately that is not the cause as the complete code line is:

Code: Select all

if(ptr != NULL)vPortFree(ptr);
. Changing to free(ptr) does not make a difference. I still try to find where the rtos heap_x.c files are included.

This is from the free rtos web sitehttps://www.freertos.org/a00111.html
heap_1 - the very simplest, does not permit memory to be freed.
heap_2 - permits memory to be freed, but does not coalescence adjacent free blocks.
heap_3 - simply wraps the standard malloc() and free() for thread safety.
heap_4 - coalescences adjacent free blocks to avoid fragmentation. Includes absolute address placement option.
heap_5 - as per heap_4, with the ability to span the heap across multiple non-adjacent memory areas.
I can't find that information in the ESP docs. I will do a very basic test program just allocating and deallocating memory and report my code and results here.

Thanks again.

Dutch66
Posts: 4
Joined: Mon May 03, 2021 4:46 pm

Re: Setting Heap Management Scheme

Postby Dutch66 » Tue May 04, 2021 4:28 pm

I still don't know what causes my problem in the original program but the following program works as expected although I don't even bother to check whether the pointer exists ( I kind of do with the allocation flag).
I compile this in the same way as my original program that causes problems. So, I conclude that it must be some bug in my program and not an issue with the Heap Management Scheme.

Thanks for the help!

Code: Select all

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <string.h>

static char *ptr = NULL;
static uint8_t allocation_flag = 0;

void mem_allocation_test(void *param){
	/*
	 *
	 */
	char buffer[78];

	while(1){
		// Create some useless data
		for(uint8_t index = 0; index <78;index++){
			buffer[index] = (char)index+48;	// Fill buffer with printable ASCII signals
		}
		// Allocate memory in heap and set allocation flag
		ptr = (char *)pvPortMalloc((100)*sizeof(char));
		printf("Free heap size after allocating buffer: %i\n",xPortGetFreeHeapSize());
		allocation_flag = 1;
		// Fill the memory
		memcpy(ptr, buffer, 78);
		// Wait a second
		vTaskDelay(1000/portTICK_PERIOD_MS);
	}
}

void mem_deallocation_test(void *param){
	while(1){
		if(allocation_flag == 1){
			printf("%s\n",ptr);
			vPortFree(ptr);
			printf("Free heap size after deallocating buffer: %i\n",xPortGetFreeHeapSize());
			allocation_flag = 0;
			vTaskDelay(200/portTICK_PERIOD_MS);
		}
	}
}

	void app_main(void){
		xTaskCreatePinnedToCore(
					mem_allocation_test,
					"Alloc Test",
					4000,
					NULL,
					1,
					NULL,
					1);

		xTaskCreatePinnedToCore(
					mem_deallocation_test,
					"Free Test",
					4000,
					NULL,
					1,
					NULL,
					1);
	}


ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Setting Heap Management Scheme

Postby ESP_Angus » Tue May 04, 2021 11:35 pm

Hi Dutch66,

ESP-IDF doesn't use any of the FreeRTOS heap implementations, we use a different one (before ESP-IDF v4.3 it's a custom one called "multi_heap", since ESP-IDF v4.3 it's a new one based on the TLSF algorithm.)

vPortMalloc() & vPortFree() are #defined to malloc() & free() in freertos portable.h so they should be compiling to the same code in ESP-IDF.

Heap corruption will definitely happen if you double-free a pointer (i.e. call free on the same pointer more than once.)

free(NULL) is valid C and it's safe to call it (it does nothing.)

For this reason you could change your sample code from having an "allocation_flag" to setting "ptr = NULL" immediately after freeing it, save a variable.

In your original code which is crashing, suggest checking very carefully that free() is only called on the exact result of a malloc() call and never called more than once on the same allocation. Also check that none of the code is overflowing a buffer (allocating X bytes but then writing >X bytes), writing to a pointer after it has been freed, etc.

There are various ways to do this, but ESP-IDF has some heap checking tools and a heap tracing feature which may be useful.

Dutch66
Posts: 4
Joined: Mon May 03, 2021 4:46 pm

Re: Setting Heap Management Scheme

Postby Dutch66 » Wed May 05, 2021 10:19 pm

Hi ESP_Angus,
thanks for your reply. Good to know that ESP is not using the heap definitions of free rtos. I got everything working now.

Who is online

Users browsing this forum: No registered users and 124 guests