【学习FreeRTOS】第18章——FreeRTOS软件定时器

1.软件定时器的简介

  • 定时器:从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可自定义定时器的周期
  • 硬件定时器:芯片本身自带的定时器模块,硬件定时器的精度一般很高,每次在定时时间到达之后就会自动触发一个中断,用户在中断服务函数中处理信息。
  • 软件定时器:具有定时功能的软件,可设置定时周期,当指定时间到达后要调用回调函数(也称超时函数),用户在回调函数中处理信息

1.1软件定时的优缺点

  • 优点:硬件定时器数量有限,而软件定时器理论上只需有足够内存,就可以创建多个;使用简单、成本低
  • 缺点:软件定时器相对硬件定时器来说,精度没有那么高(因为它以系统时钟为基准系统时钟中断优先级又是最低,容易被打断)。对于需要高精度要求的场合,不建议使用软件定时器。

1.2.FreeRTOS软件定时的特点

  • 可裁剪:软件定时器是可裁剪可配置的功能,如果要使能软件定时器,需将configUSE_TIMERS配置项配置成1
  • 单次和周期:软件定时器支持设置成:单次定时器或周期定时器

【注意】软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的API函数

软件定时器服务任务:在调用函数vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,这个任务就叫做软件定时器服务任务。软件定时器服务任务作用

  • 负责软件定时器超时的逻辑判断
  • 调用超时软件定时器的超时回调函数
  • 处理软件定时器命令队列

1.3.软件定时器的命令队列

FreeRTOS提供了许多软件定时器相关的API函数,这些API函数大多都是往定时器的队列中写入消息(发送命令),这个队列叫做软件定时器命令队列,是提供给FreeRTOS 中的软件定时器使用的,用户是不能直接访问的。
【学习FreeRTOS】第18章——FreeRTOS软件定时器_第1张图片

1.4.软件定时器的相关配置

  • 当FreeRTOS的配置项configUSE_TIMERS设置为1,在启动任务调度器时,会自动创建软件定时器的服务/守护任务prvTimerTask( ) ;
  • 软件定时器服务任务的优先级为configTIMER_TASK_PRIORITY = 31;
  • 定时器的命令队列长度为configTIMER_QUEUE_LENGTH = 5 ;

【注意】软件定时器的超时回调函数是在软件定时器服务任务中被调用的,服务任务不是专为某个定时器服务的,它还要处理其他定时器。所以,定时器的回调函数不要影响其他定时器
1.回调函数要尽快实行,不能进入阻塞状态,即不能调用那些会阻塞任务的API函数,如: vTaskDelay()
2.访问队列或者信号量的非零阻塞时间的API函数也不能调用。

2.软件定时器的状态

  • 休眠态:软件定时器可以通过其句柄被引用,但因为没有运行,所以其定时超时回调函数不会被执行
  • 运行态:运行态的定时器,当指定时间到达之后,它的超时回调函数会被调用

【注意】新创建的软件定时器处于休眠状态,也就是未运行的!
【问题】如何让软件定时器从休眠态转变为运行态?——发送命令队列

3.单次定时器和周期定时器

  • 单次定时器:一旦定时超时,只会执行一次其软件定时器超时回调函数,不会自动重新开启定时,不过可以被手动重新开启
  • 周期定时器:一旦启动以后就会在执行完回调函数以后自动的重新启动,从而周期地执行其软件定时器回调函数
    【学习FreeRTOS】第18章——FreeRTOS软件定时器_第2张图片
    单次定时器状态转换图
    【学习FreeRTOS】第18章——FreeRTOS软件定时器_第3张图片
    周期定时器状态转换图
    【学习FreeRTOS】第18章——FreeRTOS软件定时器_第4张图片

4.软件定时器结构体成员介绍

typedef struct
{
	const char * 				pcTimerName				/* 软件定时器名字 */
    ListItem_t 					xTimerListItem			/* 软件定时器列表项 */
    TickType_t 					xTimerPeriodInTicks;   	/* 软件定时器的周期 */     
    void * 						pvTimerID				/* 软件定时器的ID */
    TimerCallbackFunction_t	 	pxCallbackFunction; 	/* 软件定时器的回调函数 */
#if ( configUSE_TRACE_FACILITY == 1 )
   	UBaseType_t 				uxTimerNumber			/*  软件定时器的编号,调试用  */
#endif
   	uint8_t 					ucStatus;              	/*  软件定时器的状态  */
}xTIMER;

类似于阻塞列表,软件定时器也有两个列表,一个是列表,另一个时溢出列表,用于解决时间溢出的问题

