SIEMENS山东省济宁市 西门子代理商——西门子华北一级总代理
3.2.1 获取当前时间并决定是否切换列表
/*判断节拍计数器是否溢出过*/ if( xTimeNow < xLastTime ) { /*发生溢出,处理当前链表上所有定时器并切换管理链表*/ prvSwitchTimerLists(); *pxTimerListsWereSwitched = pdTRUE; } else { *pxTimerListsWereSwitched = pdFALSE; } /*更新时间记录*/ xLastTime = xTimeNow;
return xTimeNow;}
可以看到, 该函数每次调用都会记录当前系统节拍时间(TickCount), 下一次调用,通过比较相邻两次调用的值判断节拍计数器是否溢出。当系统节拍计数器溢出, 必须切换计时器列表。如果当前计时器列表中仍然引用任何计时器,那么它们一定已经过期,应该在切换列表之前进行处理。
切换列表的具体内容如下:
/* 列表非空,循环处理,直至将该列表处理完 */ while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) { xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
/* 从列表中移除软件定时器 */ pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); traceTIMER_EXPIRED( pxTimer );
/*执行回调函数*/ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
/*对于周期定时器*/ if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) { /*计算重新加载值:下个溢出时间 + 定时周期*/ xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); /*如果重新加载值>下个溢出时间,应该将计时器重新插入当前列表,以便在此循环中再次处理它*/ if( xReloadTime > xNextExpireTime ) { listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); } else/*否则,应该发送一个命令来重新启动计时器,以确保它只插入到列表之后列表已被交换*/ { xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); configASSERT( xResult ); ( void ) xResult; } } else { mtCOVERAGE_TEST_MARKER(); } }
pxTemp = pxCurrentTimerList; pxCurrentTimerList = pxOverflowTimerList; pxOverflowTimerList = pxTemp;}
(切换列表这里还没完全弄明白)
下面来看一下如何处理到时(或超时)的定时器:
3.2.2 处理超时的定时器展开全文
相关产品