Task List Implementation


I am trying to develop a debug script to list all the task names in the various task lists at any particular time, by using the ListItem_t->pxIndex->pvOwner to point to the TCB to get the required information

I noticed that memory is overlapping between two different task lists.

(gdb) p/x &pxReadyTasksLists[0]->pxIndex->pvOwner
$4 = 0x3ff01038
(gdb) p/x &pxReadyTasksLists[1]->uxNumberOfItems
$5 = 0x3ff01038
(gdb) p/x &pxReadyTasksLists[0]->uxNumberOfItems
$6 = 0x3ff01010
(gdb) p/x &pxReadyTasksLists[1]->pxIndex->pvOwner
$7 = 0x3ff01060
(gdb) p/x &pxReadyTasksLists[2]->uxNumberOfItems
$8 = 0x3ff01060
(gdb) p/x &pxReadyTasksLists[2]->pxIndex->pvOwner
$9 = 0x3ff01088
(gdb) p/x &pxReadyTasksLists[3]->uxNumberOfItems
$10 = 0x3ff01088

The data element uxNumberOfItems of any list is overlapping with pxIndex->pvOwner of the previous list. Note the address above, and this is consistent with all task lists
The impact is the variable pvOwner of list 0 is getting corrupted whenever the uxNumberOfItems of list 1 gets updated

While debugging I came across this code snippet in list.c:void vListInitialise( List_t * const pxList )

pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */

Here we are trying to map a 24 bytes structure onto a 40 byte structure and hence the memory overlap

I want to know why we are doing this, apart from the savings in terms of RAM Memory, and how should I accomplish my task at hand. What other areas this could impact and how ?

I’m not 100% sure I’m answering your question, but until recently the list item used to mark the end of a list was a MiniListItem_t structure. That saved memory, which may be important, especially on 8, 16 or smaller 32-bit systems. Having the same pointer point to both ListItem_t and MiniListItem_t generates warnings with some compiler options though - so recently the configUSE_MINI_LIST_ITEM constant was introduced so developers can choose to mark the end of a list with either a ListItem_t or a MiniListItem_t structure.

The uxTaskGetSystemState() API function demonstrates how to provide information on every task in the system. uxTaskGetSystemState() calls prvListTasksWithinSingleList(), which demonstrates how to walk a single list.

Funny, my initiation post to this forum was the almost identical question:

Problem with array bounds for pxReadyTasksLists (FreeRTOS 8.2.x) - Kernel - FreeRTOS Community Forums

In my case it turned out to be a subtle interrupt priority problem that corrupted the list. In a functioning system, the overlap would never be an issue.

Welcome to the forum!