Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tasks behaving incorrectly in round-robin schedule

I have FreeRTOS running on a STM32F4DISCOVERY board, and I have this code:

xTaskCreate( vTask1, "Task 1", 200, NULL, 1, NULL );
xTaskCreate( vTask2, "Task 2", 200, NULL, 1, NULL );
vTaskStartScheduler();

where vTask1 is this function:

void vTask1( void *pvParameters )
{
volatile unsigned long ul;

    for( ;; )
    {
        LED_On(0);

        for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
        {
        }
        LED_On(2);
        LED_Off(0);
    }
}

vTask2 has nearly the same code:

void vTask2( void *pvParameters )
{
const char *pcTaskName = "Task 2 is running\n";
volatile unsigned long ul;

    for( ;; )
    {
        LED_On(3);
        LED_Off(2);
        for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
        {
        }

        LED_Off(3);
    }
}

When I run the program, I see that LED0 and LED3 are always on (their switching is too fast for my eye, which is fine), and that LED2, the "shared resource", is blinking very fast. The problem is this: when I reverse the order of the xTaskCreate calls, I get the same situation with a different blinking behavior of LED2, which is much slower. Why would this happen, since the tasks should have equal priority and therefore follow a round-robin schedule? Shouldn't they get the same amount of time? Why is their behavior changing after only having created them in different order?

Thanks in advance.

like image 848
scristalli Avatar asked Apr 12 '13 15:04

scristalli


1 Answers

The rtos does not try to round robin through the tasks and you should not expect them to execute in any specific order. Neither of the tasks you have created have a delay in them as iama pointed out in their comment. instead of creating a delay by burning through no-ops in a for loop, use the delay function. this will allow the code in your while(1) loop to execute then yield back to the rtos so that the processor can run other tasks until the wait time has elapsed. If you need to synchronize work you may want to just keep it in a single task. If you have one task that is dependent on something done in another, you may want to use semaphores, queues, or other cross thread communication method.

Your code reminds me of when I was transitioning from using a while(1) loop in main to an rtos. If your new to using an rtos, this guide from ST looks like it would be a good introduction https://www.st.com/resource/en/user_manual/dm00105262-developing-applications-on-stm32cube-with-rtos-stmicroelectronics.pdf

Also, do not rely on the delay function for fine grain timing; use a timer driven interrupt instead. The link above should give you a better understanding of why then I could manage in this post.

ST should also have example projects somewhere, which would be good to reference or use as a start for your own project.

like image 157
Luke Sackash Avatar answered Oct 01 '22 03:10

Luke Sackash