个人笔记--FreeRTOS软件定时器

FreeRTOS软件定时器

简介
软件定时器的基本概念

定时器:是指从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可以自定义定时器的周期与频率。类似生活中的闹钟,我们可以设置闹钟每天什么时候响,还能设置响的次数,是响一次还是每天都响。

硬件定时器:芯片本身提供的定时器,外部晶振输入提供时钟,通常精度高、中断触发方式

软件定时器:是由操作系统提供的一类系统接口,构建在硬件定时器的基础上,使系统能够提供不受硬件定时器的资源限制的定时器服务,实现的功能与硬件定时器类似。

软硬定时器使用区别:使用硬件定时器时,定时时间到达后会触发中断,用户在中断中处理信息;使用软件定时器时,需要在创建定时器时指定时间到达后要调用的函数(也称作超时函数/回调函数),在回调函数中处理信息。

注意:软件定时器回调函数的上下文是任务,回调函数中不能有任何阻塞任务运行的情况

FreeRTOS定时器功能上的支持
  1. 裁剪:能通过宏关闭软件定时器功能

  2. 软件定时器创建

  3. 软件定时器启动

  4. 软件定时器停止

  5. 软件定时器复位

  6. 软件定时器删除

  7. 单次模式和周期模式

    • 单次模式:启动后,定时时间到后,只执行一次回调函数,之后该定时器删除,不再执行

    • 周期模式:启动后,根据定时时间周期性的执行回调函数,直到用户将定时器删除。 在这里插入图片描述

软件定时器应用场景

​ 硬件定时器资源不足,对定时精度要求不高的任务。比如可以定时闪烁LED灯作为工作状态指示灯。

软件定时器的精度

​ 在操作系统中,通常软件定时器以系统节拍周期为计时单位。系统节拍是系统的心跳节拍,表示系统时钟的频率,类似人的心跳,1秒能跳动多少下。

​ 系统节拍配置为configTICK_RATE_HZ,该宏在 FreeRTOSConfig.h 中有定义,默认是 1000。表示1秒钟跳动1000下,每跳动一下即为1ms。

​ 软件定时器的所定时数值必须是节拍周期的整数倍,由于节拍定义了系统中定时器能够分辨的精确度,系统可以根据实际系统 CPU 的处理能力和实时性需求设置合适的数值,系统节拍周期值越小,精度越高,但是系统开销也越大。

软件定时器运作机制

​ 软件定时器是可选的系统资源,在创建定时器的时候会分配一块内存空间。FreeRTOS的软件定时器采用消息队列进行通信,利用“定时器命令队列”向软件定时器任务发送一些命令,任务在接收到命令就会去处理命令对应的程序,比如启动定时器,停止定时器等。

使用软件定时器需要注意几点
  • 软件定时器的回调函数中应快进快出,绝对不允许使用任何可能引软件定时器起任务挂起或者阻塞的 API 接口,在回调函数中也绝对不允许出现死循环
  • 软件定时器使用了系统的一个队列和一个任务资源,软件定时器任务的优先级默认为configTIMER_TASK_PRIORITY,为了更好响应,该优先级应设置为所有任务中最高的优先级
  • 创建单次软件定时器,该定时器超时执行完回调函数后,系统会自动删除该软件定时器,并回收资源
  • 定时器任务的堆栈大小默认为 configTIMER_TASK_STACK_DEPTH 个字节。
软件定时器函数接口

​ 软件定时器的功能是在定时器任务中实现的,(定时器任务在开启任务调度器时由内核自动创建),软件定时器的很多API函数通过一个名字叫“定时器命令队列”的队列来给定时器任务发送命令,该定时器命令队列由RTOS内核提供,且应用程序不能直接访问,其消息队列的长度由宏configTIMER_QUEUE_LENGTH定义。

软件定时器任务:在开启任务调度时创建,可以通过系统裁剪决定是否使用此任务。

软件定时器是一个任务,在下一个定时器到了之前的这段时间,系统要把任务状态转移为阻塞态,让其他的任务能正常运行,这样子就使得系统的资源能充分利用。

软件定时器任务的处理很简单,如果当前有软件定时器在运行,那么它大部分的时间都在等待定时器到期时间的到来,或者在等待对软件定时器操作的命令,而如果没有软件定时器在运行,那定时器任务的绝大部分时间都在阻塞中等待定时器的操作命令

软件定时器动态创建函数 xTimerCreate( ),每个软件定时器只需要很少的RAM空间,创建成功后处于休眠状态,可以使用_xTimerStart()、xTimerReset()、xTimerStartFromISR() 、 xTimerResetFromISR() 、 xTimerChangePeriod() 和xTimerChangePeriodFromISR()_这些函数将其状态转换为活跃态。

/*-------------------------------------------------------------------------------------------
	软件定时器创建函数
	pcTimerName:软件定时器名字,文本形式,纯粹是为了调试(FreeRTOS使用定时器时通过句柄,而不是名字)
	xTimerPeriodInTicks:软件定时器的周期,单位为系统节拍周期(即 tick)
	uxAutoReload:设置为pdTURE使用周期模式,设置pdFALSE使用单次模式
	pvTimerID:软件定时器ID,数字形式
	pxCallbackFunction:软件定时器的回调函数(用户自己实现)
	返回值是一个TimerHandle_t类型的句柄
----------------------------------------------------------------------------------------------*/
TimerHandle_t xTimerCreate(const char * const pcTimerName,const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction )
    
