函数 prvProcessTimerOrBlockTask 中, 当节拍计数器没有溢出, 判断当前管理链表上溢出定时器并进行处理的函数 prvProcessExpiredTimer 整体和上面介绍差别不大, 执行函数回调, 判断是否需要重载等。
用户将需要处理的定时器命令发送到定时器的消息队列, Daemon 任务每次执行期间回去读取并执行, 这部分工作有任务主体中的函数 prvProcessReceivedCommands完成, 下面看看这个函数如何实现, 对应平时使用定时器控制函数更加有底。
以下代码做了简化
static void prvProcessReceivedCommands( void )
{
DaemonTaskMessage_t xMessage;
Timer_t *pxTimer;
BaseType_t xTimerListsWereSwitched, xResult;
TickType_t xTimeNow;
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL )
{
#if ( INCLUDE_xTimerPendFunctionCall == 1 )
// 延期执行函数命令
// 执行注册的函数
#endif
// 定时器命令消息
if( xMessage.xMessageID >= ( BaseType_t ) 0 )
{
// 命令处理的定时器
pxTimer = xMessage.u.xTimerParameters.pxTimer;
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
{
// 如果定时器已经在链表中, 不管37 21, 移除
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
}
// 判断节拍计数器是否溢出过 处理 切换
// 因为下面可能有新项插入 确保链表对应
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
switch( xMessage.xMessageID )
{
case tmrCOMMAND_START :
case tmrCOMMAND_START_FROM_ISR :
case tmrCOMMAND_RESET :
case tmrCOMMAND_RESET_FROM_ISR :
case tmrCOMMAND_START_DONT_TRACE :
// 以上 ,都是让定时器跑起来
// 设置定时器溢出时间并插到链表中
if( prvInsertTimerInActiveList( pxTimer,
xMessage.u.xTimerParameters.xMessageValue +
pxTimer->xTimerPeriodInTicks, xTimeNow,
xMessage.u.xTimerParameters.xMessageValue )
!= pdFALSE )
{
// 处理定时器慢了, 该定时器已经溢出
// 赶紧执行其回调就看看函数
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
// 重载定时器 重新启动
if( pxTimer->uxAutoReload
== ( UBaseType_t ) pdTRUE )
{
xResult = xTimerGenericCommand( pxTimer,
tmrCOMMAND_START_DONT_TRACE,
xMessage.u.xTimerParameters.xMessageValue+pxTimer->xTimerPeriodInTicks,
NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
break;
case tmrCOMMAND_STOP :
case tmrCOMMAND_STOP_FROM_ISR :
// 停止定时器 开头已经从链表移除
// 不需要做其他
break;
case tmrCOMMAND_CHANGE_PERIOD :
case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR :
// 更新定时器配置
pxTimer->xTimerPeriodInTicks =
xMessage.u.xTimerParameters.xMessageValue;
// 插入到管理链表 也就启动了定时器
( void ) prvInsertTimerInActiveList( pxTimer,
( xTimeNow + pxTimer->xTimerPeriodInTicks ),
xTimeNow, xTimeNow );
break;
case tmrCOMMAND_DELETE :
// 删除定时器
// 判断定时器内存是否需要释放(动态的释放)
break;
default :
/* Don't expect to get here. */
break;
}
}
}
}
函数处理定时器,开头不管后面命令是什么,如果定时器原本在运行, 直接移除。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-29404-5.html