Get error when runing simple demos

when i run freeRtos, with 3 tasks, all are simple led on-off demos,
while i got this error:


and the leds does not work.

any ideas how to solve this problem?

with kind regards,

You really should add some more information like FreeRTOS version, MCU type / FreeRTOS port used, some more details about the error.
What is throwing the error ? Your configASSERT macro implementation ?
Which error is it exactly / what’s at the line of the task.c file you’re using ? You shouldn’t expect that others try to find and lookup the code of an unknown version of task.c because you didn’t take the time to just provide the information :wink:
And last but not least the code (snippets) creating the tasks with parameters and the task code itself would be helpful.
Otherwise it’s almost impossible to tell something helpful about it.

sorry for that. it was in a hurry for other issues.
there are some details:
Freertos: v9.0.0
MCU: stm32f1
IDE: keil5
Analyzer: percepio tracealyzer
Aim: freertos runs for sometime then stops, for instance, i build 3 tasks, all are running smoothly, then around 5 or longer time, they stop working. so I use percepio to trace the issue in snapshot mode.

After porting the percepio tracealyzer files in, and built…all the tasks then have no any further response…and checked the serial print: it only shows Error:…\FreeRTOS\tasks.c,2807 when i restart stm32 board.

this is the error location 2807 lines, tasks.c


when get into this func:

#define taskSELECT_HIGHEST_PRIORITY_TASK()														
UBaseType_t uxTopPriority;																		
portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority );  	
//error assert gets from here
configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 );
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );

configASSERT func details are:

//micro implemetation
#define vAssertCalled(char,int)  printf("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0)vAssertCalled(__FILE__,__LINE__)

below is the main func, with priority:

#define START_TASK_PRIO		1 
#define START_STK_SIZE 		158  
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);

#define TASK1_TASK_PRIO		2
#define TASK1_STK_SIZE 		130
TaskHandle_t TTCANTask_Handler;
void TTCAN_task(void *pvParameters);

#define TASK2_TASK_PRIO		3
#define TASK2_STK_SIZE 		10  
TaskHandle_t Task2Task_Handler;
void Other_task(void *pvParameters);

#define TASK3_TASK_PRIO		4
#define TASK3_STK_SIZE 		10
TaskHandle_t Task3Task_Handler;
//char bufferinfo[1000];
void Other_task1(void *pvParameters);

in FreeRTOSConfig.h

#define configTOTAL_HEAP_SIZE    ((size_t)(10*1024))   

Debugging will be a lot easier with a newer FreeRTOS version (V9 is from 2016) as newer versions include more asserts() that catch misconfigurations.

The most likely cause of the assert is data corruption - and the most likely cause of data corruption is stack overflow. START_STK_SIZE and TASK1_STK_SIZE may be large enough, depending on what the task is doing. TASK2_STK_SIZE and TASK3_STK_SIZE are definitely too small, as an empty task (one that does nothing) uses 80 words of stack and you only allocated 10. This page tells you how to check for stack overflows:

thanks, while for task2 and task3 they are only for testing, so I make it very small, they still work. i also think it can be the overflow and then make freertos stops working after sometime.

one doubt, start_stk_size is the task that contains the rest of tasks, like this:

#define START_TASK_PRIO		1 
#define START_STK_SIZE 		158   
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);

and main func.

 xTaskCreate((TaskFunction_t )start_task,    
                (const char*    )"start_task",  
                (uint16_t       )START_STK_SIZE, 
                (void*          )NULL,                 
                (UBaseType_t    )START_TASK_PRIO,      
                (TaskHandle_t*  )&StartTask_Handler);   

and the start_task func contains other tasks:

void start_task(void *pvParameters)
    xTaskCreate((TaskFunction_t )Other_task,     
                (const char*    )"Led_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
   xTaskCreate((TaskFunction_t )Other_task1,     
                (const char*    )"beep_task",   
                (uint16_t       )TASK3_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK3_TASK_PRIO,
                (TaskHandle_t*  )&Task3Task_Handler); 

so the start task stack size should be larger than the stack size of led_task + beep_task ? or there is no need to be larger?

The stack size is per task and each task gets its dedicated stack allocated/assigned.
Even though your task2/3 SEEM to work there is surely a stack overflow corrupting memory because the stack size is simply too small as @rtel mentioned.
Corrupted memory might cause undefined behavior. Anything can happen.
I’d strongly recommend to follow Richard’s advise including enabling stack checking.
You know, he created FreeRTOS and knows what he’s talking about :wink:

I will increase stack size for all the tasks, and check the left stack by some apis.

I did the test by calling the API function which mentioned by @rtel : uxTaskGetStackHighWaterMark(handler)

for a simple task, only on-off the led with a rough 1s delay:

void Task2(void *pvParameters)
  UBaseType_t StackUsageMinSize;
  StackUsageMinSize = uxTaskGetStackHighWaterMark( Task2Task_Handler );
      LEDB5 = !LEDB5;
      printf("stack 2 min size is: %d\r\n",StackUsageMinSize  );

with the allocation size:

#define TASK2_TASK_PRIO		3
#define TASK2_STK_SIZE 		320
TaskHandle_t Task2Task_Handler;
void  Task2(void *pvParameters);

then the serial result is this:

stack 1 min size is: 20
stack 2 min size is: 304
stack 3 min size is: 504

The given stack size is 320, while the left min size is 304, then the task2 only need 320 - 304= 16 words = 16 * 4 = 64 bytes.
so my question is: can I simply allocate 20 words for task2 or just little bit larger like 40 ?

as you mentioned:

it means for a empty task should allocate 80 words, then for this led on-off
task which stack value would be suitable? when using the reference from uxTaskGetStackHighWaterMark(), seems some stack size larger than 16 would be fine. for example 20, 30 or 40. or I have to give a value like 80+ ?

Note the stack size is defined in words, not bytes. 80 is the minimum recommended. The whole of the task’s context is saved on the stack’s stack when its not running. printf() can use a huge amount of stack, depending on the C library you use.

I’d query uxTaskGetStackHighWaterMark not on task function entry but after all relevant code was called. In your case after printf resp. vTaskDelay.
BTW a common value for the configMINIMAL_STACK_SIZE is 128.
See the Customisation documentation for some more details.

so the 80 words = 320 bytes.
so better always at least give 80 words for the task.
for uxTaskGetStackHighWaterMark( Task2Task_Handler ); and printf() is only for test, I will comment out this after get the minal left stack size.

yes, make sense. use the common value as a reference is also a benchmark.