1、什么是任务
任务主体:无限循环且不能返回。函数参数是指针,返回值是void(无返回)。/2任务的实现过程:
1.1定义任务栈:
栈:是单片机RAM里面连续的一段内存空间。
要为每个任务分配独立的栈空间。栈空间通常是预定义的全局数组。也可以是动态分配的一段内存空间
1.2定义任务函数:
1.3定义任务控制块:
2、任务的实现过程
2.1列表和列表项定义:
2.1.1列表:
第一个和第五个:用来检查列表的完整性。
第二个:列表项的个数
第三个:当前列表项索引号
第四个:列表当中最后一个列表项,表示列表的结束
2.1.2列表项
第二个:列表项的值
第三个:指向下一个列表项
第四个:指向上一个列表项
第五个:列表项归谁拥有,属于任务的一个任务节点,归任务所有
第六个:指向就绪列表
2.1.3迷你列表项:
第二个:迷你列表项的值
第三个:指向下一个迷你列表项
第四个:指向上一个迷你列表项
2.2列表和列表项初始化
2.2.1列表初始化
列表即链表中的节点定义模版,列表项即用这个模板定义出的一个个节点
2.2.2列表项初始化
2.3列表项相关函数
2.3.1列表项插入函数
void vListInsert( List_t * const pxList,
ListItem_t * const pxNewListItem )
{
ListItem_t * pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
traceENTER_vListInsert( pxList, pxNewListItem );
listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );//检测完整性
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem;
pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++;
traceRETURN_vListInsert();
}
流程图:
2.3.2列表项末尾插入函数
void vListInsertEnd( List_t * const pxList,
ListItem_t * const pxNewListItem )
{
ListItem_t * const pxIndex = pxList->pxIndex;
traceENTER_vListInsertEnd( pxList, pxNewListItem );
/* Only effective when configASSERT() is also defined, these tests may catch
* the list data structures being overwritten in memory. They will not catch
* data errors caused by incorrect configuration or use of FreeRTOS. */
listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
/* Insert a new list item into pxList, but rather than sort the list,
* makes the new list item the last item to be removed by a call to
* listGET_OWNER_OF_NEXT_ENTRY(). */
pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
/* Only used during decision coverage testing. */
mtCOVERAGE_TEST_DELAY();
pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxPrevious = pxNewListItem;
/* Remember which list the item is in. */
pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++;
traceRETURN_vListInsertEnd();
}
2.3.3列表项删除函数
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{
/* The list item knows which list it is in. Obtain the list from the list
* item. */
List_t * const pxList = pxItemToRemove->pxContainer;
traceENTER_uxListRemove( pxItemToRemove );
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
/* Only used during decision coverage testing. */
mtCOVERAGE_TEST_DELAY();
/* Make sure the index is left pointing to a valid item. */
if( pxList->pxIndex == pxItemToRemove )
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
pxItemToRemove->pxContainer = NULL;
( pxList->uxNumberOfItems )--;
traceRETURN_uxListRemove( pxList->uxNumberOfItems );
return pxList->uxNumberOfItems;
}
2.3.4列表的遍历
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )
do {
List_t * const pxConstList = ( pxList );
/* Increment the index to the next item and return the item, ensuring */
/* we don't return the marker used at the end of the list. */
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )
{
( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext;
}
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;
} while( 0 )