dansear wrote on Friday, July 27, 2007:
I recently encountered a bug in the handling of tasks.
A consequence of the bug causes ‘pxItemToRemove->pvContainer’
to be NULL in vListRemove(). I can detect the problem by
putting a test for ‘pxItemToRemove->pvContainer == NULL’
in that function.
The source of the bug is subtle, but I will try to describe
the situation. ARM platform. Several tasks exist, including
an idle task. The tasks that cause the problem loop around
doing some work and then call vTaskSuspend(NULL). An interrupt
is used to get the task going again, via xTaskResumeFromISR().
In my case, there are 2 tasks doing this, each has its own
interrupt for resuming.
The ‘work’ that the tasks perform include using a semaphore
to lock/unlock access to a resource.
So the task may be suspended two ways 1) at the vTaskSuspend(NULL),
and 2) waiting for the semaphore. The first does not have an ‘Event’
associated with it, but the second does (involving xPendingReadyList,
and xEventListItem).
The problem appears to be generated if the task is suspended on
the semaphore, with event, but the interrupt triggers a resume.
In my case, the interrupt occurs frequently, so it may happen
during the suspend for the semaphore lock. There is nothing in
xTaskResumeFromISR() that checks if the task is suspended waiting
on an event.
Since the task is suspended, waiting for an event, I believe
the ISR resume should be ignored… the event has not occured.
The following is my solution to accomplish that. In xTaskResumeFromISR()
change:
if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )
to:
if(( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )
&& (pxTCB->xEventListItem.pvContainer == NULL) )
This has solved my current problem with the NULL pointer getting into
vListRemove(), but I have to wonder if this is correct?
Dan Searles