SSブログ

ESP32でマルチタスクを行う為の、とりあえずここまで判った事 by freeRTOS 30タスク目 [ESP32]

現在実用ガイドを読みながら編集中、、、ある事ない事書いちょりまっす!
http://www.profdong.com/elc4438_spring2016/USINGTHEFREERTOSREALTIMEKERNEL.pdf

ESP32はRTOSができるらしい、、、

タスクスタックの使用状況を動的に知る。
この辺り http://hamayan.blog.so-net.ne.jp/2018-02-18-1 でタスクの状態を知ることができず、困ったなぁ、、、と言う話の解決の1つ。

関数xTaskGetCurrentTaskHandleは、引数のタスクのスタックがあとどれ位残っているかをByte単位で答えてくれる。プロトタイプは以下になる。
  unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );

(1) 引数xTaskは、スタックサイズの残りを知りたいタスクのハンドル。

(2) 戻り値:タスクスタックの内、使用されていないスタックサイズをByte単位で答える。

loopTaskの様にタスクハンドルを渡さずに生成したタスクでは、そのタスクのハンドルをカーネルから得る必要がある。関数xTaskGetCurrentTaskHandleは実行中のタスクのハンドルを答える。プロトタイプは以下になる。
  TaskHandle_t xTaskGetCurrentTaskHandle( void );

(1) 戻り値:実行中のタスクハンドル。


ここで http://hamayan.blog.so-net.ne.jp/2018-03-08-4 作成したデモプログラムの、それぞれのタスクのスタック使用状況を簡単にモニターしてみる。

https://github.com/hamayanShowa-ele/ArduinoShare/tree/main/ESP32freeRTOS_TASK_ID_030

xQueueHandle que;
xTaskHandle taskHandle[ 3 ];

void setup()
{
  Serial.begin( 115200 );
  Serial.println( "FreRTOS Test." );

  /* create data queue */
  que = xQueueCreate( 10, sizeof(char *) );

  /* configure take task1. */
  xTaskCreatePinnedToCore(
    gateKeeperTask,  /* task name */
    "",     /* task name string */
    configMINIMAL_STACK_SIZE,   /* stack size */
    NULL,   /* execute parameter */
    1,      /* task priority : 0 to 24. 0 is lowest priority. */
    &taskHandle[ 0 ],   /* task handle pointer */
    1       /* core ID */
  );

  /* configure take task2. */
  xTaskCreatePinnedToCore(
    task2,  /* task name */
    "",     /* task name string */
    configMINIMAL_STACK_SIZE,   /* stack size */
    NULL,   /* execute parameter */
    2,      /* task priority : 0 to 24. 0 is lowest priority. */
    &taskHandle[ 1 ],   /* task handle pointer */
    1       /* core ID */
  );

  /* configure take task3. */
  xTaskCreatePinnedToCore(
    task3,  /* task name */
    "",     /* task name string */
    configMINIMAL_STACK_SIZE,   /* stack size */
    NULL,   /* execute parameter */
    3,      /* task priority : 0 to 24. 0 is lowest priority. */
    &taskHandle[ 2 ],   /* task handle pointer */
    1       /* core ID */
  );
}

void loop()
{
  unsigned portBASE_TYPE stzckSize;
  stzckSize = uxTaskGetStackHighWaterMark( taskHandle[ 0 ] );
  Serial.print( "task1 remain stack size = " ); Serial.println( stzckSize, DEC );

  stzckSize = uxTaskGetStackHighWaterMark( taskHandle[ 1 ] );
  Serial.print( "task2 remain stack size = " ); Serial.println( stzckSize, DEC );

  stzckSize = uxTaskGetStackHighWaterMark( taskHandle[ 2 ] );
  Serial.print( "task3 remain stack size = " ); Serial.println( stzckSize, DEC );

  TaskHandle_t loopTaskHandle = xTaskGetCurrentTaskHandle();
  stzckSize = uxTaskGetStackHighWaterMark( loopTaskHandle );
  Serial.print( "loopTask remain stack size = " ); Serial.println( stzckSize, DEC );

  vTaskDelay( pdMS_TO_TICKS( 1000 ) );
}

