vTaskDelay(100 / portTICK_RATE_MS);
时间: 2024-08-18 15:00:59 浏览: 56
当你在FreeRTOS中使用`vTaskDelay(100 / portTICK_RATE_MS)`时,这个表达式的作用是在当前任务中插入一个大约100毫秒(因为`portTICK_RATE_MS`通常是每毫秒执行一次)的延迟。这里的`100`代表了你想让任务暂停执行的时间(假设单位是毫秒),而`portTICK_RATE_MS`则是FreeRTOS中tick(时间片)的周期,也就是系统执行调度的频率。
例如,如果`portTICK_RATE_MS`设置为1,那么`vTaskDelay(100 / portTICK_RATE_MS)`就相当于延时100毫秒。如果是千分之一毫秒(即1us),则会延时100微秒。
需要注意的是,实际的延时可能会稍有偏差,因为`vTaskDelay`不是精确计时,而是基于任务调度周期估算的一个近似值。此外,这个函数并不会阻塞后续的任务,而是允许其他任务在等待时间内运行,直到达到设定的延迟时间。
相关问题
void WatchDogTask(void) { unsigned int CurStamp; while(1) { vTaskDelay(WD_TIM/portTICK_RATE_MS);//定时 CurStamp=HAL_GetTick(); FeetSysDog(); WR_IO_LED_RED(1); if(LedTickCnt++>(1000/WD_TIM)) { LedTickCnt=0; if(LedOn==0) { LedOn=1; WR_IO_LED_BLUE(1); } else { LedOn=0; WR_IO_LED_BLUE(0); } } } } TaskHandle_t taskUsart1SendHandle; TaskHandle_t taskUsart2SendHandle; TaskHandle_t CanRecTaskHandle; TaskHandle_t taskDebugDataProDealHandle; TaskHandle_t ComLRecTaskHandle; TaskHandle_t ComRRecTaskHandle; TaskHandle_t KeyScanTaskHandle; void StartDefaultTask(void const * argument) { unsigned char RdEepromReturn=0;
这段代码包含了一个WatchDogTask函数和一系列TaskHandle_t类型的任务句柄变量的定义。
WatchDogTask是一个无返回值(void)的函数,没有参数。该函数通过一个无限循环来实现任务的周期性执行。其中,vTaskDelay函数用于定时延迟一段时间,单位为毫秒,WD_TIM/portTICK_RATE_MS表示延迟WD_TIM个时钟周期。HAL_GetTick函数用于获取当前的系统滴答计数值,用于记录时间戳。FeetSysDog函数用于喂狗,即刷新看门狗定时器。WR_IO_LED_RED和WR_IO_LED_BLUE函数用于控制红色和蓝色LED灯的亮灭。LedTickCnt用于计数LED闪烁的次数,当计数达到一定值后进行LED状态的切换。
接下来,定义了一系列TaskHandle_t类型的任务句柄变量,用于存储不同任务的句柄。
最后,定义了一个名为StartDefaultTask的函数,该函数没有参数,没有返回值。具体函数体的实现没有给出,只定义了一个名为RdEepromReturn的无符号字符变量。
需要注意的是,这段代码只是给出了函数的声明和任务句柄变量的定义,并没有给出具体的实现代码。如果想要了解更多关于这些任务和函数的信息,需要查看其他部分的代码或提供更多上下文。
void vTaskFunction( void *pvParameters ) { char *pcTaskName; portTickType xLastWakeTime; /* The string to print out is passed in via the parameter. Cast this to a character pointer. */ pcTaskName = ( char * ) pvParameters; /* 变量xLastWakeTime需要被初始化为当前心跳计数值。说明一下,这是该变量唯一一次被显式赋值。之后, xLastWakeTime将在函数vTaskDelayUntil()中自动更新。 */ xLastWakeTime = xTaskGetTickCount(); /* As per most tasks, this task is implemented in an infinite loop. */ for( ;; ) { /* Print out the name of this task. */ vPrintString( pcTaskName ); /* 本任务将精确的以250毫秒为周期执行。同vTaskDelay()函数一样,时间值是以心跳周期为单位的, 可以使用常量portTICK_RATE_MS将毫秒转换为心跳周期。变量xLastWakeTime会在 vTaskDelayUntil()中自动更新,因此不需要应用程序进行显示更新。 */ vTaskDelayUntil( &xLastWakeTime, ( 250 / portTICK_RATE_MS ) ); } },解析这段代码
这段代码是一个任务函数`vTaskFunction`的实现。以下是代码的解析:
首先,声明了几个变量:
- `char *pcTaskName`:用于存储任务名的字符指针。
- `portTickType xLastWakeTime`:用于存储上一次任务唤醒的时间。
接下来,通过将任务参数`pvParameters`进行类型转换,将其赋值给`pcTaskName`。这里假设任务参数是一个字符指针。
然后,通过调用`xTaskGetTickCount()`函数,将当前的心跳计数值赋给`xLastWakeTime`。这个变量在后面的`vTaskDelayUntil()`函数中会自动更新。
接下来,进入一个无限循环。在循环中,首先调用函数`vPrintString()`打印出任务名。
然后,使用`vTaskDelayUntil()`函数实现了一个精确的周期执行。这个函数的第一个参数是指向上一次唤醒时间的指针,第二个参数是任务需要延迟的时间。延迟的时间以心跳周期为单位,可以使用常量`portTICK_RATE_MS`将毫秒转换为心跳周期。通过这种方式,任务可以以精确的周期执行。
最后,由于任务函数是一个无限循环,所以代码会一直执行下去。
阅读全文