Appearance
任务延时列表
从就绪列表删除, 添加到延时列表
实现两条列表, 一条是溢出列表, 一条是没有溢出的列表
c
static List_t xDelayedTaskList1;
static List_t xDelayedTaskList2;
static List_t * volatile pxDelayedTaskList;
static List_t * volatile pxOverflowDelayedTaskList;
c
//初始化列表
void prvInitialiseTaskLists( void )
{
UBaseType_t uxPriority;
/* 初始化就绪列表 */
for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )
{
vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
}
vListInitialise( &xDelayedTaskList1 );
vListInitialise( &xDelayedTaskList2 );
pxDelayedTaskList = &xDelayedTaskList1;
pxOverflowDelayedTaskList = &xDelayedTaskList2;//两个指针指向对应列表
}
c
static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U;
static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0;
下一个要解锁的变量
c
//在初始化的时候把下一个解锁的任务时间设置为最大值, 计数器时间设置为0
//初始化下一个任务的启动时间为最大值
xNextTaskUnblockTime = portMAX_DELAY;
xTickCount = 0;
- 修改代码
延时函数
c
void vTaskDelay( const TickType_t xTicksToDelay )
{
TCB_t *pxTCB = NULL;
/* 获取当前任务的TCB */
pxTCB = pxCurrentTCB;
/* 设置延时时间 */
//pxTCB->xTicksToDelay = xTicksToDelay;
/* 将任务插入到延时列表 */
prvAddCurrentTaskToDelayedList( xTicksToDelay );
/* 任务切换 */
taskYIELD();
}
c
static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait )
{
TickType_t xTimeToWake;
/* 获取系统时基计数器xTickCount的值 */
const TickType_t xConstTickCount = xTickCount;
/* 将任务从就绪列表中移除 */
if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{
/* 将任务在优先级位图中对应的位清除 */
portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );
}
/* 计算延时到期时,系统时基计数器xTickCount的值是多少 */
xTimeToWake = xConstTickCount + xTicksToWait;
/* 将延时到期的值设置为节点的排序值 */
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake );
/* 溢出 */
if( xTimeToWake < xConstTickCount )
{
vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
}
else /* 没有溢出 */
{
vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) );
/* 更新下一个任务解锁时刻变量xNextTaskUnblockTime的值 */
if( xTimeToWake < xNextTaskUnblockTime )
{
xNextTaskUnblockTime = xTimeToWake;
}
}
}
把他的就绪位删除, 从就序列表中删除, 之后根据解除的时间进行切换唤醒时间
- 更新一下时钟处理函数
c
void xTaskIncrementTick( void )
{
TCB_t * pxTCB;
TickType_t xItemValue;
const TickType_t xConstTickCount = xTickCount + 1;
xTickCount = xConstTickCount;
/* 如果xConstTickCount溢出,则切换延时列表 */
if( xConstTickCount == ( TickType_t ) 0U )
{
taskSWITCH_DELAYED_LISTS();
}
/* 最近的延时任务延时到期 */
if( xConstTickCount >= xNextTaskUnblockTime )
{
for( ;; )
{
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
{
/* 延时列表为空,设置xNextTaskUnblockTime为可能的最大值 */
xNextTaskUnblockTime = portMAX_DELAY;
break;
}
else /* 延时列表不为空 */
{
pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) );
/* 直到将延时列表中所有延时到期的任务移除才跳出for循环 */
if( xConstTickCount < xItemValue )
{
xNextTaskUnblockTime = xItemValue;
break;
}
/* 将任务从延时列表移除,消除等待状态 */
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
/* 将解除等待的任务添加到就绪列表 */
prvAddTaskToReadyList( pxTCB );
}
}
}/* xConstTickCount >= xNextTaskUnblockTime */
/* 任务切换 */
portYIELD();
}
- 之后修改taskRESET_READY_PRIORITY()
出错
在调用之后会出现硬件错误, 调整栈指针之后没有解决, 并且经过仿真发现不能正常到达空闲任务