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.

CC3200 Multiple Timer Lockup Using Power Management Framework

Other Parts Discussed in Thread: CC3200

****** UPDATE 01/12/2015 ******  THE CODE ANNOTATED BELOW ADDRESSES THE SYMPTOM OF AN UNDERLYING ISSUE AND SHOULD NOT BE USED.  PLEASE SEARCH FOR A NEW THREAD REGARDING CC3200 POWER MANAGMENT FRAMEWORK TIMER ISSUES.

Revision 2.0.  Was still having infinite loop issues.  Revised code with lines highlighted in green.

Please confirm the following is a bug or if I'm doing something wrong using the timers under the power management framework.

CC3200 running multiple timers under the power management framework has potential to lock up.

Configuration:   1st Timer = Periodic, 60 second

                          2nd Timer = Periodic, 10 second

Let them run until the 1st timer becomes the next to expire and the system has the potential to lock up.

Believe the issue is in cc_timer.c  function insert_ordered_expiry.  Source of issue is the linked list used to track the next timer to expire can become corrupt and result in the "while(node)" code being put in an infinite loop.  The end result is the application will lock up and never return.  Since this code may be executed as part of a hwi it has the potential to preempt virtually all other functions when running under an RTOS.

I have modified the code as follows and it appears to keep the linked list intact, however this has not been fully tested & debugged (or for that matter confirmed as the root of the issue).

static void insert_ordered_expiry(struct sw_timer *elem, struct sw_timer **list)

{

        struct sw_timer *node = *list, *prev = NULL;

 

        if(NULL == node) {  /* First user request for the  HW timer */

                *list = elem;

                elem->next = NULL;                                                                            //  DEBUG 10-24-2014 B01 ADD

                goto sort_insert_elem_exit1;

        }

 

        while(node) {        /* There is atleast one active request */

                if(0 > cmp_u64(&elem->hwt_expires, &node->hwt_expires)) {

                        /* 'elem' expires earlier than this 'node'  */

  if (node->next == elem) {                                 // DEBUG 10-27-2014 B02 ADD

           node->next = elem->next;                        // DEBUG 10-27-2014 B02 ADD

 }

                       elem->next = node;

                       

                        if(NULL == prev) {

                                *list  = elem; /* New first element */

                                set_scheduled(node, false);

                        }

                        else

                        {  /*  elem->next = prev->next;            */                        //  DEBUG 10-24-2014 B01 ADD     DEBUG 10-27-2014 DELETE

                                                                                                         //  should be equiv to assignment above so this probably is unnecessary

                                                                                                         //  above line is unnecessary and was removed

 

                            prev->next = elem; /* Intermediary  */

 

                        }                                                                                     //  DEBUG 10-24-2014 B01 ADD

 

 

                        /* 'elem' has been placed in 'list', quit.. */

                        goto sort_insert_elem_exit1;

                }

                 prev = node;

                node = node->next;

        }

         if(NULL == node)

        {                                                                                                                   //  DEBUG 10-24-2014 B01 ADD

              if (prev != NULL) {                                                                      //  DEBUG 10-24-2014 B01 ADD

                prev->next = elem; /* Farthest in time for schedule */

              } else {                                                                                         //  DEBUG 10-24-2014 B01 ADD

                     *list=elem;                                                                               //  DEBUG 10-24-2014 B01 ADD  This shouldn't ever happen

              }                                                                                                      //  DEBUG 10-24-2014 B01 ADD

             elem->next = NULL;                                                                                //  DEBUG 10-24-2014 B01 ADD

                                                                                                                             //  Believe above statement is where failure is.  Without this

                                                                                                                            //  it is possible for a circular reference to list to be created.

        }                                                                                                                   //  DEBUG 10-24-2014 B01 ADD

 

 sort_insert_elem_exit1:

        return;

}