FreeRTOS transport

Hello, I am a new hand at FreeRTOS.When I tried to transport FreeRTOS to sifive learn inventor,I encountered some problems.Program always stucks at function prvCheckTasksWaitingTermination.Can anyone helps me?

#include <stdio.h>
#include <string.h>
#include <unistd.h>

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

/* Priorities used by the tasks. */


/* The rate at which data is sent to the queue.  The 200ms value is converted
to ticks using the pdMS_TO_TICKS() macro. */


/* The maximum number items the queue can hold.  The priority of the receiving
task is above the priority of the sending task, so the receiving task will
preempt the sending task and remove the queue items each time the sending task
writes to the queue.  Therefore the queue will never have more than one item in
it at any time, and even with a queue length of 1, the sending task will never
find the queue full. */


/*-----------------------------------------------------------*/

/*
 * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in
 * main.c.
 */
void main_blinky( void );

/*
 * The tasks as described in the comments at the top of this file.
 */


/*-----------------------------------------------------------*/
void task1(void *pvParameters);
TaskHandle_t task1_Handler;
void task2(void *pvParameters);
TaskHandle_t task2_Handler;
void task3(void *pvParameters);
TaskHandle_t task3_Handler;

void main_blinky( void )
{

	xTaskCreate( task1,				/* The function that implements the task. */
					"task1", 								/* The text name assigned to the task - for debug only as it is not used by the kernel. */
					configMINIMAL_STACK_SIZE * 2U, 			/* The size of the stack to allocate to the task. */
					NULL, 								/* The parameter passed to the task - not used in this case. */
					4, 	/* The priority assigned to the task. */
					&task1_Handler );
	xTaskCreate( task2,				/* The function that implements the task. */
					"task2", 								/* The text name assigned to the task - for debug only as it is not used by the kernel. */
					configMINIMAL_STACK_SIZE * 2U, 			/* The size of the stack to allocate to the task. */
					NULL, 								/* The parameter passed to the task - not used in this case. */
					4, 	/* The priority assigned to the task. */
					&task2_Handler );
	xTaskCreate( task3,				/* The function that implements the task. */
					"task3", 								/* The text name assigned to the task - for debug only as it is not used by the kernel. */
					configMINIMAL_STACK_SIZE * 2U, 			/* The size of the stack to allocate to the task. */
					NULL, 								/* The parameter passed to the task - not used in this case. */
					3, 	/* The priority assigned to the task. */
					&task3_Handler );
	vTaskStartScheduler();
	/* If all is well, the scheduler will now be running, and the following
	line will never be reached.  If the following line does execute, then
	there was insufficient FreeRTOS heap memory available for the Idle and/or
	timer tasks to be created.  See the memory management section on the
	FreeRTOS web site for more details on the FreeRTOS heap
	http://www.freertos.org/a00111.html. */
	for( ;; );
}

void task1(void *pvParameters)
{
	int i=0;
	while(1)
	{
	taskENTER_CRITICAL();
	i=i+1;
	printf("this is task 1 run time %d\n",i);
	taskEXIT_CRITICAL();
	vTaskDelay(2000);
	}
}

void task2(void *pvParameters)
{
	int i=0;
	while(1)
	{
	taskENTER_CRITICAL();
	i=i+1;
	printf("this is task 2 run time %d\n",i);
	if(i==10)
	{
		printf("DELETE task2-----------------------------------\n");
		vTaskDelete(NULL);
	}
	taskEXIT_CRITICAL();
	vTaskDelay(2000);
	}
}
void task3(void *pvParameters)
{
	int i=0;
	while(1)
	{
	taskENTER_CRITICAL();
	i=i+1;
	printf("this is task 3 run time %d\n",i);
	if(i==20)
	{
		printf("DELETE task3-----------------------------------\n");
		vTaskDelete(NULL);
	}
	taskEXIT_CRITICAL();
	vTaskDelay(2000);
	}
}
/*-----------------------------------------------------------*/

Hello zhongyuchao,

Can you step through your code until it gets stuck in prvCheckTasksWaitingTermination? It is likely that something broke elsewhere in your code, and every time you pause the debugger the kernel is sitting in the idle task waiting for the other tasks.

Have you implemented the various hooks? That could be a useful start for debugging this issue. https://www.freertos.org/a00016.html

Yes - that function is in the Idle task, so if the idle task is always running then it might be one of the following:

  1. If you don’t get any print messages, then maybe it is just that the printing is not working. If you are getting print messages it might be that the print message is actually the cause of your issue (see the notes in the book about why printing is often the cause of issues). Try by just incrementing a variable or toggling an LED in each task instead (i.e. take out the print messages). The suggestion to add hooks can help, as can ensuring you have stack overflow checking on.

  2. If each task executes once, but not again, then most likely the tick interrupt is not executing properly. If that doesn’t increment time, then the time outs never unblock the tasks as there is no time.

I do not get any print messages.Does this phenomenon indicate that idle tasks always running?

Are you tasks running at all? If you put a break point in them, does the break point get hit? They should run before the idle task.

Does printf() work before the scheduler has started (from main())?

printf() doe not work.In other words,it should print some messages but actually not.If I set a breakpoint,it really get hit.If I resume again and again,it always finally stucks in prvCheckTasksWaitingTermination.

How do you know it is stuck in prvCheckTaskWaitingTermination()? That is the function that will be running if the idle task is running, and the idle task will be running 99% of the time in your case - so it is not necessarily stuck there.

but I have create 3 tasks,and task3 will always be running.So why the idle task will run 99% of the time?

Because the three tasks block for 2000 ticks each time they run. So they run for a fraction of a tick, then enter the blocked state for 2000 ticks. So in fact the idle task probably runs for much more than 99% of the time.

Thanks for your answer,so how can I solve the problem?Can you give me some suggestions?

I refer you back to my comment:

I’m not sure what your problem is.