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

What is the behavioral difference between vTaskDelay and _delay_ms?

1.简介

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

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。问题

与 _delay_ms 相比,当为任务提供 vTaskDelay 时,程序流程会发生什么变化?

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

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

Places the task that calls vTaskDelay() into the Blocked state for a fixed number of tick interrupts. Specifying a delay period of zero ticks will not result in the calling task being placed into the Blocked state, but will result in the calling task yielding to any Ready state tasks that share its priority. Calling vTaskDelay(0) is equivalent to calling taskYIELD().

我想您已经明白了,但是如果您创建了多个任务,那么 vTaskDelay() 会将 运行ning 任务置于 "Blocked" 指定数量的状态tick 中断(不是毫秒!)并允许具有下一个最高优先级的任务 运行 直到它放弃控制权(或被抢占,具体取决于您的 FreeRTOS 配置)。

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

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