Undefined reference to xPortGetFreeHeapSize() for ATMega323 port


I wanted to use the xPortGetFreeHeapSize() function in the ATMega323 port, but it’s not defined:

undefined reference to `xPortGetFreeHeapSize'

Then I found this implementation for the ARMv8M port:

size_t xPortGetFreeHeapSize( void )
	return xFreeBytesRemaining;

It seems straightforward but, can I use it safely for the ATMega323 port? If so, in which file should I put it?

Thank you!

I got it! Unless your better opinion, of course.

I’m using heap_3.c as malloc implementation, and it doesn’t define such function, but heap_2.c does (and I think all others do as well, except heap_3.c).

I recall that I’m using heap_3.c because heap_2.c failed miserably, so the only option I had was heap_3.c.

A question has just poped out to my head: Does heap_3.c uses the value set on configTOTAL_HEAP_SIZE? Yesterday, making some experiments, I created 3 tasks, each one with a stack size of 256 words (512 bytes), in total 1536 bytes, but the heap size was set to 1500!

#define configTOTAL_HEAP_SIZE  (( UBaseType_t )( 1500 ))

It was strange and I decided to investigate the issue later. But now I’m realizing that this value isn’t used when heap_3.c implementation is chosen, the heap deep depends on the malloc()/free() compiler implementation.


I confirm that these implementations failed miserably in the ATMega328 port: heap_1.c, heap_2.c and heap_4.c.

heap_3 just puts a wrapper around whichever malloc() implementation your tools provide - hence we cannot say (in a portable way) how much heap is remaining. If your malloc() implementation provides an alternative then you can use that directly.

We would need to know what the issue was before we could suggest fixes. Might just be the size of the data types as this is an 8-bit device.

Hi @rtel,

With heap_3.c the programs run as expected. For example, a program that uses queues has this output, which is ok (the timestamp is part of the terminal):

Captura de pantalla de 2021-04-22 20-59-36

But with heap_2.c the output is this:

Captura de pantalla de 2021-04-22 21-02-46

That’s not a joke!

The part of the program that creates that uses dynamic memory is this:

void setup()
   pinMode( 13, OUTPUT );
   Serial.begin( 115200 );
   Serial.println( PROGRAM_NAME );

   if( xTaskCreate( producer_task, "PROD", 128 * 3, NULL, tskIDLE_PRIORITY + 1, NULL ) != pdPASS ){
      Serial.println( "ERROR CREATING TASK PROD" );

   if( xTaskCreate( consumer_task, "CONS", 128 * 3, NULL, tskIDLE_PRIORITY, NULL ) != pdPASS ){
      Serial.println( "ERROR CREATING TASK CONS" );

   g_queue_handler = xQueueCreate( QUEUE_ELEMS, QUEUE_TYPE_SIZE );

   if( g_queue_handler == NULL ){
      Serial.println( "ERROR CREATING THE QUEUE" );


Looking into the file portmacro.h for the ATMega323 port (8 bits) I noticed this:

/* Type definitions. */
#define portCHAR		char
#define portFLOAT		float
#define portDOUBLE		double
#define portLONG		long
#define portSHORT		int
#define portSTACK_TYPE	uint8_t //<-- Would be this the issue?
#define portBASE_TYPE	char

typedef portSTACK_TYPE  StackType_t;
typedef signed char     BaseType_t;
typedef unsigned char   UBaseType_t;

It seems to be a mistake, right? I’m not fan of dynamic memory, even worst in small microcontrollers, but it would be nice to investigate the issue.

This is an excerpt of the compilation command (the rest is about the files to be compiled):

avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR ...


I understand its not working, but would need to know why, which would require stepping through the code to see what is wrong. Looking at the other AVR demos in the FreeRTOS download I see all are using heap_1 other than this one, which is using heap_4.

To debug the ATmega328 on Linux is a pain in the neck, but as soon as I finished something I’m working on I’l try to debug it to find out what’s going on under the hood.

All heap_x.c schemas do compile, Do the examples work on real hardware?

I’ll report my results ASAP.

(EDIT: Typos)