FreeRTOS_vTaskDelayUntil
笔者在音频项目上使用vTaskDelayUntil
函数时遇到一个奇怪的现象,就是vTaskDelayUntil
绝对延时不精准。
笔者第一次使用如下:
void vCyclicTaskFunction( void * pvParameters )
{
static TickType_t xLastWakeTime;
for( ;; )
{
printf("hello world!\n");
vTaskDelayUntil( &xLastWakeTime, xPeriod );
}
}
笔者第二次使用时,写法如下:
void vCyclicTaskFunction( void * pvParameters )
{
TickType_t xLastWakeTime;
for( ;; )
{
printf("hello world!\n");
vTaskDelayUntil( &xLastWakeTime, xPeriod );
}
}
这两种写法唯一的区别就是xLastWakeTime
局部变量有没有static
修饰。第一种写法,笔者测试过是正常的绝对延时,然而第二种却不是绝对延时。笔者一直都找不到问题所在,于是查看了FreeRTOS官方手册,有以下范例:
/* Define a task that performs an action every 50 milliseconds. */
void vCyclicTaskFunction( void * pvParameters )
{
TickType_t xLastWakeTime;
const TickType_t xPeriod = pdMS_TO_TICKS( 50 );
/* The xLastWakeTime variable needs to be initialized with the current tick
count. Note that this is the only time the variable is written to explicitly.
After this assignment, xLastWakeTime is updated automatically internally within
vTaskDelayUntil(). */
xLastWakeTime = xTaskGetTickCount();
/* Enter the loop that defines the task behavior. */
for( ;; )
{
/* This task should execute every 50 milliseconds. Time is measured
in ticks. The pdMS_TO_TICKS macro is used to convert milliseconds
into ticks. xLastWakeTime is automatically updated within vTaskDelayUntil()
so is not explicitly updated by the task. */
vTaskDelayUntil( &xLastWakeTime, xPeriod );
/* Perform the periodic actions here. */
}
}
范例中的xLastWakeTime
也没有static
修饰,但笔者确实测试过是绝对的延时。再仔细看注释内容,如下:
/* The xLastWakeTime variable needs to be initialized with the current tick
count. Note that this is the only time the variable is written to explicitly.
After this assignment, xLastWakeTime is updated automatically internally within
vTaskDelayUntil(). */
xLastWakeTime
变量需要用当前滴答值初始化计数。 注意,这是唯一一次显式地写入变量。在这个赋值之后,xLastWakeTime
会在内部自动更新 vTaskDelayUntil()
。