esp-open-rtosを使ってみる

タスク状態の監視

FreeRTOSにはタスク状態を取り出す関数がいくつか用意されていますが、標準では使えないようになっています。
マイコン用のRTOSではよくあることで、メモリ制限を考慮して、必要な機能だけをAddOnするようになっています。
タスク状態を取り出すためには、ソースと同じ場所にある「FreeRTOSConfig.h」に追加する機能を定義します。
今回はeTaskGetState() を使いたかったので、以下の定義を追加しました。
注意点として一番末尾に追加すると二重定義のワーニングになります。
/* Blink FreeRTOSConfig overrides.

   This is intended as an example of overriding some of the default FreeRTOSConf
ig settings,
   which are otherwise found in FreeRTOS/Source/include/FreeRTOSConfig.h
*/

/* We sleep a lot, so cooperative multitasking is fine. */
#define configUSE_PREEMPTION 0

/* Blink doesn't really need a lot of stack space! */
#define configMINIMAL_STACK_SIZE 128

/* ここに追加機能を定義する */
#define configUSE_TRACE_FACILITY 1

/* Use the defaults for everything else */
#include_next<FreeRTOSConfig.h>

/*ここに定義するとワーニングになる */
//#define configUSE_TRACE_FACILITY 1

以下のコードでタスクの状態を取り出す頃ができます。
/* 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 taskEntry(void *pvParameters)
{
    UBaseType_t prio;
    TickType_t nowTick;

    prio = uxTaskPriorityGet( NULL );
    nowTick = xTaskGetTickCount();
    printf("[%s:%d] start Priority=%d\n",pcTaskGetName(0),nowTick,(int)prio);
    ConsumptionTick(200);
    nowTick = xTaskGetTickCount();
    printf("[%s:%d] end\n",pcTaskGetName(0),nowTick);
    vTaskDelete( NULL );
}

void user_init(void)
{
    BaseType_t xReturned;
    TickType_t nowTick;
    TaskHandle_t xHandle1 = NULL;

    uart_set_baud(0, 115200);
    nowTick = xTaskGetTickCount();
    printf("[%s:%d] SDK version:%s\n",pcTaskGetName(0),nowTick,sdk_system_get_sdk_version());
    printf("[%s:%d] portTICK_PERIOD_MS=%d[ms]\n",pcTaskGetName(0),nowTick,portTICK_PERIOD_MS);
    printf("[%s:%d] configMAX_PRIORITIES=%d\n",pcTaskGetName(0),nowTick,configMAX_PRIORITIES);

    xReturned = xTaskCreate(taskEntry, "myTask1", 256, NULL, 2, &xHandle1);
    if( xReturned != pdPASS ) {
       printf("xTaskCreate fail\n");
    }

    eTaskState taskState;
    UBaseType_t taskCount;
    for(int i=0;i<10;i++) {
      taskState = eTaskGetState( xHandle1 );
      taskCount = uxTaskGetNumberOfTasks();
      nowTick = xTaskGetTickCount();
      printf("[%s:%d] taskState=%d taskCount=%d\n",pcTaskGetName(0),nowTick,taskState,(int)taskCount);
      // delay 10mSec
      vTaskDelay(10 / portTICK_PERIOD_MS);
    }

}

結果は以下の様になりました。
myTask1が終わると、ステータスが4に、タスクの数が7変わります。
これでタスクの終了を待ち合わせすることができます。
[uiT:0] SDK version:0.9.9
[uiT:0] portTICK_PERIOD_MS=10[ms]
[uiT:0] configMAX_PRIORITIES=15
[uiT:1] taskState=1 taskCount=8
[myTask1:1] start Priority=2
[uiT:159] taskState=1 taskCount=8
[myTask1:202] end
[uiT:202] taskState=4 taskCount=8
[uiT:203] taskState=4 taskCount=7
[uiT:204] taskState=4 taskCount=7
[uiT:205] taskState=4 taskCount=7
[uiT:206] taskState=4 taskCount=7
[uiT:207] taskState=4 taskCount=7
[uiT:208] taskState=4 taskCount=7
[uiT:209] taskState=4 taskCount=7

タスク終了時に終了コードを設定する機能が有るのかどうか調べてみましたが、どうもなさそうです。
タスク終了時の終了コードが必要であれば、グローバル変数に残すことになります。
myTask1が終了してもタスクの数が7つもあります。
1つは自分自身として、後の6つのタスクは何なのか、気になります。

続く....