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/CC1310: Weird semaphore behavior

Part Number: CC1310

Tool/software: TI-RTOS

Hi there, I am facing issues working with 2 tasks. The function that starts the 2 task is as follow:

void rxTaskInit(PIN_Handle ledPinHandle) {
    pinHandle = ledPinHandle;

    Task_Params_init(&rxWakeTaskParams);
    rxWakeTaskParams.stackSize = RFEASYLINKRX_TASK_STACK_SIZE;
    rxWakeTaskParams.priority = 2;
    rxWakeTaskParams.stack = &rxWakeTaskStack;
    rxWakeTaskParams.arg0 = (UInt)1000000;

    Task_Params_init(&rxDataTaskParams);
    rxDataTaskParams.stackSize = RFEASYLINKRX_TASK_STACK_SIZE;
    rxDataTaskParams.priority = 1;
    rxDataTaskParams.stack = &rxDataTaskStack;
    rxDataTaskParams.arg0 = (UInt)1000000;

    Task_construct(&rxWakeTask, rfSlaveRXWakeTask, &rxWakeTaskParams, NULL);
    Task_construct(&rxDataTask, rfSlaveRXDataTask, &rxDataTaskParams, NULL);
}

rfSlaveRXWakeTask and rfSlaveRXDataTask : 

static void rfSlaveRXDataTask(UArg arg0, UArg arg1){
    while(1) {
        Semaphore_pend(rxInterchangeSem, BIOS_WAIT_FOREVER);
        // Do stuff, then semaphore_post to let higher priority task (rfSlaveRXWakeTask) to continue
        Semaphore_post(rxInterchangeSem);
    }
}

static void rfSlaveRXWakeTask(UArg arg0, UArg arg1){
    while(1) {
        Semaphore_pend(rxInterchangeSem, BIOS_WAIT_FOREVER);

        // Do RX stuff, then sleep for 5 seconds before semaphore_post
        Task_sleep(5000 * 1000 / Clock_tickPeriod);

        Semaphore_post(rxInterchangeSem);

        // if a "Wake" packet is received, pause this higher priority task and allow the lower priority task (rfSlaveRXDataTask) to start
        if(isWakeReceived){
            isWakeReceived = FALSE;
            Task_sleep(5);
        }
    }
}

The expected behavior is to have "rfSlaveRXWakeTask" to run indefinitely, RF RX for 500ms every 5 seconds.

"isWakeReceived" will be changed to TRUE when a "Wake" packet is received.

Then "rfSlaveRXWakeTask" will sleep for 5 ticks to allow "rfSlaveRXDataTask" to continue.

When "rfSlaveRXDataTask" has done executing, it will semaphoire_post to let "rfSlaveRXWakeTask" to continue.


However, the actual behavior is:

"rfSlaveRXWakeTask" runs once, then "rfSlaveRXDataTask" runs once, sleep for 5 seconds, repeat.

What did I miss here...

Please advise.

Thanks.

Edit:

I realize that if I remove  Task_sleep(5000 * 1000 / Clock_tickPeriod);  line 14 from "rfSlaveRXWakeTask", "rfSlaveRXDataTask" will not be executed.

But "rfSlaveRXWakeTask" has to stop for a few seconds before the next loop, removing it is not an option.

Why is Task_sleep affecting the flow of the whole program?

  • Hi Lana,

    I'm not sure on how you setup the semaphores, could you share this as well? Is there a reason you want to defer processing to "Data Task" and block out the radio task for the complete processing time? Is there any other task in the system active?
  • Hi M-W,

    Semaphore initialization:

    Semaphore_Params_init(&rxInterchangeParams);
    Error_init(&rxInterchangeEb);

    /* Create semaphore instance */
    rxInterchangeSem = Semaphore_create(1, &rxInterchangeParams, &rxInterchangeEb);
    if(rxInterchangeSem == NULL){
    System_abort("Semaphore creation failed");
    }

    Well, the "Wake Task" is the task that is going to be running indefinitely.
    It will RF RX for 300ms every 5 seconds, listening for incoming "WAKE" packets.
    Once a "WAKE" packet is received, it will then run the "DATA Task", RF RX for 5 seconds continuously, to listen/ receive multiple long data packets.

    This flow is to save current consumption.

    Anyway, now I've accomplished what I wanted by just having the "Wake Task" running indefinitely, and the "DATA task" is now a function that will get called in the async RX callback from "WAKE Task".
  • Hi Lana,

    Just out of curiosity, did you try the original solution out using both counting and binary semaphores?

    Another solution in your case could have been to use the Event system, where one task waits for a "Process trigger" while the other waits for either "RX" or "Process done". You then setup a timer to create the periodic "5s" event.
  • Hi M-W,

    Is there an example for the "Event system" you've mentioned?
    Thanks
  • Hi Lana,

    Except from many of the stack projects using the event system, there is no "clean" examples on how to use events. Is however rather simple and the TI-RTOS User guide contain some code snippets that you might find helpful:

    dev.ti.com/.../Bios_User_Guide.pdf