FreeRTOS的vTaskDelay()和vTaskDelayUntil()

  • Post author:
  • Post category:其他


1、void vTaskDelay( const TickType_t xTicksToDelay )

2、void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )


从参数看 :

相对延时:void vTaskDelay只需要一个形参,就是要延时的毫秒数(我的系统节拍是1ms,为了好理解我就直接说多少毫秒了,其实这个数代表的是系统节拍数)。

绝对延时:vTaskDelayUntil需要一个TickType_t 类型的指针;一个要延时的毫秒数


实际延时原理

vTaskDelay是从调用延时函数开始算xTicksToDelay毫秒后完成延时,主体函数运行时间越长,延时开始时间越往后,整体任务周期就会变长。

vTaskDelayUntil是以pxPreviousWakeTime开始算xTimeIncrement 毫秒后完成延时,因为pxPreviousWakeTime是从任务第一次执行开始就记录的一个数值,所以整个任务执行周期就是绝对时间xTimeIncrement毫秒(这里要保证任务主体执行时间小于延时时间)

测试程序,这里仅黏贴测试任务代码

void task_lED2(void *pvParameters)
{                                                         // 本系统采用滴答定时器的1ms节拍 
	TickType_t PreviousWakeTime,MaskTime=0;               //定义任务第一次调用时间点
	const TickType_t TimeIncrement =pdMS_TO_TICKS(1000);  //将延时时间1000ms转为节拍数
	PreviousWakeTime=xTaskGetTickCount();                 //获取当前节拍数 用于vTaskDelayUntil
	while(1)                                              //主体循环函数开始
	{
		
		LED2_TOGGLE;                                      //翻转LED灯																	
		printf("PreviousWakeTime=%d	MaskTime=%d	\t\r\n",PreviousWakeTime,MaskTime);
		MaskTime+=100;
		if(MaskTime>900)
			MaskTime=0;
		HAL_Delay(MaskTime);																//利用HAL库延时增加主任务执行时间

//		vTaskDelay(TimeIncrement);
		vTaskDelayUntil(&PreviousWakeTime,TimeIncrement);
	}
}

结果如下

可以看出,主体时间变化但是任务执行周期未变化一直保持1秒,这就是所谓的绝对延时,这在一些通讯协议要求周期发送心跳包中很实用。


下面使用vTaskDelay测试

void task_lED2(void *pvParameters)
{                                                       // 本系统采用滴答定时器的1ms节拍 
	TickType_t PreviousWakeTime,MaskTime=0;               //定义任务第一次调用时间点
	const TickType_t TimeIncrement =pdMS_TO_TICKS(1000);  //将延时时间3000转为节拍数
	while(1)                                              //主体循环函数开始
	{
		PreviousWakeTime=xTaskGetTickCount();               //获取当前节拍数 用于vTaskDelayUntil
		LED2_TOGGLE;                                        //翻转LED灯																	
		printf("PreviousWakeTime=%d	MaskTime=%d	\t\r\n",PreviousWakeTime,MaskTime);
		MaskTime+=100;
		if(MaskTime>900)
			MaskTime=0;
		HAL_Delay(MaskTime);																//利用HAL库延时增加主任务执行时间

		vTaskDelay(TimeIncrement);
//		vTaskDelayUntil(&PreviousWakeTime,TimeIncrement);
	}
}


结果如下

可以看出任务总体运行时间为主体运行时间+TimeIncrement延时时间,总的任务运行周期是根据任务主体执行时间变化的,这就是相对时间,相对于主体任务结束时候延时的时间,也可以理解为在任务执行后顺延的时间。

说明:vTaskDelayUntil()函数内部有一句代码    *pxPreviousWakeTime = xTimeToWake;每次循环会更新pxPreviousWakeTime值,所以只需要在进入死循环前只需要调用一次即可;但是vTaskDelay()没有,所以为了输出系统节拍时间将PreviousWakeTime=xTaskGetTickCount();  移动到while(1)内



版权声明:本文为qq_43175613原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。