therefore a two-way link between the
object containing the list item and
the list item itself. */
void * pvContainer; /* Pointer to the list in which this list
item is placed (if any). */
};
每个元素持有一个数字,xItemValue,这通常是一个被跟踪的任务优先级或者是一个调度事件的计时器。列表保存从高到低的优先级指令,这意味着最高的优先级xItemValue(最大数)在列表的最前端,而最低的优先级xItemValue(最小数)在列表的末尾。
pxNext和pxPrevious指针是标准链表指针。pvOwner 列表元素所有者的指针。这通常是任务的TCB对象的指针。pvOwner被用来在vTaskSwitchContext()中加快任务切换:当最高优先级任务元素在pxReadyTasksLists[]中被发现,这个列表元素的pvOwner指针直接连接到需要任务调度的TCB。
pvContainer指向自己所在的这个列表。若列表项处于一个特定列表它被用作快速终止。任意列表元素可以被置于一个列表,如下所定义:
typedef struct xLIST
{
volatile unsigned portBASE_TYPE uxNumberOfItems;
volatile xListItem * pxIndex; /* Used to walk through the list. Points to
the last item returned by a call to
pvListGetOwnerOfNextEntry (). */
volatile xMiniListItem xListEnd; /* List item that contains the maximum
possible item value, meaning it is always
at the end of the list and is therefore
used as a marker. */
} xList;
列表的大小任何时候都是被存储在uxNumberOfItems中,用于快速列表大小操作。所有的列表都被初始化为容纳一个元素:xListEnd元素。xListEnd.xItemValue是一个定点,当portTickType是16位数时,它等于xItemValue变量的最大:0xffff,portTickType是32位数时为0xffffffff。其他的列表元素也可以使用相同的;插入算法保证了xListEnd总是列表项中最后一个。
自列表从高到低排序后,xListEnd被用作列表开始的记号。并且,自循环开始,xListEnd也被用作列表结束的记号。
你也许可以用一个单独的for()循环或者是函数调用来访问大多数“传统的”列表,去做所有的工作,就像这样:
for (listPtr = listStart; listPtr != NULL; listPtr = listPtr->next) {
// Do something with listPtr here...
}
FreeRTOS经常需要通过多个for()和while()循环,也包括函数调用来访问列表,因此它使用操纵pxIndex指针的列表函数来遍历这个列表。这个列表函数listGET_OWNER_OF_NEXT_ENTRY()执行pxIndex = pxIndex->pxNext;并且返回pxIndex。(当然它也会正确检测列尾环绕。)这种,当执行遍历的时候使用pxIndex,由列表自己负责跟踪“在哪里”的方法,使FreeRTOS可以休息而不用关心这方面的事。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-30698-7.html