esp-open-rtosを使ってみる

vTaskDelayとvTaskDelayUntil

FreeRTOSでタスクに待ち時間を与える場合、vTaskDelay()を使いますが、よく似た機能にvTaskDelayUntil()が 有ります。
vTaskDelay()は現在時刻からの待ちを行いますが、vTaskDelayUntil()は指定された時刻からの待ちを行います。
以下のコードで違いを確認をしてみました。
/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include <stdlib.h>
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"

//時間稼ぎ
void ConsumptionTick(int delay) {
    TickType_t startTick;
    TickType_t endTick;
    TickType_t nowTick;
    startTick = xTaskGetTickCount();
    endTick = startTick + delay;
    //printf("startTick=%d endTick=%d\n",startTick,endTick);
    while(1) {
      nowTick = xTaskGetTickCount();
      if (nowTick > endTick) break;
    }
}

// Task Body
void task(void *pvParameters)
{
    TickType_t nowTick;
    TickType_t xLastWakeTime;
    nowTick = xTaskGetTickCount();
    printf("[%s:%d] start\n",pcTaskGetName(0),nowTick);

    // Initialise the xLastWakeTime variable with the current time.
    xLastWakeTime = xTaskGetTickCount();
    for(int i=0;i<10;i++) {
      // Wait for the next cycle.
      vTaskDelayUntil( &xLastWakeTime, 100 );
      nowTick = xTaskGetTickCount();
      printf("[%s:%d] wakeup from vTaskDelayUntil\n",pcTaskGetName(0),nowTick);
      ConsumptionTick(10);
    }

    for(int i=0;i<10;i++) {
      // Wait for the next cycle.
      vTaskDelay( 100 );
      nowTick = xTaskGetTickCount();
      printf("[%s:%d] wakeup from vTaskDelay\n",pcTaskGetName(0),nowTick);
      ConsumptionTick(10);
    }

    vTaskDelete( NULL );
}

void user_init(void)
{
    uart_set_baud(0, 115200);
    printf("SDK version:%s\n", sdk_system_get_sdk_version());
    printf("pcTaskGetName=%s\n",pcTaskGetName(0));

    xTaskCreate(task, "task", 256, NULL, 2, NULL);

}

ビルドして実行すると結果は以下の様になります。
起動直後は裏でAPへの接続が行われる影響で、Delayが正しく行われないことに初めて気が付きました。
Delayから抜けた後に、10Tick分の時間稼ぎを行っています。
vTaskDelayUntil()の場合は、時間稼ぎ(処理に要した時間)に関係なく100Tick毎に次の処理を始めることができます。
vTaskDelay()の場合は、現在時刻からの待ちなので、時間稼ぎ(処理に要した時間)があると、次の処理を始める時間がずれます。
vTaskDelayUntil()を使うと、処理に要した時間に関係なく、正確な定周期処理を行うことができます。
SDK version:0.9.9
pcTaskGetName=uiT
mode : sta(18:fe:34:d4:2f:77)
add if0
[task:1] start
scandone
[task:138] wakeup from vTaskDelayUntil
add 0
aid 7
cnt

connected with aterm-e625c0-g, channel 11
dhcp client start...
[task:201] wakeup from vTaskDelayUntil
[task:301] wakeup from vTaskDelayUntil
ip:192.168.10.154,mask:255.255.255.0,gw:192.168.10.1
[task:401] wakeup from vTaskDelayUntil
[task:501] wakeup from vTaskDelayUntil
[task:601] wakeup from vTaskDelayUntil
[task:701] wakeup from vTaskDelayUntil
[task:801] wakeup from vTaskDelayUntil
[task:901] wakeup from vTaskDelayUntil
[task:1001] wakeup from vTaskDelayUntil
[task:1112] wakeup from vTaskDelay
[task:1223] wakeup from vTaskDelay
[task:1334] wakeup from vTaskDelay
[task:1445] wakeup from vTaskDelay
[task:1556] wakeup from vTaskDelay
[task:1667] wakeup from vTaskDelay
[task:1778] wakeup from vTaskDelay
[task:1889] wakeup from vTaskDelay
[task:2000] wakeup from vTaskDelay
[task:2111] wakeup from vTaskDelay

続く....