you’ll find the analysis here. In a nutshell, FreeRTOS lists are organized such that the last list element does not have a payload, so trying to use it as a list element WITH a payload will result in looking at invalid memory. Thus, the condition “list length > 0” along with “the first list element is a terminator” is illegal.
Now how could it happen that a linked list has a length > 0 but consists of only the terminating element (that is, is empty)? Normally via missing atomicity. Operations that manipulate FreeRTOS lists must not be interruptible by other pieces of code that also manipulate the list; otherwise one thread of execution may change the list count but not be able to adjust the list itself accordingly.
That is a fairly reliable hint that there was no critical section in effect where there should have been one, because the critical section is the one FeeRTOS mechanism that ensures atomicity on the OS level.
In my case, a context switch - which manipulates the task ready list array - was not atomic due to incorrect ordering of the service and sys tick ISRs - service MUST POSITIVELY have the lowest priority since it must only interrupt a task context, never an interrupt context. Thus the sys tick interrupt was being interrupted by the service ISR which broke atomicity on the task ready list.
The next thing to look for, then, is an incorrect usage of the critical section, for example in the guise that an interrupt w/ priority > MAX_SYSCALL illegaly performs operations on FreeRTOS lists.
Sorry for the rather elaborate explanation, I hope it gives you a useful pointer or two…