Issue with FreeRTOS priorities

cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with FreeRTOS priorities

817 Views
luca_corna
Contributor I

Hallo,

I am developing my application on FreeRTOS port from NXP for ImX8.

I am creating just as demo 2 simple task. The first (loop_task) contains just a while(1) with a counter++. The second (uart_task) a while(1) with the API UART_RTOS_Send.

void loop_task()

{

   static int counter;

   while(1)

   counter++;

}

void uart_task()

{

   while(1)

   {

      UART_RTOS_Send(handle, &out_buffer, strlen(out_buffer));

   }

}

I have the following behaviors in the following cases:

case 1

#define configUSE_PREEMPTION       1

xTaskCreate(loop_task, "loop_task", 200, NULL, 3, NULL);

xTaskCreate(uart_task, "uart_task", 200, NULL, 4, NULL);

The uart task send the first time the buffer and then correctly yields. The scheduler put the loop_task in running. So far so good.

Then (depending on my tick configuration), when the uart_task is ready, the scheduler should put loop_task in ready and uart_task in running. But this does not happens. After the first "send" the uart_task starves. The situation I encounter should occur with #define configUSE_PREEMPTION    0.

case 2

#define configUSE_PREEMPTION       1

xTaskCreate(loop_task, "loop_task", 200, NULL, 2, NULL);

xTaskCreate(uart_task, "uart_task", 200, NULL, 4, NULL);

Just changing the loop_task from 3 to 2 made the application work as expected. Where is the trick? is it a bug of FreeRTOS port or what?

0 Kudos
4 Replies

572 Views
luca_corna
Contributor I

Hallo,

UART_RTOS_Send is NXP API provided with SDK. It transmits and then (waiting for the transfer callback) it yields.

In my case 1. it is the higher priority task that starves!

In case 2 everything works perfectly: the uart task sends the messages, then it yields. In that moment the loop task can run untile the uart unblocks.

These 2 cases should perform in the same way but they don't.

0 Kudos

572 Views
BlackNight
NXP Employee
NXP Employee

not directly related, but your tasks should be of the form

void myTask(void *pv) {
...
}‍‍‍

You actually are not giving back any CPU time, so they are starving any lower prio tasks.

So your task should be something like this:

void loop_task(void *pv)
{
   static int counter;

   while(1) {
     counter++;
     vTaskDelay(pdMS_TO_TICKS(10));
   }
}

void uart_task(void *pv)
{
   while(1)
   {
      UART_RTOS_Send(handle, &out_buffer, strlen(out_buffer));
      vTaskDelay(pdMS_TO_TICKS(10));
   }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

In your first case you have the uart_task running with the highest prio: if he does not give back time or is not suspended by any RTOS API calls, it will just consume all the CPU time.

I'm not sure what your UART_RTOS_Send() does (blocking or not?), but this will be an issue.

Changing the priorities as in your case 2 does not change anything. But keep in mind that there is at least the IDLE task running (at prio 0) and the timer task (at a higher prio, if you have enabled it). And other tasks can play into this too. At the end, I think it really depends what your UART_RTOS_Send() is exactly doing.

I hope this helps,

Erich

0 Kudos

572 Views
luca_corna
Contributor I

Hello,

I discovered that that configTIMER_TASK_PRIORITY was set to 2, exactly the value that, assigned to the loop_task, made my application work. To prove it, I set configTIMER_TASK_PRIORITY to the maximum. This made the application work as expected in every situation. 

So the question is: why should it be put to the maximum? it is not something that is requested in the manuals.

0 Kudos

572 Views
BlackNight
NXP Employee
NXP Employee

If you are using FreeRTOS timers, it is recommended to give it the (configMAX_PRIORITIES-1U) priority.

For more about how timers work, see

Tutorial: Understanding and Using FreeRTOS Software Timers | MCU on Eclipse 

I hope this helps,

Erich

0 Kudos