xQueueGenericReceive problem with TCP/IP

fanlex wrote on Thursday, September 25, 2008:


I have a problem in xQueueGenericReceive : I’m using FreeRTOS 5.0.2 with the lwip layer (1.3.0) for TCP/IP, and wanted to use the mem_malloc function of lwip because that function is able to reassemble freed memory blocs (I have some problems due to the absence of that functionality with the heap2.c management).

The problem is: depending on which type of heap memory allocation I use, on a particularly fast TCP/IP connection from a web browser (there are 15 files referenced in the first index.html), the vTaskPlaceOnEventList() function is called twice in the same loop (do while ( xReturn == queueERRONEOUS_UNBLOCK ), not everytime.

This leads to a hang situation in vListInsert, as noticed by a recent topic from Szymansk on the forum, since the function tries to insert the same item twice in the list and there is no test on that situation in vListInsert.

My question is : why does the queueReceive function loop twice in a particular situation ? the queue is empty, the timeout is not elapsed, and the xReturn status is set to queueERRONEOUS_UNBLOCK before the ending while.

when using heap2.c for heap management, this does not happen. There is only one call to vTaskPlaceOnEventList(). But it’s not easy to debug, since there are calls to taskYIELD() into the function.

maybe one or the other heap management system is more or less fast than the other ?

Please can somebody help …

davedoors wrote on Sunday, September 28, 2008:

I cannot comment on the lwIP heap management, but it seems you are saying "when I use FreeRTOS.org code it works file, when I patch in third party code it stops". It could be as simple as the lwIP code is using much more stack memory.

queueERRONEOUS_UNBLOCK will occur when a task unblocks because of an event on a queue only to find that the reason for it unblocking is no longer present by the time the task actually gets to execute. Image a situation where you have a task that is blocked waiting for data on a queue. An interrupt posts to the queue and unblocks the task, but the task does not run because there is a higher priority task already running. Now if the higher priority task or even another interrupt removed an item from the queue, when the unblocked task eventually runs again it will find the queue already empty so it must return to the blocked state to wait for the rest of its block time.

fanlex wrote on Monday, September 29, 2008:

I’ll try to better understand how the queuereceive function works, but for the moment I don’t.

You are meaning that I can have 2 tasks of different priority waiting on the same queue ?

I think that executing the while loop twice should never occur (in a normal situation I have set a breakpoint on a second pass, but it never stopped), or at least the event should has been removed from the list before re-adding it in.

If it was a stack problem,maybe the program should have crashed …