vTaskDelay和_delay_ms之间的行为差​​异是什么?

时间:2018-07-02 22:34:33

标签: c multithreading scheduling avr freertos

1。简介

我似乎找不到有关FreeRTOS任务中以下功能之间行为差异的信息或详细解释:

  • vTaskDelay
  • _delay_ms

2。代码

假设您具有以下代码:

空闲挂钩+任务创建

Long value = 0;

void vApplicationIdleHook( void ) {
    while(1)
    {
        // empty
    }
}

int main(void)
{
     xTaskCreate(TaskIncrement, (const portCHAR *)"up" , 256, NULL, 2, NULL );
     xTaskCreate(TaskDecrement, (const portCHAR *)"down" , 256, NULL, 1, NULL );

     vTaskStartScheduler();
}

带有vTaskDelay的任务

static void TaskDecrement(void *param)
{
    while(1)
    {
        for(unsigned long i=0; i < 123; i++) {
            //semaphore take
            value--;
            //semaphore give
        }
        vTaskDelay(100);
    }
}

static void TaskIncrement(void *param)
{
    while(1)
    {
        for(unsigned long i=0; i < 123; i++) {
            //semaphore take
            value++;
            //semaphore give
        }
        vTaskDelay(100);
    }
}

具有_delay_ms

的任务
static void TaskDecrement(void *param)
{
    while(1)
    {
        for(unsigned long i=0; i < 123; i++) {
            //semaphore take
            value--;
            //semaphore give
        }
        _delay_ms(100);
    }
}

static void TaskIncrement(void *param)
{
    while(1)
    {
        for(unsigned long i=0; i < 123; i++) {
            //semaphore take
            value++;
            //semaphore give
        }
        _delay_ms(100);
    }
}

3。问题

vTaskDelay与_delay_ms一起提供任务时,程序流程会怎样?

注意:给定的两个示例任务具有不同的优先级。

1 个答案:

答案 0 :(得分:6)

来自https://www.freertos.org/Documentation/FreeRTOS_Reference_Manual_V10.0.0.pdf

  

将调用vTaskDelay()的任务置于“阻止”状态,以获得固定数量的滴答中断。指定零滴答声的延迟时间不会导致调用任务进入“阻塞”状态,但是会使调用任务屈服于任何共享其优先级的“就绪”任务。调用vTaskDelay(0)等效于调用taskYIELD()。

我认为您已经知道了,但是如果您创建了多个任务,那么vTaskDelay()会将运行中的任务在指定的滴答中断次数(不是毫秒!)下置于“已阻止”状态,并允许具有最高优先级的任务才能运行,直到获得控制权(或被抢占,具体取决于您的FreeRTOS配置)。

我不认为_delay_ms()是FreeRTOS库的一部分。您确定它不是特定于平台的功能吗?我的猜测是,如果优先级最高的任务调用_delay_ms(),则将导致繁忙的等待。否则,优先级较高的任务可能会抢占正在延迟的调用_delay_ms()的任务(也就是说,_delay_ms()不会立即产生控制权)。

也许可以更好地概括上述内容:在多任务应用程序中,_delay_ms()不是确定性的。