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.

Semaphore: line 207: assertion failure: A_badContext: bad calling context. Must be called from a Task.

Other Parts Discussed in Thread: SYSBIOS

I need to call a CC3000 firmware method using a Clock or Timer. Unfortunately when I do this, I get the following error message.

ti.sysbios.knl.Semaphore: line 207: assertion failure: A_badContext: bad calling context. Must be called from a Task.

I know that I am getting this as a Clock creates a SWI thread and a Timer creates a HWI thread. Both of these threads will cause an assertion failure when a semaphore pend is called, which I believe is occurring when I call the CC3000 firmware method mdnsAdvertiser.

I have tried starting the Clock and Timer from within a Task context, but this makes no difference.

Here is my code

void mDNSSend(UArg arg0)
{
	char device_name[] = "DeviceName";

	if ((deviceConnected == TRUE) && (dhcpComplete == TRUE))
	{
		mdnsAdvertiser(1,device_name,strlen(device_name));  //This is where the assertion failure occurs
	}
}

/* Timer task, I have also tried a Clock with a timeout value set, but still get the assertion */
void mDNSSendTask(UArg arg0, UArg arg1)
{
    Error_Block eb;
    Timer_Params timerParams;
    Error_init(&eb);
    Timer_Params_init(&timerParams);
    timerParams.period = 200000; 
    timerHandle = Timer_create(Timer_ANY, mDNSSend, &timerParams, &eb);
    if (timerHandle == NULL)
    {
    	System_abort("Timer create failed");
    }
}

/* mDNSSendTask is created statically in my TI-RTOS config */
/* I have also tried starting dynamically, but get the same result */
var taskParams = new Task.Params();
taskParams.instance.name = "mDNSSendTask";
taskParams.stackSize = 1024;
taskParams.priority = 4;
Program.global.wifiTask = Task.create("&mDNSSendTask", taskParams);

Is there any way I can call the mdnsAdvertiser method with a Clock or Timer?

If there is no way, then how can I call this method on a regular timed basis?

Glenn.

  • Glenn,

    Even though you are creating the Timer (or Clock) from your task, the callback function that is invoked by Timer (or Clock) will not be running as a Task - this is what is causing the assertion. You need to call your mDNSSend() function from the task directly.

    If your timing accuracy is not critical, you could just use Task_sleep():

    Void mdnsTask(UArg arg0, UArg arg1)
    {
        while (TRUE) {
            Task_sleep(MDNSPERIOD_IN_TICKS);
            mDNSSend(0);
        }
    }
    

    If you need better performance, create a Clock object that posts a semaphore:

    Void mdnsTask(UArg arg0, UArg arg1)
    {
        Semaphore_Handle mdnsSem;
        Clock_Handle mdnsClock;
        Clock_Params clockParams;
    
        mdnsSem = Semaphore_create(0, NULL, NULL);
        Clock_Params_init(&clockParams);
        clockParams.arg = (UArg)mdnsSem;
        clockParams.period = MDNSPERIOD_IN_TICKS;
        clockParams.startFlag = TRUE;
        mdnsClock = Clock_create(Semaphore_post, MDNSPERIOD_IN_TICKS, &clockParams, NULL);
    
        while (TRUE) {
            Semaphore_pend(mdnsSem);
            mDNSSend(0);
        }
    }
    

    Mark

    Void mDNSSendTask(UArg arg0, UArg arg1)

  • Hi Mark,

    Thanks for the great answer and quick response!

    Glenn.