Changing Task Priority

ktownsend wrote on Tuesday, January 06, 2009:

I’m just trying FreeRTOS out for the first time, and have made two tasks with different priority.  As expected, the higher priority task executes 10 times, but when I adjust it’s priority to be lower (expecting the other task to kick in), everything seems to stop.  The second tasks priority is higher than idle, so I don’t understand why this is happening?  I get the same results if I delete the higher priortity task as well.  Perhaps the problem is with the handlers? 

If anyone has a moment to enlighted me, I’d appreciate it.  (It would be great to see more code examples on the website, but beggers can’t be choosers I suppose.)

-----------

#include "lpc214x.h"
#include "FreeRTOS.h"
#include "task.h"

// Note: On ARM7 devices, you must be using Supervisor mode to run the scheduler with FreeRTOS.
// This can be set in Crossworks by adding "#define SUPERVISOR_START" to crt0.s

// Declare task handlers (used to reference a task when required)
xTaskHandle xFirstTaskHandle, xPriorityTaskHandle;              

// Temp Fields
U8 counter = 0;

// First task code
static portTASK_FUNCTION (vFirstTask, pvParameters __attribute__ ((unused)))
{
    for( ;; )
    {
        debug_printf("Executing First Task\n");
    }
}

// Priority task code
static portTASK_FUNCTION (vPriorityTask, pvParameters __attribute__ ((unused)))
{
    for( ;; )
    {
        debug_printf("Executing Priority Task\n");
        counter++;

        // If this task has been executed 10 times, reduce it’s priority
        if (counter == 10)
        {
          counter = 0;

          // Remove this task from the scheduler
          // vTaskDelete(xPriorityTaskHandle);

          // Lower this task’s priority
          vTaskPrioritySet(xPriorityTaskHandle, tskIDLE_PRIORITY + 1);
        }
    }
}

int main(void)
{

  xTaskCreate(vFirstTask, (const signed portCHAR * const) "FIRST", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 2), &xFirstTaskHandle);
  xTaskCreate(vPriorityTask, (const signed portCHAR * const) "PRIORITY", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 3), &xPriorityTaskHandle);

  // Start scheduler
  vTaskStartScheduler ();

  return 0;
}

rtel wrote on Tuesday, January 06, 2009:

> I’m just trying FreeRTOS out for the first time, and have
> made two tasks with different priority.  As expected, the
> higher priority task executes 10 times, but when I adjust
> it’s priority to be lower (expecting the other task to kick
> in), everything seems to stop.  The second tasks priority is
> higher than idle, so I don’t understand why this is
> happening?  I get the same results if I delete the higher
> priortity task as well.  Perhaps the problem is with the handlers?
>
> If anyone has a moment to enlighted me, I’d appreciate it. 
> (It would be great to see more code examples on the website,
> but beggers can’t be choosers I suppose.)

There is a new pdf file, but there is a small charge for it (it took a long time to write!)

> // First task code
> static portTASK_FUNCTION (vFirstTask, pvParameters
> __attribute__ ((unused))) {
>     for( ;; )
>     {
>         debug_printf("Executing First Task\n");
>     }
> }

I’m not sure if the unused attribute will have any negative effect or not as I have not looked at the output it generates.  You can just write the function:

static void vFirstTask( void *pvParameters )

The portTASK_FUNCTION macro is provided for weird compilers that requires special voodoo.

Does debug_printf() output to the CrossWorks IDE?  If so then there are two things to check, first is that it does not use the SWI interrupt to do this (many IDEs do) because FreeRTOS uses the SWI itself, and second you may need some mutual exclusion as a task switch while debug_printf() is being used could cause corruption, although probably not a crash.

Also this task will continuously hammer debug_printf() which might be very intensive on the JTAG interface and make it appear as if nothing is happening.  Try adding a vTaskDelay( 500 ) after each call, just to see if it makes a difference.

>
> // Priority task code
> static portTASK_FUNCTION (vPriorityTask, pvParameters
> __attribute__ ((unused))) {
>     for( ;; )
>     {
>         debug_printf(“Executing Priority Task\n”);
>         counter++;
>
>         // If this task has been executed 10 times, reduce
> it’s priority
>         if (counter == 10)
>         {
>           counter = 0;
>
>           // Remove this task from the scheduler
>           // vTaskDelete(xPriorityTaskHandle);
>
>           // Lower this task’s priority
>           vTaskPrioritySet(xPriorityTaskHandle, tskIDLE_PRIORITY + 1);
>         }

I think your use of the handles is correct, so just for reference, if you want to change the priority of the task calling vTaskPrioritySet() then you don’t need a handle and can just use NULL as the first task parameter.

Regards.