This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Time Slicing and Tasks

Other Parts Discussed in Thread: SYSBIOS

Hello,

I have created below program from New CCS project and SYS/BIOS typical template.

/*
 *  ======== main.c ========
 */

#include <xdc/std.h>

#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>

/*
 *  ======== taskFxn ========
 */
Void task1Fxn(UArg a0, UArg a1)
{
    System_printf("enter task1Fxn(): %d\n",(Int)a0);
    System_printf("exit task1Fxn()\n");

}
Void task2Fxn(UArg a0, UArg a1)
{
    System_printf("enter task2Fxn(): %d\n",(Int)a0);
    System_printf("exit task2Fxn()\n");
}
Void clkFxn(UArg a0)
{
    UInt32 ticks;
    System_printf("Entered Clock Function\n");
    Task_yield();
    ticks = Clock_getTicks();// Time in Clock ticks()
    if(ticks > 20)
        BIOS_exit(0);
    System_printf("Exit Clock Function\n");
}

/*
 *  ======== main ========clk
 */
Void main()
{
    Task_Handle task1,task2;
    Task_Params taskParams;
    Clock_Params clkParams;
    Error_Block eb;

    System_printf("enter main()\n");
    //create Clock dynamically
    Clock_Params_init(&clkParams);
    clkParams.period = 2;
    clkParams.arg = 0;
    clkParams.startFlag = TRUE;
    Clock_create(clkFxn, 2, &clkParams,NULL);

    Task_Params_init(&taskParams);
    //Create task1
    Error_init(&eb);
    taskParams.arg0 = 1;
    taskParams.priority = 3;
    taskParams.stackSize = 512;
    task1 = Task_create(task1Fxn, &taskParams, &eb);
    if (task1 == NULL) {
        System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }
    //Create task2
    Error_init(&eb);
    taskParams.arg0 = 2;
    taskParams.priority = 3;
    taskParams.stackSize = 512;
    task2 = Task_create(task2Fxn, &taskParams, &eb);
    if (task2 == NULL) {
        System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }
    BIOS_start();     /* enable interrupts and start SYS/BIOS */
}


-------------------------------------------------------------------------------------------------------

1) one clock function is defined with period = 2 ticks. ( clkFxn)

2) two task functions are defined with same priority = 3 (task1Fxn and task2Fxn)

I used Task_yield() in clock function.

So, I believe that the sequence should be like,

1) Clock tick shall start

2) with 2delay +2 period ticks completed, and clock function shall come in picture.

3) Task_yield() shall be executed and control shall go to task1Fxn.

4) With more 2 ticks, Task_yield() shall be executed again and control shall go to task2 Fxn.

5) Sequence 3 and 4 shall remain continue till tick time <20

I get below output:

[Cortex_M3_0] n(): 1
exit task1Fxn()
enter task2Fxn(): 2
exit task2Fxn()
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function
Exit Clock Function
Entered Clock Function

but I believe that between every, Entered Clock Function and Exit Clock Function, there should be printfs of task1Fxn and task2Fxn alternatively.

Is my understanding about time slicing correct? or I am missing some fundamental?

( I referred to Example 3.1 Time Slicing from SYS/BIOS v 6.35 User's guide - June2013)

Thanks in advance.

  • Hi,

    You are letting the Task exit (as noted by the output). Once a Task exits, it does not come back unless you re-create it. Tasks almost always have a "while" loop. For example

     

    Void task1Fxn(UArg a0, UArg a1)
    {    
        while (1) {
            System_printf("running %d\n",(Int)a0);
        }
    }

    And similarly for task2Fxn. Now you example will print lots of "running 1" and then when the clkFxn runs, you see a bunch of "running 2" output.

    Todd

  • Hello Todd,

    I am not explicitly letting task to exit.

    Task is created but never deleted so, I feel no need to recreate it. ( This is my understanding please correct me)

    I believe that with first Task_yield(), task1 should be executed.

    When second Task_Yield() occurs after 2 clock ticks, task1 shall be blocked and task2 shall be executed.

    This is what I understood as time slicing.

    ---------------------

    I modified program according to your comments. But still not getting desired output.

    /*
     *  ======== main.c ========
     */

    #include <xdc/std.h>

    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>

    #include <ti/sysbios/BIOS.h>

    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>

    /*
     *  ======== taskFxn ========
     */
    Void task1Fxn(UArg a0, UArg a1)
    {
        System_printf("enter task1Fxn(): %d\n",(Int)a0);
        while (1)
        {
            System_printf("running %d\n",(Int)a0);
        }
       // System_printf("exit task1Fxn()\n");

    }
    Void task2Fxn(UArg a0, UArg a1)
    {
        System_printf("enter task2Fxn(): %d\n",(Int)a0);
        while (1)
        {
            System_printf("running %d\n",(Int)a0);
        }
        //System_printf("exit task2Fxn()\n");
    }
    Void clkFxn(UArg a0)
    {
        UInt32 ticks;
        System_printf("Entered Clock Function\n");
        Task_yield();
        ticks = Clock_getTicks();// Time in Clock ticks()
        if(ticks > 20)
            BIOS_exit(0);
        System_printf("Exit Clock Function\n");
    }

    /*
     *  ======== main ========clk
     */
    Void main()
    {
        Task_Handle task1,task2;
        Task_Params taskParams;
        Clock_Params clkParams;
        Error_Block eb;

        System_printf("enter main()\n");
        //create Clock dynamically
        Clock_Params_init(&clkParams);
        clkParams.period = 2;
        clkParams.arg = 0;
        clkParams.startFlag = TRUE;
        Clock_create(clkFxn, 2, &clkParams,NULL);

        Task_Params_init(&taskParams);
        //Create task1
        Error_init(&eb);
        taskParams.arg0 = 1;
        taskParams.priority = 3;
        taskParams.stackSize = 512;
        task1 = Task_create(task1Fxn, &taskParams, &eb);
        if (task1 == NULL) {
            System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }
        //Create task2
        Error_init(&eb);
        taskParams.arg0 = 2;
        taskParams.priority = 3;
        taskParams.stackSize = 512;
        task2 = Task_create(task2Fxn, &taskParams, &eb);
        if (task2 == NULL) {
            System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }
        BIOS_start();     /* enable interrupts and start SYS/BIOS */
    }
    -----------------------------------

    Output is

    [Cortex_M3_0]
    Exit Clock Function
    ng 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    running 1
    runEntered Clock Function

  • For information,

    Also to my question I wanted to add that I know and  want to clarify below statement from my above mentioned application.

    " invoking the Task_yield() API from within a periodic interrupt. This will cause the two tasks to alternately pre-empt each other for the duration of the periodic interrupt"

  • Try making your SysMin output buffer larger. You'll see more output then.For example:

    SysMin.bufSize = 0x1000;

    If you have a Task and it calls "return" (implicitly or explicitly), then you have exited  the Task and it will never run again. It is now terminated. So in your first example, there is an implied "return" because the function is a void.

    Void task1Fxn(UArg a0, UArg a1)
    {
        System_printf("enter task1Fxn(): %d\n",(Int)a0);
        System_printf("exit task1Fxn()\n");
    }

    Note: depending on you version of SYS/BIOS, there is a configuration parameter called Task.deleteTerminatedTasks. This dictates whether a terminated task is deleted automatically or not.

  • Hello Todd,

    Thanks for the reply.

    I created while(1) loop and it solves my problem and Task_yield() calls both function one by one.