软件定时器实现原理源码分析

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;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值