****** 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;
}