Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Infinitive loop -> last event list it...

Posted by Alexander on 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_PRIORITY0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY5


- 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[ADCUNIT0].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

RE: Infinitive loop -> last event list it...

Posted by Dave on August 30, 2012
The line

xSemaphoreGiveFromISR( HndlBufSwitch[ADCUNIT0].mutDeviceLock, xHigherPriorityTaskWoken );


should be

xSemaphoreGiveFromISR( HndlBufSwitch[ADCUNIT0].mutDeviceLock, &xHigherPriorityTaskWoken );


(note the addition of the '&')

RE: Infinitive loop -> last event list it...

Posted by Alexander on August 30, 2012
Hi Dave,

thanks for your reply.

It's just a copy-paste error.

In our code we use a define for calling xSemphoreGiveFromISR:


#define ADC_WAKE( handle, taskwoken )\
xSemaphoreGiveFromISR( handle, &taskwoken )


so the call is:



ADC_WAKE( HndlBufSwitch[ADCUNIT0].mutDeviceLock, xHigherPriorityTaskWoken );

RE: Infinitive loop -> last event list it...

Posted by Alexander on August 30, 2012
Some information I forgot to post:

We are using:
FreeRTOS V7.1.1 / Eclipse + IAR-Toolchain.

RE: Infinitive loop -> last event list it...

Posted by Dave on August 30, 2012
Have a look at this similar thread that discusses a lot of things before eventually coming to a conclusion.
http://sourceforge.net/projects/freertos/forums/forum/382005/topic/5574717

does it help?

RE: Infinitive loop -> last event list it...

Posted by Alexander on August 31, 2012
Hi Dave,

sorry but I can not see a direct relation between this thread and our problem.

Regards
Alex

RE: Infinitive loop -> last event list it...

Posted by Richard on August 31, 2012
...its nice to have a support request from somebody who has already put some effort in themselves, rather than just expecting a magic answer from a vague question. The fact that you have already tried these things means it is harder to find a starting point, as normally the starting point is to ask people to do the things you already seem to have done. We are yet to have a similar support request that we have not eventually been able to find the answer to yet though...so here goes.

From your original post, I presume you have seen these pages already. I will post links all the same, mainly for other people viewing this thread:

http://www.freertos.org/FAQHelp.html
http://www.freertos.org/RTOS-Cortex-M3-M4.html

+ Can you post the code for your ADC_LOCK_BUFFER() and ADC_UNLOCK_BUFFER() macros. I'm guessing they map to the semaphore take/give functions, but would like to see them.

+ Why is ADC_LOCK_BUFFER() needed if you are also using a critical section?

+ What else is accessing the buffer that the critical section is protecting?

+ What is the frequency at which HndlBufSwitch[ADCUNIT0].mutDeviceLock is given by the ISR?

+ Do you ever change the global interrupt enable bit, or the BASEPRI registers in any way other than calling taskENTER_CRITICAL() and taskEXIT_CRITICAL()?

+ Do you ever call the portSET/CLEAR_INTERRUPT_MASK_FROM_ISR() functions macros manually (rather than by calling an API function that uses them)?

Regards.

RE: Infinitive loop -> last event list it...

Posted by Alexander on August 31, 2012
Richard,

thanks for your reply.

Here the answers to your questions:


+ Can you post the code for your ADC_LOCK_BUFFER() and ADC_UNLOCK_BUFFER() macros. I'm guessing they map to the semaphore take/give functions, but would like to see them.


[code
]#define ADC_LOCK_BUFFER( handle, delay )\
xSemaphoreTake( handle, (delay / portTICK_RATE_MS) )

#define ADC_UNLOCK_BUFFER( handle )\
xSemaphoreGive(handle);



+ Why is ADC_LOCK_BUFFER() needed if you are also using a critical section?


There is a user task reading from this buffer. So we lock the buffer to avoid a double access.


What is the frequency at which HndlBufSwitch[ADCUNIT0].mutDeviceLock is given by the ISR?


The task from the code example is started at a freqeuncy of 6Hz by the ISR.

There are 3 tasks using this mechanism.
The frequencies are 6Hz (code example), 62Hz and 1kHz.


