Bug? Static timers call vPortFree()!

While creating a static timer (and all the dynamic support being dropped out), I found that the kernel calls the vPortFree() function, and as it doesn’t exist, then the program doesn’t compile.

   StaticTimer_t timer1_tcb;
   TimerHandle_t timer1_handler;

   timer1_handler =
   xTimerCreateStatic(
         ( const portCHAR* ) "TMR1",
         pdMS_TO_TICKS( 10 ),
         pdTRUE,
         ( void* ) 0,
         timer1,
         &timer1_tcb );

In the Makefile I have:

#define configSUPPORT_STATIC_ALLOCATION     1
//#define configSUPPORT_DYNAMIC_ALLOCATION    0
//#define configTOTAL_HEAP_SIZE               (( UBaseType_t )( 1500 ))

A stripped output is:

build-uno/libcore.a(timers.c.o): In function prvTimerTask': timers.c:(.text.prvTimerTask+0x202): undefined reference to vPortFree’
collect2: error: ld returned 1 exit status

Tracing back into the function xTimerCreateStatic() (in the file timers.c) I guess some copy and paste is the guilty one:

#if( configSUPPORT_STATIC_ALLOCATION == 1 )

	TimerHandle_t xTimerCreateStatic(	const char * const pcTimerName,		/*lint !e971 Unqualified char types are allowed for strings and single characters only. */
										const TickType_t xTimerPeriodInTicks,
										const UBaseType_t uxAutoReload,
										void * const pvTimerID,
										TimerCallbackFunction_t pxCallbackFunction,
										StaticTimer_t *pxTimerBuffer )
	{
	Timer_t *pxNewTimer;

		#if( configASSERT_DEFINED == 1 )
		{
			/* Sanity check that the size of the structure used to declare a
			variable of type StaticTimer_t equals the size of the real timer
			structure. */
			volatile size_t xSize = sizeof( StaticTimer_t );
			configASSERT( xSize == sizeof( Timer_t ) );
		}
		#endif /* configASSERT_DEFINED */

		/* A pointer to a StaticTimer_t structure MUST be provided, use it. */
		configASSERT( pxTimerBuffer );
		pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */

		if( pxNewTimer != NULL )
		{
			prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );


                #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )  //<== I GUESS THIS IS THE TROUBLE-MAKER ===
     			{
     				/* Timers can be created statically or dynamically so note this
	         			timer was created statically in case it is later deleted. */
		        		pxNewTimer->ucStaticallyAllocated = pdTRUE;
			    }
                #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
		}

		return pxNewTimer;
	}

#endif /* configSUPPORT_STATIC_ALLOCATION */

I haven’t tried to correct the code from

#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )

to

#if( configSUPPORT_STATIC_ALLOCATION == 1 )

because I don’t want to break things (I like to break things, but not now). Let the creator to give us green light.

Any advice, good or bad?

The code you posted from xTimerCreateStatic() seems correct as is. The “correction” you propose doesn’t seem right.

In the case where both configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION are ‘1’, the code makes a note that this particular timer was created statically. This seems to make sense as is.

If these are the contents of FreeRTOSConfig.h, then you should end up with both static and dynamic allocation. Note the following defaults in FreeRTOS.h:

#ifndef configSUPPORT_DYNAMIC_ALLOCATION
	/* Defaults to 1 for backward compatibility. */
	#define configSUPPORT_DYNAMIC_ALLOCATION 1
#endif

Does your build failure change behavior if you define configSUPPORT_DYNAMIC_ALLOCATION to 1 yourself? In other words, did commenting out that line change the build results for you?

As Jeff said, not defining configSUPPORT_DYNAMIC_ALLOCATION means that it is assumed to be 1, and thus allowed. If you want to disable dynamic allocations, you must define
configSUPPORT_DYNAMIC_ALLOCATION as 0, and then you can no include a heap function. With it undefined, and thus defaulted to 1, the various create functions will add a flag (like you added the comment to) to mark if it was dynamically or statically created, and the delete functions will check that flag and if cleared (indicating dynamic) will call free.

I was brave enough to make the change from

#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )

to

#if( configSUPPORT_STATIC_ALLOCATION == 1 )

But it didn’t resolve the problem.

It seems that somewhere deep in the code is changing the field pxNewTimer->ucStaticallyAllocated from pdTRUE to pdFALSE, that’s way

SOLVED.

You’re completely right. I’m ashame of myself :grinning: Instead of

//#define configSUPPORT_DYNAMIC_ALLOCATION 1

this next sentence works as expected:

#define configSUPPORT_DYNAMIC_ALLOCATION 0

Changing what I proposed didn’t solve the problem, because configSUPPORT_DYNAMIC_ALLOCATION was still defined somewhere inside the code as you’ve pointed it out.

BTW: The timer software functionality uses a lot of code =)

When configSUPPORT_DYNAMIC_ALLOCATION is set to 0, you need to remove (or change the name, as I do) to the file heap_X.c. Otherwise the project won’t compile:

53:3: error: #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
  #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0

with both:

#define configSUPPORT_STATIC_ALLOCATION     1
//#define configSUPPORT_DYNAMIC_ALLOCATION    0
//#define configTOTAL_HEAP_SIZE               (( UBaseType_t )( 1500 ))

or

#define configSUPPORT_STATIC_ALLOCATION     1
#define configSUPPORT_DYNAMIC_ALLOCATION    0
//#define configTOTAL_HEAP_SIZE               (( UBaseType_t )( 1500 ))

The hints from Jeff made my project to compile. Thank you both!

:grinning:

You just need to not include it in the project.

I know it. But as I’m working with both kind of projects, static and dynamic, I cannot (I don’t want) to remove it. That’s way I just change its name.

And it gets worst: Because of my lack of expertise in makefiles, the FreeRTOSConfig.h file is shared among all my projects. So whenever I comeback to a project I need to check it.

FreeRTOSConfig.h should be in the directory of your projects local files, so not part of the FreeRTOS library code, that way each project gets its own version of the file, since it really does need to be adjusted to the application.

You don’t need to physically remove the file, just remove it from the list of files that are to be processed by the project.

In toolchains (Eclipse based) other than the one to program the ATmega328 do allow me to place the FreeRTOSConfig.h file at the current project location (as it should be). They also allow me to drop out the heap_x.c file so it’s not be considered in the compilation process, so I don’t need to remove it nor change it its name.

However, the toolchain I’m using to program the ATmega328 doesn’t allow me (or it’s extremely difficult) to place the FreeRTOSConfig.h where it should be.

For the record, I’m programming Arduino from the command line using the Arduino-Makefile project file. I’ve created a project called Molcajete that integrates Arduino, Arduino-Makefile and FreeRTOS. I’ve hacked some files so FreeRTOS works along Arduino, but I’m attached to a Makefile I didn’t create (and I don’t understand).

To put the FreeRTOSConfig.h in the project directory just requires you to go into the settings and add that directory to the include directory list. With a makefile, there should be a macro somewhere in the project definitions that lists the include directory to use, just as there is normally a listing of what files to include in the project.