您的位置:

vTaskDelay详解

在FreeRTOS中,任务调度是由调度器完成的。每个任务都可以通过调用不同的task API函数来添加任务到调度器中,vTaskDelay就是其中之一,它能够把任务阻塞一段时间。在这篇文章中,我们将详细介绍vTaskDelay的各种用法及其实现原理。

一、vTaskDelay(0)

vTaskDelay(0)是使用最普遍的调度函数之一。它允许其他任务获得时间片来执行,同时也会安排当前任务回到就绪状态。在实际开发中,很多任务需要在执行完成后立即回到任务列表中等待下一次执行,这时就可以使用vTaskDelay(0)。

  void task_a(void *p)
  {
    while(1)
    {
      //处理任务a的相关操作
      vTaskDelay(0);   //将任务a放回任务列表
    }
  }

二、vTaskDelayUntil函数

vTaskDelayUntil函数使任务在精确定时刻执行。这个函数的参数包括初始时间和延迟时间,任务将延迟至指定的时间再执行。在调用这个函数时需要注意的是,传入的tick值必须是由系统提供的时间源进行计算得到的,这可以通过FreeRTOS提供的configTICK_RATE_HZ宏定义来获取。

  void task_b(void *p)
  {
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = pdMS_TO_TICKS(1000);   //任务周期为1s
    
    xLastWakeTime = xTaskGetTickCount();
    while(1)
    {
      //处理任务b的相关操作
      vTaskDelayUntil(&xLastWakeTime, xFrequency);  //延时至循环周期结束
    }
  }

三、vTaskDelay vinsertlist函数

vTaskDelay vinsertlist函数可以暂停一个任务的执行,为其分配不少于指定周期的时间片。比如,在一些特别紧急的情况下,我们可能希望让某个任务立即执行,这种情况下可以使用vTaskDelay vinsertlist指令来插入或者替换一个或几个任务的time list中的任务,已实现快速切换。

  void task_c(void *p)
  {
    while(1)
    {
      //处理任务c的相关操作
      vTaskDelay(1000);   //暂停任务c1s
      vTaskDelayVInsert(&xTaskToDelay, 0);   //插入/替换一个新任务
    }
  }

四、vTaskDelay卡死

虽然vTaskDelay函数是非常有用的一个函数,但是在某些情况下可能会出现任务阻塞或卡死的现象。这种情况一般是由于系统调度器任务堵塞所导致的,可以通过增加系统tick时间,减少任务阻塞时间,来解决该问题。

五、vTaskDelay调用卡死

在一些特殊情况下,比如在中断服务程序中调用vTaskDelay函数,就会导致当前任务阻塞或卡死。这种情况下,建议使用Task-Notify机制,或者是在FreeRTOS中使用队列来实现相关功能。

六、vTaskDelay(100)

vTaskDelay(100)是一个阻塞当前任务的函数。它将任务放入任务等待列表,并在给定的时间(这里是100*configTICK_RATE_HZ)之后再执行该任务。在实际开发中,我们经常会使用这个函数来模拟并发执行。

  void task_d(void *p)
  {
    while(1)
    {
      //处理任务d的相关操作
      vTaskDelay(100);  //等待100ticks后再次执行任务
    }
  }

七、vTaskDelay用不了

如果您的程序中无法使用vTaskDelay函数,却不确定原因,可以考虑以下情况:

1、任务列表中只有一个任务,任务执行的频率太高。

2、推出中断锁定时调用vTaskDelay函数,会发生阻塞。

3、在中断服务程序中调用了vTaskDelay函数,导致任务卡死。

八、vTaskDelayUntil设置多少

在使用vTaskDelayUntil时,应该根据实际系统运行情况来设置任务延时时间。一般来说,任务的延时时间应该小于一个任务的周期,在本例中我们设置了1000ms,也就是一个周期。如果需要更高的实时性,建议将该值适当缩小。

以上就是关于vTaskDelay函数的详细介绍,通过了解vTaskDelay的常规用法及其实现原理,可以更好地用这个函数来掌握任务的执行时间。希望这篇文章能够帮助您更好地利用vTaskDelay。