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: Hanging in TI RTOS functions "Clock_walkQueueDynamic()"

Part Number: CC1310

Tool/software: TI-RTOS

Hello All,

my programm always ends in the TI Rtos function "Clock_walkQueueDynamic" and it does not react on other SWI's. I do not have an idea, why this happens. Does anybody can help?

Some Informarion

CCScreenshot:

Here is also a ROV Screenshot which may help.

BR and thanks in advanced,

Noge

  • OK I will look why the screenshot didn't work.
    BR Egon
  • OK. here is (hopefully)

    the CCS Screenshot:

    ROV Info:

  • OK, ones more:

    Ok. Hopefully someone can help me now.
    BR Egon

  • Hi Egon,

    Could you share some code showing how you setup the timers in your application? it seems you have 3 timers sharing the same callback function, is this the case?
  • Hi M-W,

    yes this is true. May this be a Problem?

    Here you can see the construction of the clocks:

      /* Construct clock for App- and TT-Interval */

        Clock_Params clockParams;
        Clock_Params_init(&clockParams);
        clockParams.arg = (UArg)WAKEUP_SOURCE_SLEEPTIMER_APPL;
    //    clockParams.period = 10000000/Clock_tickPeriod;   // 10s (10Mio us)   --> kann später mit Clock_setPeriod(handle, intervall[us]/Clock_tickPeriod); noch geändert werden
        Clock_construct(&AppClock, wakeupCb, 0, &clockParams);
        hAppClock = Clock_handle(&AppClock);
    
        clockParams.arg = (UArg)WAKEUP_SOURCE_SLEEPTIMER_TT;
    //    clockParams.period = 10000000/Clock_tickPeriod;   // 10s (10Mio us)   --> kann später mit Clock_setPeriod(handle, intervall[us]/Clock_tickPeriod); noch geändert werden
        Clock_construct(&TTClock, wakeupCb, 0, &clockParams);
        hTTClock = Clock_handle(&TTClock);
    
               Clock_Params clockParams;
               Clock_Params_init(&clockParams);
               clockParams.arg = (UArg)WAKEUP_SOURCE_SLEEPTIMER_PROTOCOLL;
               Clock_construct(&HopClock, wakeupCb, (uint32)ui16SleepProtocoll*1000/Clock_tickPeriod, &clockParams);
               hHopClock = Clock_handle(&HopClock);
               Clock_start(hHopClock);
    

    And the general Timer, I think the clocks derive from a GPT.

    /*
     *  ============================ GPTimer begin =================================
     *  Remove unused entries to reduce flash usage both in Board.c and Board.h
     */
    /* Place into subsections to allow the TI linker to remove items properly */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_SECTION(GPTimerCC26XX_config, ".const:GPTimerCC26XX_config")
    #pragma DATA_SECTION(gptimerCC26xxHWAttrs, ".const:gptimerCC26xxHWAttrs")
    #endif
    
    /* GPTimer hardware attributes, one per timer part (Timer 0A, 0B, 1A, 1B..) */
    const GPTimerCC26XX_HWAttrs gptimerCC26xxHWAttrs[HWDEF_GPTIMERPARTSCOUNT] = {
        { .baseAddr = GPT0_BASE, .intNum = INT_GPT0A, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT0, .pinMux = GPT_PIN_0A, },
        { .baseAddr = GPT0_BASE, .intNum = INT_GPT0B, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT0, .pinMux = GPT_PIN_0B, },
        { .baseAddr = GPT1_BASE, .intNum = INT_GPT1A, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT1, .pinMux = GPT_PIN_1A, },
        { .baseAddr = GPT1_BASE, .intNum = INT_GPT1B, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT1, .pinMux = GPT_PIN_1B, },
        { .baseAddr = GPT2_BASE, .intNum = INT_GPT2A, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT2, .pinMux = GPT_PIN_2A, },
        { .baseAddr = GPT2_BASE, .intNum = INT_GPT2B, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT2, .pinMux = GPT_PIN_2B, },
        { .baseAddr = GPT3_BASE, .intNum = INT_GPT3A, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT3, .pinMux = GPT_PIN_3A, },
        { .baseAddr = GPT3_BASE, .intNum = INT_GPT3B, .intPriority = (~0), .powerMngrId = PowerCC26XX_PERIPH_GPT3, .pinMux = GPT_PIN_3B, },
    };
    
    /*  GPTimer objects, one per full-width timer (A+B) (Timer 0, Timer 1..) */
    GPTimerCC26XX_Object gptimerCC26XXObjects[HWDEF_GPTIMERCOUNT];
    
    /* GPTimer configuration (used as GPTimer_Handle by driver and application) */
    const GPTimerCC26XX_Config GPTimerCC26XX_config[HWDEF_GPTIMERPARTSCOUNT] = {
        { &gptimerCC26XXObjects[0], &gptimerCC26xxHWAttrs[0], GPT_A },
        { &gptimerCC26XXObjects[0], &gptimerCC26xxHWAttrs[1], GPT_B },
        { &gptimerCC26XXObjects[1], &gptimerCC26xxHWAttrs[2], GPT_A },
        { &gptimerCC26XXObjects[1], &gptimerCC26xxHWAttrs[3], GPT_B },
        { &gptimerCC26XXObjects[2], &gptimerCC26xxHWAttrs[4], GPT_A },
        { &gptimerCC26XXObjects[2], &gptimerCC26xxHWAttrs[5], GPT_B },
        { &gptimerCC26XXObjects[3], &gptimerCC26xxHWAttrs[6], GPT_A },
        { &gptimerCC26XXObjects[3], &gptimerCC26xxHWAttrs[7], GPT_B },
    };
    
    /*
     *  ============================ GPTimer end ===================================
     */
    

    BR,
    Noge

  • You should be OK using the same CB for all of the objects, have you checked in this case if this CB is called in this case, or stepping through the queue to see what it is doing (I assume something is triggering an CB).

    Regarding GPTImer, this is not used for the Clock module, this is based on-top of the Timer module which wraps the RTC.
  • Hi M-W,
    in the case, the systems hangs in the knl_Queue... it seems that no other interrupt is accepted, whether one of the other clocks, nor the PIN interrupt. In the ROV screenshot, you can see, that the PIN_swi is posted, but no callback function is called.
    BR Noge
  • Hi Noge,

    That makes sense, as you are currently in a Swi of higher priority then other Swis. What can you find out by single stepping over the ISR function?

    Looking closer at it, what is your expectations of:

    Clock_Params clockParams;
    Clock_Params_init(&clockParams);
    clockParams.arg = (UArg)WAKEUP_SOURCE_SLEEPTIMER_APPL;
    // clockParams.period = 10000000/Clock_tickPeriod; // 10s (10Mio us) --> kann später mit Clock_setPeriod(handle, intervall[us]/Clock_tickPeriod); noch geändert werden
    Clock_construct(&AppClock, wakeupCb, 0, &clockParams);
    hAppClock = Clock_handle(&AppClock);

    When do you start it and do you give it a period before you do?
  • Hi M-W,

    what I can say to the swi, th function UInt32 Clock_walkQueueDynamic(Bool service, UInt32 thisTick) is not left by return, the firmware always run into the function. But I do not know which module / swi it is, because I newer come out. I had a look at our board file, but I do not have a module with a swi priority of 5.

    To the clocks, yes period and timeouts are set at other different places on the application. and also starting the clocks.

    Do you know, if it is a SWI of the knl which runs on priority 5?

    BR,
    Egon

  • Hi Noge,

    It is called from the Clock_workFuncDynamic function, which is running in a priority 5 Swi (the clock module always run with a Swi at the highest priority).

    Clock_walkQueueDynamic() should call a callback bound to the clock object on the "obj->fxn(obj->arg);" line, is this the case?

    You can also check in Clock_workFuncDynamic, what it sets skippable and nextTick to be (you should also be able to use "serviceTick" to link to what clock object is causing this four you. An alternative, if possible, is to also disable one of your three clock objects one by one to see which one is causing this.
  • Hi M-W,

    the "obj->fxn(obj->arg);" is not called. The condition if (obj->active == TRUE) { ...} always stays false.
    What you said about the Void Clock_workFuncDynamic(UArg arg0, UArg arg1) function, I cant follow you, because the firmware dont come back to it.
    Here there is a screenshot of it


     

    BR,
    Noge

  • Hi M-W,

    there is no callback function called from  obj->fxn(obj->arg);. The condition  if (obj->active == TRUE) {...} in the UInt32 Clock_walkQueueDynamic(Bool service, UInt32 thisTick) is always false and it does not return from this function. How to check/link  the  ServiceTick, I canot follow you.

    here is a new creenshot from the Void Clock_workFuncDynamic(UArg arg0, UArg arg1) 

    What I could see, the trouble is caused from my last clock instance I created. and it is done like this:

               Clock_Params clockParams;
               Clock_Params_init(&clockParams);
               clockParams.arg = (UArg)WAKEUP_SOURCE_SLEEPTIMER_PROTOCOLL;
               Clock_construct(&HopClock, wakeupCb, (uint32)ui16SleepProtocoll*1000/Clock_tickPeriod, &clockParams);
               hHopClock = Clock_handle(&HopClock);
               Clock_start(hHopClock);
    

    Is there anythin wrong?

    BR,

    Noge

  • Hi Noge,

    I don't see a direct issue with your setup, could you share what "ui16SleepProtocoll" is set to as well as which clock handle it is (so that it can be matched with the ROV view).
  • Hi M-W,
    the clock, which causes troubles has the handle 0x20001e20. The ui16SleepProtocoll is always set with 154 (ms).
    BR Noge
  • Hi Noge,

    I'm not able to directly see what would cause this, could you have a look at the stacks of the system to see if there might be something strange going on here?

    Also, would it be possible for you to share this project (or smaller project re-creating this) with me?
  • Hi M-W,

    Sharing the project will be difficult, because it is confidential information. Part of it may work. But before I will try to have a look at the stack. I used the Stack usage tap of the CCS, but it remaisn empty, Why?

    Her please see my screenshot:

    BR Noge

  • Hi Noge,

    The stack usage guide will not help you in this case. What you can do is to observe the task stacks using the ROV, making sure they have not overflowed. You can also look at the Hwi stack if this still holds.

    Note that the best way to know if the stack is intact is to use the memory address specified in ROV and browse it using the memory viewer. There should be padding bytes in the end of the stack (0xBEBE). If you don't find these paddings, it is likely that the stack has overflowed.
  • Hi M-W,

    See my screenshot:

    What do you think, it seems the stack is empty, but once was filled up to the address 0x20001094. Is the stack mok, or has there been an overflow?
    BR Noge

  • Hi Noge,

    That stack looks fine, you got plenty of padding left. Judging from the tasks, it seems that this occurs early in your program, is this correct?

    For the sake of it, does this happens only for this clock or can you see that it is related to the number of clocks in your case? In other words, if you take away another clock object, will it run or is it the same?
  • Hi M-W,
    I took away one clock object, and it is still the same. Any Idea?
    BR Noge
  • Hi Noge,

    There is nothing wrong with how you use the clock object itself, I suspect there is some nasty memory failure going on affecting your clock module. As all the active clocks have an ridiculous high "tRemaining", the module must be off as this should be close to the delta between the clock objects "currTimeout" and the modules "ticks". You can find these numbers by changing to "Raw" view in the ROV.

    You can also find the address of the clock module, which means you could put a memory watch point to try catch when/if this value goes astray. As this seams to happen early in you program, it makes no sense that the "tRemaining" is a value that close to the 32-bit limit.

    Could you maybe also share what you are doing in the callback?
  • Hi Noge,

    Do you have an update on this issue?
  • Hi M-W,

    I was on a sick leave, so some time passed. But now I'm back on work.  So let' focus on the clock module.

    here you can see the actual ROV:




    Actual I do not know what is messed up in  the clock module.

    Here I can give you the Callback functions:

    void wakeupCb(UArg arg)
    {
        unsigned short wakeupsource = (unsigned short) arg;
    
    //    if( wakeupsource == WAKEUP_SOURCE_PORT )  // Wakeup by Port       //##pw 2017_07_03 anstatt generell für alle Ports die WS, wird nun einzeln unterschieden (je nach Key)
        if( wakeupsource == WAKEUP_SOURCE_SLEEPTIMER_APPL )    // Wakeup by Appl-Timer
        {
            // spezieller Code im Falle Wakeup durch App-Intervall
            // zuerst findet die Sonderbehandlung für ein sehr langes Intervall statt (>~11,9h), damit wir danach sichergehen können, dass das Intervall auch tatsächlich vollständig abgelaufen ist...
            UInt32 ticksFor1s = 1000000/Clock_tickPeriod;   // Zeit für 1s
            UInt16 maxSPeriod = ((UInt32)0xFFFFFFFF)/ticksFor1s;    // max. mögliche Anzahl von Sekunden die in einer Periode Platz finden (Achtung: max. liegt bei 42.949 Sekunden (~11,9h), theoretisch können aber 65.535 eingegeben werden...)
    
            if( SleepLoopMaxAppl > maxSPeriod ) // das App-Intervall ist länger als die max. mögl. Sekunden die in der Periode Platz finden (32bit Wertebereich, aber 1 Tick pro 10us!)
            {
                Clock_stop(hAppClock);
                if (SleepLoopMaxAppl >= SleepLoopCounterAppl)
                {
                    if( (SleepLoopMaxAppl - SleepLoopCounterAppl) <= maxSPeriod )   // das war der letzte Durchlauf
                    {
                        SleepLoopCounterAppl = 0;
                        Clock_setTimeout(hAppClock, maxSPeriod * ticksFor1s);
                    }
                    else    // es sind weitere Durchläufe nötig
                    {
                        wakeupsource = 0;   // da gesamtes Intervall noch nicht abgelaufen ist, auch noch kein Wakeup-Handling
                        SleepLoopCounterAppl += maxSPeriod;
                        if( (SleepLoopMaxAppl - SleepLoopCounterAppl) < maxSPeriod )    // es bleibt nur mehr ein Rest (letzter Durchlauf bis Wakeup)
                        {
                            Clock_setTimeout(hAppClock, (SleepLoopMaxAppl - SleepLoopCounterAppl) * ticksFor1s);
                        }
                        else    // oder noch mind. eine ganze maxPeriode
                        {
                            Clock_setTimeout(hAppClock, maxSPeriod * ticksFor1s);
                        }
                    }
                    Clock_start(hAppClock);
                }
                else
                {
                    System_printf("Callback overflow%x \n",WakeUpSource);
                }
            }
            if( wakeupsource )  // Zeug für Intervall nur machen, wenn es auch wirklich abgelaufen ist...
            {
                // Wichtig: hier darf nichts blockierendes gemacht werden (wir sind im IRQ-Handler!)
            }
        }
        else if( wakeupsource ==  WAKEUP_SOURCE_ULP)  // Wakeup by TT-Timer
        {
        }
        else if( wakeupsource ==  WAKEUP_SOURCE_SLEEPTIMER_PROTOCOLL)
        {
            ui8RF_State = RF_WAKEUP;
        }
        if( wakeupsource )  // durch Sonderbehandlung kann ev. noch verhindert werden, dass wirklich das Wakeup durchkommt
        {
            WakeUpSource |= wakeupsource;
    #ifndef DEBUG_SLEEP
            //Task_getMode();
            Semaphore_post(hWakeupSem); // Tasks die auf diese wakeupSem warten, werden aufgeweckt
            //
    #endif
    #ifdef SYSTEM_PRT
            System_printf("Wakeup CB %x \n",WakeUpSource);
    #endif
        }
    }
    
    void clk_CallBk(UArg arg)
    {
        ui8RF_State = RF_WAKEUP;
        WakeUpSource = arg;
        Semaphore_post(hWakeupSem);
    }
    

    Any Ideas how to gon on?
    BR Noge

  • Hi Noge, welcome back.

    Unfortunately, it is very hard to say what could be wrong in your case. If you would be able to share a project that re-produces the issue so that I can debug it, I could possibly help you figuring this out a lot sooner (either here or in private).

    As for the Raw clock view, what is the value of the "Clock module" variables (the once at the top, for example "nextScheduledTick") when you have the hiccup inside the walk function?

    Also, as the callback is rather big, have you made sure that both the System stack and tasks stacks are intact? You can find info on the "System stack" if you look under "Hwi" in ROV and select "Raw" view.