+ Do you ever change the global interrupt enable bit, or the BASEPRI registers in any way other than calling taskENTER_CRITICAL() and taskEXIT_CRITICAL()?


We do not touch this register and do not change the global interrupt enable bit.


+ Do you ever call the portSET/CLEAR_INTERRUPT_MASK_FROM_ISR() functions macros manually (rather than by calling an API function that uses them)?


We never call this function manually.

Best regards and have a nice weekend.
Alex

RE: Infinitive loop -> last event list it...

Posted by Richard on August 31, 2012
That all sounds ok so far.

As an aside:

“The frequencies are 6Hz (code example), 62Hz and 1kHz.”


1Khz is a high frequency to give a semaphore to a task. I'm not sure what your tick frequency is, but if it is high then this task is going to run in nearly every time slice, leaving only a partial amount of the time slice for other tasks. You might consider performing that processing in the interrupt itself, if that is at all possible, rather than deferring it to a task. This comment is probably not relevant to the issue you are reporting though.

The problem you describe is almost certainly due to data corruption, it's a matter of finding out what is doing the corrupting. Crudely speaking, you can split that into two: Mis-use of the kernel or CPU setup (as per the pages already linked above, and I think you see to have that covered), or a user application mis-behaving. There is also the option of a problem in the kernel itself, of course, I'm not dismissing that - but from all the support requests handled so far, none have arisen from the kernel itself (yet).

I'm not sure what to suggest next, but will ask a few more questions to see if something drops out of the discussion.

You have stated the interrupt priorities already, and I have checked that the device does indeed have 4 priority bits, but could you please also post the configMAX_SYSCALL_INTERRUPT_PRIORITY setting (rather than the "LIBRARY" version), and the code used to set the priority of each interrupt you are using.

Regards.

RE: Infinitive loop -> last event list it...

Posted by Alexander on August 31, 2012

1Khz is a high frequency to give a semaphore to a task.

Thanks for the recommendation. I was already talking about this with my college.

The configMAX_SYSCALL_INTERRUPT_PRIORITY should be 80.

/* The lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Priority 5, or 160 as only the top three bits are implemented. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )


The code we are using to set the priority is:

static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
}


Regards
Alex

RE: Infinitive loop -> last event list it...

Posted by Alexander on August 31, 2012
The definition of the PRIO_BITS is this:

#define __NVIC_PRIO_BITS 4 /* FM3 uses 4 Bits for the Priority Levels */


#define configPRIO_BITS __NVIC_PRIO_BITS

RE: Infinitive loop -> last event list it...

Posted by Richard on August 31, 2012
That all looks like standard stuff - I will have to think on the next thing to suggest.

Is it possible you could zip up your entire working directory and send it to me? If so, include all the project files and source files, and make sure it will build when the project is moved to a different directory (it doesn't have any absolute paths in it) and send it to r _dot_ barry _at_ freertos.org.

Regards.

RE: Infinitive loop -> last event list it...

Posted by Richard on September 3, 2012
Do you have run time stats enabled? If so, try setting configGENERATE_RUN_TIME_STATS to 0 in FreeRTOSConfig.h to see if that fixes your problem. If it does, then the issue is probably due to an error in the example run time stats gathering code in the original demo file (although it has been fixed in more recent versions). It is a one line change I can show you.

Please let me know.

Regards.

RE: Infinitive loop -> last event list it...

Posted by Alexander on September 3, 2012
Hi Richard,

I just send you a mail with our project source code. Probably it will take some time before you get it, because we have some problems with our server in the moment.

configGENERATE_RUN_TIME_STATS is set to 0.

Regards,
Alex

RE: Infinitive loop -> last event list it...

Posted by Alexander on September 13, 2012
Hi Richard,

we are using a timer interrupt at a high priority of 1. The timer service routine does not use any api call. The frequency of the timer interrupt is about 25Hz. Could this cause the kernel to crash?
If we change the priority to 5 (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY) everything seems to work fine.

Regards,
Alex

RE: Infinitive loop -> last event list it...

Posted by Alexander on September 18, 2012
Hi Richard,

we solved our problem. It was a stupid system call in our high prior timer service routine. He was hidden in a callback function which we ignored.

Thanks for your support. Your kernel works great!

Best regards
Alex


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS