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.

LAUNCHXL-F28379D: SYS/BIOS Running Task function before Clock function

Part Number: LAUNCHXL-F28379D


Hi,

I have a Task and a Clock (periodic function) created using the Task_create and Clock_create functions.

I was hoping to run some one-time initializations as part of the task and some periodic actions using clock. But I notice that the Clock function is getting executed before the Task function.

I have used _create functions as below

Task_create(Init_Fxn, &tskParams1, &eb1);

Clock_create(Clk_Fxn, 5, &clkParams, NULL);

Question 1:

Could you help me with the files that needs to be modified to change the scheduling of Tasks and Clocks?

Question 2:

Is there another way to make tasks periodic (other than creating a Clock function)?

Regards,

Rashmitha 

  • Could you leave the clock disabled until after the Task has a chance to do its initialization and then start it? I thought the Clock startFlag parameter defaulted to false--are you enabling it somewhere? The clock function executes as part of a Swi context so it's always going to have a higher priority than a Task, regardless of how you've configured the Task priorities.

    You can use Timers for periodic functions, although note that their functions run within Hwi context. If you're specifically looking for controlling the timing of Tasks you can use Task_sleep to put them to sleep for a period of time or use a semaphore to block it for a while until a Timer/Clock function posts the semaphore.

    Whitney

  • Hi Whitney,

    I had set "    clkParams.startFlag = TRUE; " 

    I am assuming that the task initialization happens after BIOS_start() is called in my application file.

    and the startFlag needs to be set before BIOS_start() is called, isnt it?

    Currently the code is like this:

    /* Create a periodic Task Instance*/
    Error_init(&eb1); 
    Task_Params_init(&tskParams1);
    tskParams1.priority = 1;

    task = Task_create(taskfxn0, &tskParams1, &eb1);

    /* Create a periodic Clock Instance with period = 5 system time units */
    Clock_Params_init(&clkParams);
    clkParams.period = 5;
    clkParams.startFlag = TRUE;
    CLK = Clock_create(clkfxn0, 5, &clkParams, NULL);
    if (CLK == NULL) {
    System_printf("Clock_create() failed!\n");
    BIOS_exit(0);
    }

    BIOS_start(); /* does not return */
    return(0);

    Question 1:

    Where else do you suggest adding startFlag parameter ?

    Question 2:

    Could you point me to any example that uses Timers? I cannot find any in SYS/BIOS templates/examples

    Regards,

    Rashmitha

  • I suggest leaving startFlag set to false when you first create the Clock instance, and then once your Task has completed its initialization, you can call Clock_start(). Would that work?

    The "swi28" and "task28" examples use the Timer module--you'll see the timer set up in the examples' .cfg file. If you aren't sure how to find these examples, there are some instructions here.

    Whitney

  • Hi Whitney,

    Thank you for your response.

    I am trying to do with 2 clock instances now and my create statements are as below

    "

    /* Create an one-shot Clock Instance with timeout = 5 system time units */
    Clock_Params_init(&clkParams2);
    clkParams2.period = 0;
    clkParams2.startFlag = TRUE;
    Clock_create(Init_Fxn, 5, &clkParams2, NULL);

    /* Create a periodic Clock Instance with period = 5 system time units */
    Clock_Params_init(&clkParams1);
    clkParams1.period = 5;
    clkParams1.startFlag = TRUE;
    Clock_create(Repeat_Fxn, 5, &clkParams1, NULL);

    "

    As expected Init_Fxn is getting executed first and Repeat_Fxn executes after that. However, Repeat_Fxn is only executed once and then it keeps going through SYS/BIOS code when I step through until a Stack Overflow error occurs

    I want the Repeat_Fxn to run indefinitely

    I can see in the ROV classic window that PERIODIC =TRUE for my second function.

  • Do you think you are only seeing it once because of the stack overflow? As in, the stack overflow is occurring in the period between the first run and the second? Does increasing the stack size solve the problem?

    Whitney

  • Hi Whitney,

    I will try increasing the stack size. But the same issue occurred when I modified the clock example given with SYS/BIOS. Please find the code below. I am using semaphore as printf is giving GateMutex error and I found another post that suggests using semaphore to get rid of the error.

    Void clkFxn(UArg arg0);
    Void clk0Fxn(UArg arg0);
    Void clk1Fxn(UArg arg0);
    void myTask0();
    void myTask();
    void myTask2();
    
    Semaphore_Handle mySem0, mySem, mySem2;
    
    /*
     *  ======== main ========
     */
    Int main()
    {
        Clock_Handle clk0, clk2;
        Clock_Params clkParams;
        Task_Params taskParams;
    
        mySem0 = Semaphore_create(0, NULL, NULL);
        mySem = Semaphore_create(0, NULL, NULL);
        mySem2 = Semaphore_create(0, NULL, NULL);
    
        Task_Params_init(&taskParams);
        taskParams.priority = 1;
        Task_create (myTask0, &taskParams, NULL);
    
        Task_Params_init(&taskParams);
        taskParams.priority = 2;
        Task_create (myTask, &taskParams, NULL);
    
        Task_Params_init(&taskParams);
        taskParams.priority = 3;
        Task_create (myTask2, &taskParams, NULL);
    
        /* Create an one-shot Clock Instance with timeout = 11 system time units */
        Clock_Params_init(&clkParams);
        clkParams.period = 0;
        clkParams.startFlag = TRUE;
        clk0 = Clock_create(clkFxn, 1, &clkParams, NULL);
    
     //   Clock_start(clk0);
    
        /* Create a periodic Clock Instance with period = 5 system time units */
        clkParams.period = 5;
        clkParams.startFlag = TRUE;
        Clock_create(clk0Fxn, 5, &clkParams, NULL);
        
        /* Create an one-shot Clock Instance with timeout = 11 system time units */
        clkParams.period = 0;
        clkParams.startFlag = FALSE;
        clk2 = Clock_create(clk1Fxn, 21, &clkParams, NULL);
    
        Clock_start(clk2);
                    
        BIOS_start();    /* does not return */
        return(0);
    }
    
    
    void myTask0()
    {
        Semaphore_pend(mySem0, BIOS_WAIT_FOREVER);
    
    	UInt32 time;
    
        time = Clock_getTicks();
        System_printf("System time in INIT = %lu\n", (ULong)time);
        System_flush(); /* force SysMin output to console */
    
    }
    
    void myTask()
    {
        Semaphore_pend(mySem, BIOS_WAIT_FOREVER);
    
    	UInt32 time;
    
        time = Clock_getTicks();
        System_printf("System time in MAIN = %lu\n", (ULong)time);
        System_flush(); /* force SysMin output to console */
    
    }
    
    void myTask2()
    {
        Semaphore_pend(mySem2, BIOS_WAIT_FOREVER);
    
        UInt32 time;
    
        time = Clock_getTicks();
        System_printf("System time in ABORT = %lu\n", (ULong)time);
        System_printf("Calling BIOS_exit() from clk1Fxn\n");
        System_flush(); /* force SysMin output to console */
        BIOS_exit(0);
    
    }
    
    /*
     *  ======== clkFxn =======
     */
    Void clkFxn(UArg arg0)
    {
    	Semaphore_post(mySem0);
    }
    
    /*
     *  ======== clk0Fxn =======
     */
    Void clk0Fxn(UArg arg0)
    {
    	Semaphore_post(mySem);
    }
    
    /*
     *  ======== clk1Fxn =======
     */
    Void clk1Fxn(UArg arg0)
    {
    	Semaphore_post(mySem2);
    }

    Even with this code, the output was

    System time in INIT = 1

    System time in INIT = 1

    System time in MAIN = 5

    System time in ABORT = 21

    I was expecting MAIN to be printed for clock values 10, 15 and 20 too but that is not happening. In this case there is no stackoverflow error and the program reaches BIOS_Exit() correctly.

  • Your myTask function prints once and ends. If you want the task to execute multiple times, you need to put a loop in it. If I put the contents of myTask in a while(1) loop I got

    System time in INIT = 1
    System time in MAIN = 5
    System time in MAIN = 10
    System time in MAIN = 15
    System time in MAIN = 20
    System time in ABORT = 21
    Calling BIOS_exit() from clk1Fxn

    Whitney

  • Hi Whitney,

    The original clock example project prints multiple times from clk0fxn even without a while(1) loop

    Void clk0Fxn(UArg arg0);
    Void clk1Fxn(UArg arg0);
            
    /*
     *  ======== main ========
     */
    Int main()
    {
        Clock_Handle clk2;       
        Clock_Params clkParams;
    
        /* Create a periodic Clock Instance with period = 5 system time units */
        Clock_Params_init(&clkParams);
        clkParams.period = 5;
        clkParams.startFlag = TRUE;
        Clock_create(clk0Fxn, 5, &clkParams, NULL);
        
        /* Create an one-shot Clock Instance with timeout = 11 system time units */
        clkParams.period = 0;
        clkParams.startFlag = FALSE;
        clk2 = Clock_create(clk1Fxn, 21, &clkParams, NULL);
    
        Clock_start(clk2);
                    
        BIOS_start();    /* does not return */
        return(0);
    }
    
    /*
     *  ======== clk0Fxn =======
     */
    Void clk0Fxn(UArg arg0)
    {
        UInt32 time;
        
        time = Clock_getTicks();
        System_printf("System time in clk0Fxn = %lu\n", (ULong)time);
    }
    
    /*
     *  ======== clk1Fxn =======
     */
    Void clk1Fxn(UArg arg0)
    {
        UInt32 time;
        
        time = Clock_getTicks();
        System_printf("System time in clk1Fxn = %lu\n", (ULong)time);
        System_printf("Calling BIOS_exit() from clk1Fxn\n");
        BIOS_exit(0);
    }
    
    

    And the output I get is

    Each time the timeout value for clk0 is reached the clk0fxn should be evoked and all of the code that is inside should be executed. Why does the implementation using task and semaphore skip executing the code after the first evoke?

  • clk0Fxn is a Clock function--it's periodic. There is a Clock tick interrupt that occurs on a CPU timer timeout that checks to see if any of the Clock instances are ready to run and if so it posts a Swi that executes your Clock function. Your myTask is a Task function--it is not periodic. You create it, it runs, it returns, and that's it unless you use a loop to keep it running.

    Whitney

  • Thank you for the explanation. I understand it now.

    I was expecting the task to execute each time the semaphore is posted by clkfxns. But yes, that would need an infinite loop.