【问题标题】:What is the behavioral difference between vTaskDelay and _delay_ms?vTaskDelay 和_delay_ms 之间的行为区别是什么?
【发布时间】:2018-07-02 22:34:33
【问题描述】:

1.简介

我似乎无法找到有关 FreeRTOS 任务中以下函数之间行为差异的信息或详细说明:

  • vTaskDelay
  • _delay_ms

2。代码

假设你有以下代码:

IdleHook + 任务创建

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 时,程序流程会发生什么?

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

【问题讨论】:

    标签: c multithreading scheduling avr freertos


    【解决方案1】:

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

    将调用 vTaskDelay() 的任务置于 Blocked 状态以进行固定数量的滴答中断。指定零滴答的延迟时间不会导致调用任务进入阻塞状态,但会导致调用任务让步给任何共享其优先级的就绪状态任务。调用 vTaskDelay(0) 相当于调用 taskYIELD()。

    我想你已经明白了,但是如果你创建了多个任务,那么vTaskDelay() 会将正在运行的任务置于“阻塞”状态并持续指定数量的滴答中断(不是毫秒!)并允许该任务以次高优先级运行,直到它产生控制权(或被抢占,具体取决于您的 FreeRTOS 配置)。

    我不认为_delay_ms() 是 FreeRTOS 库的一部分。您确定这不是特定于平台的功能吗?我的猜测是,如果最高优先级的任务调用_delay_ms(),那么它会导致忙等待。否则,具有更高优先级的任务可能会抢占调用_delay_ms() 的任务,因为它正在延迟(即_delay_ms() 不会立即让出控制权)。

    也许对上述内容进行了更好的总结:在多任务应用程序中,_delay_ms() 不是确定性的。

    【讨论】:

    • _delay_ms 是(很可能)延迟的 AVR 实现。它不与 RTOS 交互,如果从最高优先级任务调用它,调用它实际上会阻塞 100 毫秒的所有内容。否则延迟可能甚至几天(取决于更高优先级的任务..)。始终使用基于 RTOS 的延迟函数。
    • @tilz0R 感谢您提供的额外解释,这正是我一直在寻找的。我知道应该使用 vTaskDelay。我想知道如果您使用 AVR 函数 _delay_ms 而不是 vTaskDelay,程序流程会发生什么。
    • vTaskDelay 会将您的任务置于 100ms 的阻塞状态,同时将执行其他任务。当100ms 时间过去时,任务将回到runnable 状态,调度程序将在下次选择它。在_delay_ms 的情况下,您没有此选项,因为 _delay_ms 使用 for 循环运行,并且此 for 循环必须按循环数执行。如果您在循环之间切换任务,当您返回此任务时(如果您曾经返回),您将继续。不要尝试使用 _delay_ms。
    猜你喜欢
    • 2011-11-29
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多