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.

Compiler/TM4C1294NCPDT: TM4C: Is timer construct and function treated as TASK, correct, so it okay to run a semp.

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI C/C++ Compiler

Timer_Params timerParams;
Timer_Params_init(&timerParams);
timerParams.periodType = Timer_PeriodType_MICROSECS; // Period in uSec (default)
timerParams.runMode = Timer_RunMode_CONTINUOUS; // Continuous Run (default)
timerParams.startMode = Timer_StartMode_AUTO; // Auto Start
timerParams.period = 1000; // 1000 uSecs = 1ms
Timer_construct(&LED_timer0Struct, Timer_ANY, (Timer_FuncPtr)RFD_LED_TimerFxn, &timerParams, NULL);
----------------------------------------------------------------------------------------------------------------------------

http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/sysbios/6_41_02_41/exports/bios_6_41_02_41/docs/cdoc/ti/sysbios/knl/Semaphore.html#pend 

In the context table, I'm correct to classified above as TASK and therefore safe to post semp in timer event function?

I getting missed semp execution every 1mSec because the binary count is 1. How to isolate why the binary count is stuck 1 and does not goes to 0 when it loop back to pend.  Should I use reset before post?

Even with timeout set to 10 in semp post below, it did not work, am I missing something?

----------------------------------------------------------------------------------------------------------------------------
void RFD_Sem_Task_System(UArg arg0, UArg arg1)
{
while (1)
{
Semaphore_pend(RFD_System_sem_handle, 10); // Every 1mSec Event via RFD_LED.c/h 1mSec timer. Also 10mSec to ensure it reset to 0.
if (zSTCFlag.AppState != eAPP_STANDBY) //-------------Application Manager
{
RFD_System_AppState();
}
if (zSTCFlag.DebugState != eDBG_STANDBY) //-------------Debug Manager (Test Mode)
{
RFD_System_DebugState();
}
if (zSTCFlag.RCVState != eRCV_STANDBY) //-------------ADC24 and RCV Manager,
{
RFD_System_RCVState();
}
// if (SysTick1Sec==1)
// {
// }
}
}
----------------------------------------------------------------------------------------------------------------------------
Void RFD_LED_TimerFxn(UArg arg) { ...... ......LED seq function code (no HWI/SWI call/post from here). ...... Semaphore_post(RFD_System_sem_handle); }

  • Hi Richard,

    Timer functions are ran in the context of a Hwi (not a Task). However, you can call Semaphore_post from any thread type. You cannot call Semaphore_pend from a Hwi or Swi with a non-zero timeout.

    Regarding the missing action. First confirm your timer is running every 1 ms. I expect your task is getting starved out for short periods of time and so the Semaphore_post is being called twice (but staying at 1 since it is a binary semaphore) before the task can run. You can enable kernel logging to see the execution graph. You need to enable kernel logging (BIOS.assertsEnabled = true;) and set up some loggers (var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');) in the .cfg file. You can then pause the target when you think the situation has occurred and open Tools->RTOS Analyzer->Execution Graph.

    Sidenote: since, by default, the Clock module has a 1ms timer, why not use that instead of a new dedicated timer? Of course, the dedicated timer will give you exactly 1ms granularity as ~1ms since other things are done in the context of the Clock tick (call other Clock functions, make ready tasks as needed, etc.).

    Todd

  • It needs to be stable accurate 1mSec.

    However when I use semaphore timeout with 10, then I do not need a timer in HWI to fire the semaphore where it can self fire itself. The simple solution is to remove the semaphore post from the timer code.

    Is this right approach?

  • Hi Richard,

    What exactly are you trying to do? You could simply use Task_sleep in RFD_Sem_Task_System(). In this case, you don't need the semaphore or the Timer instance since the sleep is based off the Clock modules timer. 

    Todd

  • Thank for the suggestion about Task Sleep, however, I do have other semp post from command interface from other part of code so I leave semp pend, (but again that can be further changed)

    This loop code is part of the operation sequencer which now runs every 10mSec checking flag to process application tasks. 

    It now running correctly when I remove semp post in HWI code, it indeed a mistake. 

  • I little confused about HWI and SEMP (TASK)

    I have GPIO interrupt callback, are they HWI?, if so this means I cannot post a SEMP, right?, how to post SEMP from GPIO event?

    I do have GPIO interrupt callback that post semp, it has BIOS_WAIT_FOREVER on Semp pend statement. It seems to work fine. 

  • Richard, are you trying to dispatch your action every 10mS?

    If so, and in the likely event you have not run out of hardware timers, might I suggest you use an actual timer rather than a software timer? That will give you stability close to the microprocessor clock stability.

    Also it is conventional wisdom that 1mS produces too high an overhead for the clock. That's a your milage may vary situation though and should be less of an issue on most ARM cores than smaller processors.

    Robert

  • Yes, 1mSec come from Timer4 I deleted the Semp post from there, it was a mistake. This is accurate for 1msec tick number to measure the performance of the system and LED sequencer. 

    The sequencer task body now run 10mSec via Semp pend timeout every 10 mSec which is good enough. I could use spare timer and run 10mSec this way rather than Semp or Task_Sleep. Should I do that?

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

    So GPIO interrupt (and timer interrupt?) is permitted to use Semp Post because they not HWI, correct?

    Below is a callback example (about 30mSec event)

    void RFD_AD7175_RCV1_DataReadyFx(unsigned int index)
    {
    //---------------------------------------Debug Timing
    GPIO_toggle(EK_PL4_EXP4_TIMINGPIN);
    //---------------------------------------
    GPIO_disableInt(EK_PQ1_SDI0_DRDY);
    Semaphore_post(RFD_RCV1_ADC24Data_sem_handle);
    //---------------------------------------Debug Timing
    GPIO_toggle(EK_PL4_EXP4_TIMINGPIN);
    //---------------------------------------
    }

  • richard payne said:
    could use spare timer and run 10mSec this way rather than Semp or Task_Sleep. Should I do that?

    I won't say should. It is an alternative. The advantage is a single interrupt every 10mS with accuracy as good as your crystal. The disadvantage is you are using another hardware interrupt. If your timing is tight though, it's a real alternative.

    richard payne said:
    So GPIO interrupt (and timer interrupt?) is permitted to use Semp Post because they not HWI, correct?

    If I understand the terminology used then it is a HWI. The interrupt will be restricted to a subset of RTOS functions normally. OTOH if you are doing small actions, like changing pin state then you can complete it entirely within the interrupt. Small is user defined.

    Robert

  • Richard,

    As I stated initially "However, you can call Semaphore_post from any thread type." So Semaphore_post can be called from an Hwi. Please refer to the "Calling Context" section in the API Reference Guide.