freertos hanging on vListInsert (again)

marcabramson wrote on Friday, November 06, 2015:

my code blocks in the line
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. /
/); pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */

of vListInsert funciton .
I HAVE read carefully the comment and:
-I’m nor using Cortex M3
- I’m not using interrupt (except the timer interrupt for the context switch) so the functionFromIsr don’t need to be called
- I have checked the stack overflow
- I’m not using a queue or semaphore before it has been initialised or before the scheduler has been started

What I have is
-3 task, with the same priority

  • one of them waiting with a vTaskDelay
  • one of them waiting for a semaphore

anyway looking to the following comment in the code
/* However, if the xItemValue is the same as the back marker
the iteration loop below will not end. Therefore the value is checked
first, and the algorithm slightly modified if necessary. */

I can see that I’m in this case
But I can also not the see how this case is handled in the code, and how the algoirhm is sliglty modified.

So, I did the following modification, replacing
if( xValueOfInsertion == portMAXDELAY )
pxIterator = pxList->xListEnd.pxPrevious;


pxIterator= ( ListItemt  ) &( pxList->xListEnd );
if ((xValueOfInsertion == portMAXDELAY )  || (xValueOfInsertion== pxIterator->pxNext->xItemValue))
	pxIterator = pxList->xListEnd.pxPrevious;

which does correspond (in my opinion) to the comment. Value of the back Marker is now compared first to the xitemValue

and after that, everything works 100% fine.

Any comment ?

rtel wrote on Friday, November 06, 2015:

I’m not sure I understand your modification, but that doesn’t matter, as that code is known to work, so if it is not working for you then something else is wrong - most likely a corruption of some of the structures used by the kernel.

You have said which port you are not using, but you have not said which port you are using, as far as I can see, so the obvious first question is: Which port are you using?

marcabramson wrote on Monday, November 09, 2015:

my target is a specific asic, based on ARM7 tdmi. I have started from portable/gcc/ARM7_lcp23xx0 but then I did my own port based on it. So, I did my own prvSetupTimerInterrupt function, based on my hardware.

rtel wrote on Monday, November 09, 2015:

Ok - as the ARM7 ports don’t support interrupt nesting, that removes a
lot of possibilities (the most common cause of this symptom these days
being incorrect interrupt priorities when nesting interrupts), but does
leave the question as to whether this is just a simple data corruption

On the ARM7 you have to set up stacks for supervisor mode, and IRQ mode,
have you done that? If so, are they big enough? FreeRTOS will only
check the stacks used by tasks (which are set up by FreeRTOS itself).
You don’t need to allocate any other stacks unless you are also using
FIQ mode.

marcabramson wrote on Monday, November 09, 2015:

yes, this is done. I have 32K for IRQ stack and 32K for supervisor mode.
please notice that this append only if I have 2 task with the same priority. Otherwise, anything works fine.
I will have a look again.

marcabramson wrote on Monday, November 09, 2015:

I did have a better look
the problem is that, when VlistInsert is called, what is inserted is already in the queue
in other world, we have
pxNewListItem ==( ListItem_t * ) &( pxList->xListEnd )->pxNext
I think this not correct
so, I looked why

it’s comming from the fact that my code is doing this

xSemaphoreHandle	cat_sema;
	cat_sema = xSemaphoreCreateCounting(1,1);
and then, after, 

this xSemaphoreTake does call vlistInsert twice for the same element
and the reason, for me, is in the XSempahoreTake , which is a macro for xQueueGenericReceive

xQueueGenericReceive is an endless loop
for (;:wink: (line 1383 for FreeRTOS V8.2.3)
with a first test
if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) (line 1389)
not my case since no message has been posted
then, a second test
if( xTicksToWait == ( TickType_t ) 0 ) (line 1868)
still not my case, xTicksToWait is set to portMAX_DELAY

then, next test is
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) (line 1499)
not expired, in my case, since it’s an infinite timeout so, code is entering the test

next test
if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) (line 1501)
Queue is empty since there are still no message waiting, so prvIsQueueEmpty does not return FALSE

so, code reach
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); (line 1522)
which does the current Task to the list of task waiting for this semaphore.

Up to now, everything is fine.

but then, code reach line 1547, which is the end of the for (;;:wink: from line 1383
so, the for is executed again… and everything append again. so, the line 1522 is done a SECOND time, again for the same task… and this time, it reach the case in the VlistInsert in which an element is inserted in a list which does already contains this element, which lead to the infinite loop.

can you comment ?
(if needed, can we discuss that privately instead of doing that in a public forum)

rtel wrote on Monday, November 09, 2015:

Once the task is added to the blocked list, and is no longer in the
running state, it should yield to another task. From your description I
would say that is not happening (the task continues executing), so
suspect you do not have the FreeRTOS yield handler installed as the
handler for SVC interrupts.

marcabramson wrote on Tuesday, November 10, 2015:

thanks. I’m using eclipse, and I’m moving from UCOS to FreeRtos. So, in my eclipse, there are ucos target and freertos target. and , in one of the FreerTos target, the boot.s used was still the ucos boot.s, and not the freertos boot.s… So, as you’ve suggested, swi handler was not correct… I have now corrected it and everything works fine. thanks again