Appearance
实现时间片
- 修改时间中断函数
c
void xPortSysTickHandler( void )
{
/* 关中断 */
vPortRaiseBASEPRI();
{
//xTaskIncrementTick();
/* 更新系统时基 */
if( xTaskIncrementTick() != pdFALSE )
{
/* 任务切换,即触发PendSV */
//portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
taskYIELD();
}
}
/* 开中断 */
vPortClearBASEPRIFromISR();
}
这里只有当有任务的优先级比较高的时候才会发生切换
c
//void xTaskIncrementTick( void )
BaseType_t xTaskIncrementTick( void )
{
TCB_t * pxTCB;
TickType_t xItemValue;
BaseType_t xSwitchRequired = pdFALSE;
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 );
#if ( configUSE_PREEMPTION == 1 )
{
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
{
xSwitchRequired = pdTRUE;
}
}
#endif /* configUSE_PREEMPTION */
}
}
}/* xConstTickCount >= xNextTaskUnblockTime */
#if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) )
{
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) )
> ( UBaseType_t ) 1 )
{
xSwitchRequired = pdTRUE;
}
}
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */
/* 任务切换 */
//portYIELD();
}
实际上就是在时间片到达之后检测是否有更高优先级的任务存在, 存在的话就进行切换, 否则不进行切换