5.FreeRTOS软件定时器相关API函数

  • xTimerCreate():动态方式创建软件定时器
  • xTimerCreateStatic():静态方式创建软件定时器
  • xTimerStart():开启软件定时器定时
  • xTimerStartFromISR():在中断中开启软件定时器定时
  • xTimerStop():停止软件定时器定时
  • xTimerStopFromISR():在中断中停止软件定时器定时
  • xTimerReset():复位软件定时器定时
  • xTimerResetFromISR():在中断中复位软件定时器定时
  • xTimerChangePeriod():更改软件定时器的定时超时时间
  • xTimerChangePeriodFromISR():在中断中更改软件定时器的定时超时时间
  • xTimerDelete():删除软件定时器

5.1.动态方式创建软件定时器xTimerCreate()

TimerHandle_t xTimerCreate(	const char * const 		    pcTimerName,
							const TickType_t 		    xTimerPeriodInTicks,
							const UBaseType_t 	    	uxAutoReload,
							void * const 			    pvTimerID,
							TimerCallbackFunction_t     pxCallbackFunction); 
  • 形参pcTimerName:软件定时器名
  • 形参xTimerPeriodInTicks:定时超时时间,单位:系统时钟节拍
  • 形参uxAutoReload:定时器模式,pdTRUE:周期定时器,pdEALSE:单次定时器
  • 形参pvTimerlD:软件定时器ID,用于多个软件定时器公用一个超时回调函数
  • 形参pxCallbackFunction:软件定时器超时回调函数
  • 返回值:NULL,软件定时器创建失败;其他值,软件定时器创建成功,返回其句柄

5.2.开启软件定时器定时xTimerStart()

BaseType_t xTimerStart(	TimerHandle_t 		xTimer,
						const TickType_t 	xTicksToWait); 
  • 形参xTimer:待开启的软件定时器的句柄
  • 形参xTickToWait:发送命令到软件定时器命令队列的最大等待时间
  • 返回值:pdPASS,软件定时器开启成功;pdFAIL,软件定时器开启失败

5.3.停止软件定时器定时xTimerStop()

BaseType_t xTimerStop(	TimerHandle_t 		xTimer,
						const TickType_t 	xTicksToWait); 
  • 形参xTimer:待停止的软件定时器的句柄
  • 形参xTickToWait:发送命令到软件定时器命令队列的最大等待时间
  • 返回值:pdPASS,软件定时器停止成功;pdFAIL,软件定时器停止失败

5.4.复位软件定时器定时xTimerReset()

BaseType_t xTimerReset(	TimerHandle_t 		xTimer,
						const TickType_t 	xTicksToWait);

该功能将使软件定时器的重新开启定时,复位后的软件定时器以复位时的时刻作为开启时刻重新定时

  • 形参xTimer:待复位的软件定时器的句柄
  • 形参xTickToWait:发送命令到软件定时器命令队列的最大等待时间
  • 返回值:pdPASS,软件定时器复位成功;pdFAIL,软件定时器复位失败
    【学习FreeRTOS】第18章——FreeRTOS软件定时器_第5张图片

5.5.更改软件定时器的定时超时时间xTimerChangePeriod()

BaseType_t xTimerChangePeriod(	TimerHandle_t 		xTimer,
								const TickType_t 	xNewPeriod,
								const TickType_t 	xTicksToWait);
  • 形参xTimer:待更新的软件定时器的句柄
  • 形参xNewPeriod:新的定时超时时间,单位:系统时钟节拍
  • 形参xTickToWait:发送命令到软件定时器命令队列的最大等待时间
  • 返回值:pdPASS,软件定时器更新成功;pdFAIL,软件定时器更新失败

6.软件定时器整体流程

【学习FreeRTOS】第18章——FreeRTOS软件定时器_第6张图片

  • 开启任务调度器时,会创建软件定时器任务和空闲任务,其中软件定时器完成初始化后,因接收队列无内容而阻塞
  • 当创建好软件定时器后,软件定时器处于休眠,软件定时器任务仍处于阻塞状态
  • 当调用启动定时器API时,所在任务给软件定时器任务发送消息队列,软件定时器消息队列收到消息后被唤醒,进行一次处理
  • 当定时器超时时,软件定时器被唤醒,调用回调函数(快进快出)

7.FreeRTOS软件定时器实验

  • 实验目的:学习FreeRTOS的软件定时器相关API函数的使用。
  • 实验设计:将设计两个任务: start_task、task1两个任务的功能如下
    start_task用来创建task1任务,并创建两个定时器(单次和周期)
    task1用于按键扫描,并对软件定时器进行开启、停止操作

【学习FreeRTOS】第18章——FreeRTOS软件定时器_第7张图片

你可能感兴趣的:(学习FreeRTOS专栏,学习,单片机,嵌入式硬件,笔记,stm32)