esp-open-rtosを使ってみる

Task Notifications機能

FreeRTOSにはTask Notifications機能が有ります。
LinuxのSignal機能と少し似ていますが、送信先のタスクIDを直接指定して、相手にイベントを通知する機能です。

Task Notifications機能の確認のために簡単なサンプルを作ってみました。
この機能を利用するためには、通知先のタスクIDを知っている必要が有りますので、
それぞれのタスクIDをグローバル領域に確保しています。
/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include <stdlib.h>
#include <string.h>
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"

static TaskHandle_t xTask1 = NULL, xTask2 = NULL;

void task1(void *pvParameters)
{
    TickType_t nowTick;
    nowTick = xTaskGetTickCount();
    printf("[%s:%d] Start\n",pcTaskGetName(0),nowTick);

    while(1) {
      // delay 1000mSec
      vTaskDelay(1000 / portTICK_PERIOD_MS);
      /* Send a notification to prvTask2(), bringing it out of the Blocked
        state. */
      xTaskNotifyGive( xTask2 );
      nowTick = xTaskGetTickCount();
      printf("[%s:%d] xTaskNotifyGive\n",pcTaskGetName(0),nowTick);

      /* Block to wait for prvTask2() to notify this task. */
      ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
      nowTick = xTaskGetTickCount();
      printf("[%s:%d] ulTaskNotifyTake\n\n",pcTaskGetName(0),nowTick);
    }
}

void task2(void *pvParameters)
{
    TickType_t nowTick;
    nowTick = xTaskGetTickCount();
    printf("[%s:%d] Start\n",pcTaskGetName(0),nowTick);

    while(1) {
      /* Block to wait for prvTask2() to notify this task. */
      ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
      nowTick = xTaskGetTickCount();
      printf("[%s:%d] ulTaskNotifyTake\n",pcTaskGetName(0),nowTick);

      // delay 1000mSec
      vTaskDelay(1000 / portTICK_PERIOD_MS);
      /* Send a notification to prvTask2(), bringing it out of the Blocked
        state. */
      xTaskNotifyGive( xTask1 );
      nowTick = xTaskGetTickCount();
      printf("[%s:%d] xTaskNotifyGive\n",pcTaskGetName(0),nowTick);

    }
}


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(task1, "task1", 256, NULL, 2, &xTask1);
    xTaskCreate(task2, "task2", 256, NULL, 2, &xTask2);

}

実行すると以下の表示となります。
GiveとTakeが対になって動きます。
SDK version:0.9.9
pcTaskGetName=uiT
mode : sta(18:fe:34:d4:2f:77)
add if0
[task1:1] Start
[task2:1] Start
[task1:138] xTaskNotifyGive
[task2:138] ulTaskNotifyTake
[task2:238] xTaskNotifyGive
[task1:238] ulTaskNotifyTake

[task1:338] xTaskNotifyGive
[task2:338] ulTaskNotifyTake
[task2:438] xTaskNotifyGive
[task1:438] ulTaskNotifyTake

[task1:538] xTaskNotifyGive
[task2:538] ulTaskNotifyTake
[task2:638] xTaskNotifyGive
[task1:638] ulTaskNotifyTake

[task1:738] xTaskNotifyGive
[task2:738] ulTaskNotifyTake
[task2:838] xTaskNotifyGive
[task1:838] ulTaskNotifyTake

Semaphoreとよく似た機能ですが、Semaphoreでは2つ以上のタスク(特にタスク数に制限はなし)の同期を行うことができますが、
この機能では2つのタスク間の同期に限定されます。

続く....