Какова поведенческая разница между vTaskDelay и _delay_ms? - PullRequest
0 голосов
/ 03 июля 2018

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?

Примечание: две приведенные в качестве примера задачи имеют разные приоритеты.

1 Ответ

0 голосов
/ 03 июля 2018

С 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() не является детерминированным.

...