TimerTask
BaseType_t xTimerCreateTimerTask( void )
{
BaseType_t xReturn = pdFAIL;
/*
1、检查 软件定时器列表和队列
2、如果没有创建内存空间,需要新建
*/
prvCheckForValidListAndQueue();
if( xTimerQueue != NULL )
{
#else
{
//为了满足软件定时器的实时性,软件定时器任务的优先级最高,其实就是最大值
xReturn = xTaskCreate( prvTimerTask,
"Tmr Svc",
configTIMER_TASK_STACK_DEPTH,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
&xTimerTaskHandle );
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
}
else
{
mtCOVERAGE_TEST_MARKER();
}
configASSERT( xReturn );
return xReturn;
}
/*
*/
static void prvCheckForValidListAndQueue( void )
{
taskENTER_CRITICAL();
{
//如果队列为空,则进行列表的初始化和队列的创建
if( xTimerQueue == NULL )
{
vListInitialise( &xActiveTimerList1 );
vListInitialise( &xActiveTimerList2 );
pxCurrentTimerList = &xActiveTimerList1;
pxOverflowTimerList = &xActiveTimerList2;
//创建消息队列
/*
消息队列参数:
1、configTIMER_QUEUE_LENGTH ------软件定时器 队列长度 10
2、DaemonTaskMessage_t ------整个软件定时器消息的大小
*/
{
xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
}
#endif
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
taskEXIT_CRITICAL();
}
xTimerCreate
TimerHandle_t xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
Timer_t *pxNewTimer;
//动态分配 软件定时器控制块内存空间
pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );
if( pxNewTimer != NULL )
{
//进入控制初始化
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );
}
return pxNewTimer;
}
static void prvInitialiseNewTimer( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction,
Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
/* 0 is not a valid value for xTimerPeriodInTicks. */
configASSERT( ( xTimerPeriodInTicks > 0 ) );
if( pxNewTimer != NULL )
{
/* 再次判断是否已经创建 队列 初始化了列表 */
prvCheckForValidListAndQueue();
/*
1、进行软件定时器控制块信息的赋值
2、把当前软件定时器列表项初始化,便于以后使用
*/
pxNewTimer->pcTimerName = pcTimerName;
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
pxNewTimer->uxAutoReload = uxAutoReload;
pxNewTimer->pvTimerID = pvTimerID;
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
traceTIMER_CREATE( pxNewTimer );
}
}
xTimerStart
#define xTimerStart( xTimer, xTicksToWait )
/*
参数:
1、软件定时器句柄
2、定义Start编号
3、当前的系统的Tick值
4、null
5、阻塞等待时间
*/
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
#define xTimerStop( xTimer, xTicksToWait )
/*
参数:
1、软件定时器句柄
2、定义Stop编号
3、0 不需要传入消息
4、null
5、阻塞等待时间
*/
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait )
/*
参数:
1、软件定时器句柄
2、定义CHANGE编号
3、xNewPeriod 用于改变新的周期
4、null
5、阻塞等待时间
*/
xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait )
{
BaseType_t xReturn = pdFAIL;
DaemonTaskMessage_t xMessage;
if( xTimerQueue != NULL )
{
/*
1、xCommandID 用于标识 触发的类型 比如start
2、xOptionalValue = xTaskGetTickCount
在start时,才是软件定时器的真正启动,内部参考systick,这个时候要传入一个初值,才能计算
3、xTimer 要操作的软件定时器的句柄
*/
xMessage.xMessageID = xCommandID;
xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;
xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer;
//判断命令类型
if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )
{
//判断调度器状态
if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )
{
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );
}
else
{
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
}
}
else
{
xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
}
traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
return xReturn;
}