STM32F103 Freertos update to 7.5.2

tabulous2011 wrote on Tuesday, September 10, 2013:

Hi All,
just move up from 7.1.1 to 7.5.2, everything ran fine on 7.1.1 (Using Atollic GCC and STM Libs). All I’ve done is copy and replace all the new files in, ive kept the FreeRTOSConfig.h the same and per 7.1.1

Now if got two issues

1). getting configASSERT in vPortFree, this seems to be new ??? i have INCLUDE_vTaskDelete set to 1 in the config file, as i was using vTaskDelete to delete a startup task. Heap1.c is been used for memory. I can stop this by not calling vTaskDelete.

2) Issue is hardfault after call to prvPortStartFirstTask,

rtel wrote on Tuesday, September 10, 2013:

Heap1.c does not implement vPortFree() so the assert is most likely highlighting an error in your code that has always been there.  Please refer to http://www.freertos.org/a00111.html

I suspect previously you were deleting the task, but the memory used by the task’s stack and TCB were never actually being freed.

The simplest memory allocation file that includes a free function is heap_2.  If you are doing a lot of freeing (which I don’t think you are) then use heap_4.c as it prevents memory fragmentation as much as is possible.

Regards.

tabulous2011 wrote on Tuesday, September 10, 2013:

What i dont understand is 7.1.1 works fine, basically the update to 7.5.2 breaks the system, surely this cant be right ?

I dont used any malloc / free functions the only memory management is that of freertos, and thus as i was using heap1.c before and had now issues, i could use the same.

rtel wrote on Tuesday, September 10, 2013:

What i dont understand is 7.1.1 works fine

heap_1.c has never included a free function, as I said:

I suspect previously you were deleting the task, but the memory used by the task’s stack and TCB were never actually being freed.

The only difference now is the addition of a configASSERT() that lets you know you are calling a function that is not implemented.

Your last post says…

I dont used any malloc / free functions

…but your first post says

I can stop this by not calling vTaskDelete.

So if you read the page I linked to in my last post you will see that by calling vTaskDelete() you are indeed calling a free function.  The addition of the configASSERT() has not introduced a problem, but highlighted a problem that has always existed, albeit with no ill effect in your particular application.

Regards.

tabulous2011 wrote on Wednesday, September 11, 2013:

so i’ve removed the vTaskDelete call, and also set INCLUDE_vTaskDelete 0.

Now all i get is hardfault, all pointing to vGenericQueueSend

The wired thing is, if i build my application based on 7.1.1 everything runs fine no issues. Soon as i build with 7.5.2 boom broken, handfault. Also noted the the size difference in the compiled output is 6K bigger using 7.5.2.

Here is my config file

#define GCC_ARMCM3
#include “stm32f10x.h”

#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 256 )//512 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configGENERATE_RUN_TIME_STATS 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 0

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 3 )
#define configTIMER_QUEUE_LENGTH 5
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1

/* Use the system definition, if there is one */
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS       __NVIC_PRIO_BITS
#else
#define configPRIO_BITS       4        /* 15 priority levels */
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

/* The lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Priority 5, or 95 as only the top four bits are implemented. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

All interrupts are set as follows

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - X;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

Where X is a number normally from 0 - 5

edwards3 wrote on Wednesday, September 11, 2013:

The extra code probably comes from extra assert() statements which will only be there when configASSERT() is defined. I think any additional features in newer versions will default to be turned off. And if you are stripping dead code from your binaries new API functions would not make a difference.

configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY - X

You have configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY set to 5 so interrupts using FreeRTOS (ISR safe) calls can use priority 5 and lower priorities. Remember ARM does interrupt priorities backwards, so a priority of 6 is lower than 5 and a priority of 4 is higher than five. Your interrupts should be set to priorities configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + X, where X can be 0 to 10 in this case, giving your priorities of 5 to 15 inc.

FreeRTOS V7.5.2 includes extra code that should trigger an assert in the interrupt if you have this wrong though.