waalex wrote on Thursday, August 30, 2012:
In our application we get stuck at the well known line
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
in the file list.c.
We are using a Fujitsu Cortex-M3 Processor (mb9bf506r) for our application. Since this problem is well known and discussed (especially with Cortex-M3 Processors) we checked the following points.
- We could not detected any stack overflow.
- We checked our interrupts priorities. The interrupts using api calls are running with a priority of 0xf, just one is running at a priority of 0xA
#define configPRIO_BITS 4
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
- We also checked our code for api calls within a critical section.
- To avoid interrupts firing before the scheduler has started, we start our drivers and application in a start-up task.
In our application we are synchronizing several tasks, with the corresponding driver ISR’s using binary semaphores. For each single synchronization there is just one sync task and just one ISR to take and give back the binary semaphore.
Below a code example:
//ADC0 ISR
void ADC0_IRQHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
//Do some driver specific stuff.
xSemaphoreGiveFromISR( HndlBufSwitch[ADCUNIT0].mutDeviceLock, xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
//Sync Task
static void _ADC0_BufferSwitch_Task( void *pvParameters )
{
static boolean_t bSwitchBuf = FALSE;
xSemaphoreTake( HndlBufSwitch[ADCUNIT0].mutDeviceLock, 0 );
for( ;; )
{
#ifdef ADC_DEGUB
adc0switchstack = uxTaskGetStackHighWaterMark( NULL );
#endif
/* Wait for BufferSwitch event */
xSemaphoreTake( HndlBufSwitch[ADCUNIT0].mutDeviceLock, portMAX_DELAY )
/* Lock semaphore */
if( ADC_LOCK_BUFFER( ADC_Unit[ADCUNIT0].Mutex.mutDeviceLock, 1 /*ms*/ ) == pdTRUE )
{
/* CRITICAL SECTION:
/*+++++++++++++++++++++++++++++++++++++++++*/
taskENTER_CRITICAL();
/* Switch buffer */
if( !bSwitchBuf )
{
ADC_Unit[ADCUNIT0].BufferBusy = ADC_Unit[ADCUNIT0].Buffer1;
ADC_Unit[ADCUNIT0].BufferReady= ADC_Unit[ADCUNIT0].Buffer0;
bSwitchBuf = TRUE;
}
else
{
ADC_Unit[ADCUNIT0].BufferBusy = ADC_Unit[ADCUNIT0].Buffer0;
ADC_Unit[ADCUNIT0].BufferReady= ADC_Unit[ADCUNIT0].Buffer1;
bSwitchBuf = FALSE;
}
taskEXIT_CRITICAL();
/*+++++++++++++++++++++++++++++++++++++++++*/
/* Unlock semaphore */
ADC_UNLOCK_BUFFER( ADC_Unit[ADCUNIT0].Mutex.mutDeviceLock );
}
/* Wait for pt100 voltage is stabilized */
vTaskDelay( 1 );
/* Clear fifo */
ADC_Unit[ADCUNIT0].Handle->SCCR_f.SFCLR = 1;
/* Restart conversion */
ADC_Unit[ADCUNIT0].Handle->SCCR_f.SSTR = 1;
}
}
Our application runs sometimes for a day or more and sometimes just for few hours. When the application gets stuck, we see that the last call came from one of our sync tasks trying to take the semaphore (“xSemaphoreTake( HndlBufSwitch.mutDeviceLock, portMAX_DELAY )”). Also we notice, that there is at least one task (same task which is calling) waiting in the event list which does not point to the list end item (instead it points to itself).
How could this happen and how can we avoid it?
Thanks in advance.
Best regards.
Alex