SIEMENS山东省泰安市 西门子代理商——西门子华北一级总代理
3.2.3 让队列按照给定的时间进行阻塞
回顾prvProcessTimerOrBlockTask()函数,定时器定时时间还没到,将当前任务挂起,直到定时器到期才唤醒或者收到命令的时候唤醒:
/* 队列为空 */ if( pxQueue->uxMessagesWaiting == ( UBaseType_t )0U ) { /* 将任务插入等待接收队列项而阻塞的事件列表,并加入延时列表进行阻塞延时 */ vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait, xWaitIndefinitely ); } /* 队列不为空 */ else { mtCOVERAGE_TEST_MARKER(); } /* 解锁队列 */ prvUnlockQueue(pxQueue);}3.3 处理命令队列中接收的消息
用户将需要处理的定时器命令发送到定时器的消息队列, Daemon 任务每次执行期间回去读取并执行,下面看看该函数的具体内容:
/*消息队列接收*/ while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) { #if ( INCLUDE_xTimerPendFunctionCall == 1 ) { /* 命令码小于等于0 (事件标志组中断中置位的命令)*/ if( xMessage.xMessageID < ( BaseType_t ) 0 ) { const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); configASSERT( pxCallback );
/* 执行回调函数 */ pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* INCLUDE_xTimerPendFunctionCall */
/* 命令码大于等于0 (软件定时器命令)*/ if( xMessage.xMessageID >= ( BaseType_t ) 0 ) { /* 定时器句柄 */ pxTimer = xMessage.u.xTimerParameters.pxTimer;
/* 定时器队列项包含该定时器 */ if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) { /* 移除该定时器 */ ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); } else { mtCOVERAGE_TEST_MARKER(); }
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue );
/* 获取当前时间,并判断是否需要切换定时器列表,如果需要则切换 */ 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 : /* 计算超时时间,超时时间没过加入活跃列表,超时时间已过返回pdTrue */ if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) { /* 在加入列表前已经超时,执行对应的回调函数 */ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); traceTIMER_EXPIRED( 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; } else { mtCOVERAGE_TEST_MARKER(); } } else { mtCOVERAGE_TEST_MARKER(); } 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; configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
/* 计算超时时间,超时时间没过则加入活跃列表 */ ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); break;
/* 删除定时器 */ case tmrCOMMAND_DELETE : #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) { /* 释放软件定时器内存 */ vPortFree( pxTimer ); } #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) { if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) { /* 释放软件定时器内存 */ vPortFree( pxTimer ); } else { mtCOVERAGE_TEST_MARKER(); } } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ break;
default : /* Don't expect to get here. */ break; } } }}
展开全文
相关产品