使用实例
static TimerHandle_t  Swtmr1_Handle = NULL;//软件定时器句柄
Swtmr1_Handle = xTimerCreate((const char*)"AutoReloadTimer",
                            (TickType_t)1000,/* 定时器周期 1000(tick) */
                            (UBaseType_t)pdTRUE,/* 周期模式 */
                            (void* )1,/* 为每个计时器分配一个索引的唯一 ID */
                            (TimerCallbackFunction_t)Swtmr1_Callback); /* 回调函数 */);
if(Swtmr1_Handle != NULL)
{
    printf("软件定时器1创建成功\r\n");
    xTimerStart(Swtmr1_Handle,0);	//开启周期定时器
}

static void Swtmr1_Callback(void* parameter)
{
    //软件定时器的回调函数,用户自己实现
}

软件定时器启动函数 xTimerStart( )

软件定时器在创建完成时是处于休眠状态,需要用相关API函数进行启动。系统开始调度时会自动创建一个定时器任务_prvTimerTask( )_,刚开始没有运行的定时器,此任务处于阻塞状态,定时器启动函数是通过定时器命令队列向定时器发送一个启动命令,定时器任务获得命令后解除阻塞,然后执行启动软件定时器命令。

/*------------------------------------------------------------------------------------------------
	软件定时器启动函数
	xTimer:要操作的软件定时器句柄
	xTicksToWait:软件定时器启动命令
	返回值:成功pdPASS,失败pdFALSE
-------------------------------------------------------------------------------------------------*/
BaseType_t xTimerStart( xTimer, xTicksToWait );

软件定时器启动函数 xTimerStartFromISR( ) (中断中调用)

/*------------------------------------------------------------------------------------------------
	软件定时器启动函数
	xTimer:要操作的软件定时器句柄
	pxHigherPriorityTaskWoken:判断退出中断后是否要进行任务切换
	返回值:成功pdPASS,失败pdFALSE
-------------------------------------------------------------------------------------------------*/
BaseType_t xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken )

软件定时器停止函数 xTimerStop( )

用来停止一个已经启动的软件定时器,同样是通过发送通知命令实现。

/*-----------------------------------------------------------------------------------------------
	软件定时器停止函数
	xTimer:软件定时器句柄
	xBlockTime:用户指定超时时间
-------------------------------------------------------------------------------------------------*/
BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xBlockTime );

//使用实例
static TimerHandle_t Swtmr1_Handle =NULL; //软件定时器句柄
/* 周期模式的软件定时器 1,定时器周期 1000(tick)*/
Swtmr1_Handle=xTimerCreate((const char* )"AutoReloadTimer",
						(TickType_t )1000,					//定时器周期 1000(tick)
						(UBaseType_t )pdTRUE,				//周期模式
						(void*)1,							//为每个计时器分配一个索引的唯一 ID
						(TimerCallbackFunction_t)Swtmr1_Callback);//回调函数

if (Swtmr1_Handle != NULL)
{
    /**************************************************************************************
            xTicksToWait:如果在调用 xTimerStart()时队列已满,则以 tick 为单位指定调用任务应保持
            在 Blocked(阻塞)状态以等待 start 命令成功发送到 timer 命令队列的时间。
            如果在启动调度程序之前调用 xTimerStart(),则忽略 xTicksToWait。在这里设置等待时间为 0.
     **************************************************************************************/
	xTimerStart(Swtmr1_Handle,0); //开启周期定时器 
}

static void test_task(void* parameter)
{
	while (1) 
    {
		/* 用户自己实现任务代码 */
		xTimerStop(Swtmr1_Handle,0); //停止定时器 
	}
}

软件定时器停止函数 xTimerStopFromISR( )(中断中调用)

用来停止一个已经启动的软件定时器,同样是通过发送通知命令实现。

/*-----------------------------------------------------------------------------------------------
	软件定时器停止函数
	xTimer:软件定时器句柄
	pxHigherPriorityTaskWoken:用来判断退出中断前是否进行任务切换
	返回值:成功pdPASS,失败pdFALSE
-------------------------------------------------------------------------------------------------*/
BaseType_t xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken);

软件定时器删除函数 xTimerDelete( )

用于删除一个已经被创建成功的软件定时器,删除之后就无法使用该定时器,并且定时器相应的资源也会被系统回收释放。

/*-----------------------------------------------------------------------------------------------
	软件定时器删除函数
	xTimer:软件定时器句柄
	xTicksToWait:用户指定的超时时间
	返回值:成功pdPASS,失败pdFALSE
-------------------------------------------------------------------------------------------------*/
xTimerDelete( xTimer, xTicksToWait )

FreeRTOS软件定时器的笔记总计完毕,以后有新的认识会继续更新此笔记—2020-11-28

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值