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.

RTOS/EK-TM4C1294XL: Static Task Reference

Part Number: EK-TM4C1294XL

Tool/software: TI-RTOS

Hi,

I've created a task in app.cfg, like this:

Program.global.Task_HeartBeat = Task.create("&HeartBeatFxn", task1Params);

I'd like to stop and start this task with a button so have the following questions:

1) What's the best way to stop and start this task, should I block / unblock it OR set its priority to -1 and the back to some priority above zero to enable it OR something else?

2) How do I get a reference to this task in order to stop and start it? Since it's created in the app.cfg I'm not sure how I can refer to this task in the code that's triggered by my button press.

Thanks in advance for your help!

Cheers,

Tim

  • Tim,

    You must define a function called "HeartBeatFxn" in your application. This function will serve as your task and will begin execution after BIOS_Start().

    As a quick test case, you could use something like the pseudo code below to ensure your task is running as expected:

    void HeartBeatFxn(void * someArg)
    {
        while(1)
        {
           /* Toggle an LED */  
           /* Sleep for 1 second */
        }
    }
    

    1. The best way to start and stop a task is to block/unblock. This can easily be achieved using a semaphore. Check out the pseudo code below:

    /* Your heartBeat function is "running" by default */
    static volatile uint8_t isHeartRunning = 1;
    
    void pushButtonInterrupt(void)
    {
    
        if (isHeartRunning == 1)
        {
            isHeartRunning = 0;
        }
        else 
        {
            isHeartRunning = 1;
            
            /* 
             * This will unblock the heartbeat function/tasks. Since
             * This is in a interrupt context, the scheduler will not
             * be called until this ISR is complete.
             */
            Semaphore_post(Heartbeat_Semaphore);
        }
    
        /* Add code to clear the button interrupt */
    
    }
    
    
    void HeartBeatFxn(void * someArg)
    {
        while(1)
        {
           
           /* Disable interrupts here */
           if (isHeartRunning == 0)
           {
                /* Re-enable interrupts here */
             
                /* This will block the task until the button is pressed. */
                Semaphore_pend(Heartbeat_Semaphore);
           }
           else
           {
               /* Re-enable interrupts */
           }
    
           /* Your heartbeat code goes here. */
        }
    }

    2. You will be able to use a Semaphore to achieve the blocking/unblocking. You therefore would not need any reference to the task.

  • Thanks Derrick, I will give that a go and let you know how it turns out.

    Quick question though, how can I ensure that the tasks starts as blocked? Is there a way to block it once it's created in app.cfg? The button would be used to unblock the task, which I want the task to run through once, then block itself again.

    Many thanks for your help so far!

    Cheers
  • Hi Tim,

    There are actually two ways you can solve your issue--my original response addresses one.

    An easier solution is to use Task_setPri(). The task priority can be set to -1 which puts the
    task into the INACTIVE state and the task will not run.

    task1Params.priority = -1;
    Program.global.Task_HeartBeat = Task.create("&HeartBeatFxn", task1Params);

    This will cause the task to initially be in an inactive state. Inside your application, you can then do the following:

    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    
    #include <ti/sysbios/knl/Task.h>
    
    void pushButtonInterrupt(void)
    {
    
        static uint32_t taskPriority = 6;
    
        /*
         * The following function, Task_setPri() accepts the new priority and
         * returns the old priority. This code assumes that the initial priority
         * is (-1) as set in the application.cfg file. This ISR will toggle the
         * priority between (-1) and (6). This also assumes that the priority of
         * this task is not being modified anywhere else in the application.
         * Toggle the Task Priority.
         */
        taskPriority = Task_setPri(Task_HeartBeat, taskPriority);
    
        /* Add code to clear the button interrupt */
    
    }
    
    Void HeartBeatFxn(UArg arg0, UArg arg1)
    {
        while(1)
        {
           /* Your heartbeat code goes here. */
        }
    }

    If you chose to stick with my original method, you wish to know how the task starts as blocked. In that case, you would set your global flag, isHeartRunning, to zero. The task will then immediately block until a button press. Note that this also depends on the Semaphore being created with an initial count of 0.

    Derrick