void gateKeeperTask( void *execParam )
{
  char buffer[ 128 ];
  while( 1 )
  {
    char *pvBuffer;
    xQueueReceive( que, (void *)&pvBuffer, portMAX_DELAY );
    strcpy( buffer, pvBuffer );
    Serial.print( buffer );
//    Serial.print( pvBuffer );
  }
}

void task2( void *execParam )
{
  static const char *msg = "this is task2.\r\n";
  while( 1 )
  {
    xQueueSendToBack( que, (const void *)&msg, portMAX_DELAY );
    vTaskDelay( pdMS_TO_TICKS( 250 ) );
  }
}

void task3( void *execParam )
{
  static const char *msg = "this is task3.\r\n";
  while( 1 )
  {
    xQueueSendToBack( que, (const void *)&msg, portMAX_DELAY );
    vTaskDelay( pdMS_TO_TICKS( 500 ) );
  }
}

ESP32_stackCheck_001.png

いやいやしかし、gateKeeperTask、task2、task3の3つのタスクには4kbyteのスタック、loopTaskには32kbyteのスタックを設定しているにも関わらず、この残り量のしょぼさは何だろう?
μiTRONであればtask2、task3辺りなら数十~数百Byte程度の設定で済みそうな気がするが。

※いやぁ、でも、目安程度しか使えない気がするなぁ、、、

※スタックサイズがでかすぎる点は、ここでも話題になっているなぁ、、、
https://esp32.com/viewtopic.php?f=2&t=900
あれぇ???ESP32のスタック単位はWORDではなくBYTEって書いてあるぞ!
スタックに使われている型のStackType_tは、portmacro.hの中で以下になっている、、、
#define portSTACK_TYPE  uint8_t

typedef portSTACK_TYPE  StackType_t;

あーん、うーん、なぜFreeRTOS公式と違う!

https://github.com/espressif/esp-idf/blob/master/components/freertos/readme_xtensa.txt
Then, you must also make sure to allocate extra space on the stack for each task that will use the C library reentrant functions. This extra space is to be allocated over and above the actual stack space required by the task itself. The define XT_STACK_EXTRA_CLIB specifies the amount of extra space to be added on to the stack to allow saving the context for the C library as well as the coprocessors if any. E.g. if your task requires 2000 bytes of stack space, you must allocate (2000 + XT_STACK_EXTRA_CLIB) bytes for the stack.


Interrupt Stack --------------- Beginning with port version 1.2, the port uses a separate interrupt stack for handling interrupts. Thus, it is no longer necessary for each task to reserve space on its stack to handle interrupts. The size of the interrupt stack is controlled by the parameter "configISR_STACK_SIZE" defined in FreeRTOSConfig.h. Define this carefully to match your system requirements.


※APIにxTaskGetHandle()やpcTaskGetName()は存在していない、、、


ITRONプログラミング入門 H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門 H8マイコンとHOSで始める組み込み開発

  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/23
  • メディア: Kindle版



図解 μITRONによる組込みシステム入門(第2版)

図解 μITRONによる組込みシステム入門(第2版)

  • 作者: 武井 正彦
  • 出版社/メーカー: 森北出版
  • 発売日: 2018/02/17
  • メディア: 単行本(ソフトカバー)



μITRON4.0標準ガイドブック

μITRON4.0標準ガイドブック

  • 作者:
  • 出版社/メーカー: パーソナルメディア
  • 発売日: 2001/11/01
  • メディア: 単行本(ソフトカバー)



リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))

リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))

  • 作者: 高田 広章
  • 出版社/メーカー: CQ出版
  • 発売日: 2004/02
  • メディア: 単行本



nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。