FreeRTOS-软件定时器
一、软件定时器简介
二、软件定时器结构体成员和API函数 三、软件定时器实验
一、软件定时器简介
定时器 :指定时间开始,经过一个指定的时间,触发一个超时事件,用户可自定义定时器的周期硬件定时器 :硬件自带的定时器模块,精度高 ,定时时间到达以后可以触发中断,调用中断函数 ,缺点 是个数有限 软件定时器 :具有定时功能的软件 ,可设置定时周期,当指定时间到达后要调用回调函数 (也称超时函数 ),用户在回调函数中处理信息,成本低 ,内存足够的情况下个数不限 ,但精度不高 软件定时器特点:可裁剪 :configUSE_TIMERS 配置成1使能定时器、支持设置单次定时器 或周期定时器 软件定时器的超时回调函数 是由软件定时器服务任务 调用的,超时回调函数 本身不是任务 ,不能在该回调函数中使用可能会导致任务阻塞的API函数 软件定时器服务任务 :在调用vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器 的任务,叫软件定时器服务任务 软件定时器服务任务作用 :负责软件定时器超时的逻辑判断、调用超时软件定时器的超时回调函数、处理软件定时器命令队列软件定时器的API函数都是往定时器的队列中 写入消息(发送命令 ),这个队列叫做软件定时器命令队列 ,提供给软件定时器使用,用户不能直接访问 软件定时器配置:configUSE_TIMERS 配置成1,在启动任务调度器时,会自动创建软件定时器的服务/守护任务prvTimerTask() 。软件定时器服务任务的优先级为configTIMER_TASK_PRIORITY = 31 ,配置成最大 。定时器的命令队列长度为configTIMER_QUEUE_LENGTH = 5
1.1 软件定时器的状态和工作模式
软件定时器有两种状态 :休眠态 -软件定时器可以通过其句柄被引用,但因为没有运行,所以其定时超时回调函数不会被执行。运行态 -当指定时间到达以后,它的超时回调函数会被调用 新创建 的软件定时器处于休眠状态 ,发送命令队列 可以从休眠态变为运行态软件定时器的工作模式:单次定时器 一旦定时超时,只会执行一次其软件定时器超时回调函数 ,不会自动重新开启定时,不过可以被手动重新开始。周期定时器 -周期定时器的一旦启动以后就会在执行完回调函数以后自动的重新启动 ,从而周期的执行其软件定时器回调函数。
二、软件定时器结构体成员和API函数
typedef struct tmrTimerControl
{
const char * pcTimerName;
ListItem_t xTimerListItem;
TickType_t xTimerPeriodInTicks;
void * pvTimerID;
TimerCallbackFunction_t pxCallbackFunction;
# if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTimerNumber;
# endif
uint8_t ucStatus;
} xTIMER;
xTimerCreate ( ) ;
xTimerCreateStatic ( ) ;
xTimerStart ( ) ;
xTimerStartFromISR ( ) ;
xTimerStop ( ) ;
xTimerStopFromISR ( ) ;
xTimerReset ( ) ;
xTimerResetFromISR ( ) ;
xTimerChangePeriod ( ) ;
xTimerChangePeriodFromISR ( ) ;
TimerHandle_t xTimerCreate ( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction) ;
BaseType_t xTimerStart ( TimerHandle_t xTimer,
const TickType_t xTicksToWait) ;
BaseType_t xTimerStop ( TimerHandle_t xTimer,
const TickType_t xTicksToWait) ;
下面为复位软件定时器函数 该函数使软件定时器重新开启计时,复位后的软件定时器以复位时的时刻 作为开启时刻重新定时
BaseType_t xTimerReset ( TimerHandle_t xTimer,
const TickType_t xTicksToWait) ;
下图为软件定时器时间步图 ,超时时候为t5时,在t3复位,则还需要到t8才超时
BaseType_t xTimerChangePeriod ( TimerHandle_t xTimer,
const TickType_t xNewPeriod,
const TickType_t xTicksToWait) ;
三、软件定时器实验
实验设计:设计两个任务,start_task :创建task1和两个定时器-单次和周期。task1 :按键扫描,对定时器进行开启、停止操作。
# define configSUPPORT_DYNAMIC_ALLOCATION 1
# define configUSE_TIMERS 1
# define configTIMER_TASK_PRIORITY 31
# define configTIMER_QUEUE_LENGTH 5
# define configTIMER_TASK_STACK_DEPTH 256
# define START_TASK_STACK_SIZE 128
# define START_TASK_PRIO 1
TaskHandle_t start_task_handle;
# define TASK1_STACK_SIZE 128
# define TASK1_PRIO 2
TaskHandle_t task1_handle;
void task1 ( void * pvParameters )
{
uint8_t KeyNum = 0 ;
while ( 1 )
{
KeyNum = Key_GetNum ( ) ;
if ( KeyNum == 1 )
{
xTimerStart ( timer1_handle, portMAX_DELAY) ;
xTimerStart ( timer2_handle, portMAX_DELAY) ;
}
else if ( KeyNum == 2 )
{
xTimerStop ( timer1_handle, portMAX_DELAY) ;
xTimerStop ( timer2_handle, portMAX_DELAY) ;
}
vTaskDelay ( 10 ) ;
}
}
void timer1_callback ( TimerHandle_t pxTimer)
{
}
void timer2_callback ( TimerHandle_t pxTimer)
{
}
TimerHandle_t timer1_handle = 0 ;
TimerHandle_t timer2_handle = 0 ;
void Start_task ( void * pvParameters )
{
taskENTER_CRITICAL ( ) ;
timer1_handle = xTimerCreate ( "timer1" , 1000 , pdFALSE, 1 , timer1_callback) ;
timer2_handle = xTimerCreate ( "timer2" , 1000 , pdTRUE, 2 , timer2_callback) ;
xTaskCreate ( task1,
"task1" ,
TASK1_STACK_SIZE,
NULL ,
TASK1_PRIO,
& task1_handle
) ;
vTaskDelete ( start_task_handle) ;
taskEXIT_CRITICAL ( ) ;
}
void freertos_demo ( )
{
xTaskCreate ( Start_task,
"Start_task" ,
START_TASK_STACK_SIZE,
NULL ,
START_TASK_PRIO,
& start_task_handle
) ;
vTaskStartScheduler ( ) ;
}