SSブログ

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

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

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

排他制御について
〇 ミューテックス(とバイナリーセマフォ)、、、3

● 優先度の継承
FreeRTOSのミューテックスとバイナリーセマフォはすごく似ている。唯一の違いはミューテックスは優先度継承の機構を持つ点である。優先度継承は、優先度の逆転の負の側面を最小にする枠組みである。固定された優先度の逆転ではなく、単にその影響を軽減する。
ただ、優先度継承はシステムの振舞いの数学的な解析をより複雑にする。その為優先度継承の利用を避けられない状況以外での利用は薦められない。

優先度継承はトークン・ホルダーの優先度を一時的に、資源の利用を待つタスクの中でもっとも高い優先度と同じレベルに上げる。資源の利用が終わり、ミューテックスをGiveすれば、自動的に元の優先度に戻る。


以下のデモプログラムはバイナリーセマフォを使って優先度が低、中、高の3つのタスクを動かした時の出力。文字列に続く数値はmillis()の出力であり、図の1行目と2行目に100msの時間差が発生している。通常は優先度の高いタスクは10ms周期で出力するが、優先度の逆転が起きて優先度が中間のタスクに邪魔をされている。

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

volatile SemaphoreHandle_t sema;

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

  // Create binary semaphore
  sema = xSemaphoreCreateBinary();
  xSemaphoreGive( sema );  /* give one semaphore */

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

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

  /* configure take task3. */
  xTaskCreatePinnedToCore(
    upperPriorityTask,  /* task name */
    "",     /* task name string */
    configMINIMAL_STACK_SIZE,   /* stack size */
    NULL,   /* execute parameter */
    4,      /* task priority : 0 to 24. 0 is lowest priority. */
    NULL,   /* task handle pointer */
    1       /* core ID */
  );
  vTaskDelete( NULL );  /* delete loopTask. */
}

void loop()
{
}

void lowerPriorityTask( void *execParam )
{
  while( 1 )
  {
    xSemaphoreTake( sema, portMAX_DELAY );
    Serial.print( "lowerPriorityTask time = " ); Serial.println( millis(), DEC );
    xSemaphoreGive( sema );

    vTaskDelay( pdMS_TO_TICKS( 1 ) );
  }
}

void middlePriorityTask( void *execParam )
{
  while( 1 )
  {
    vTaskDelay( pdMS_TO_TICKS( 20 ) );
//    Serial.print( "middlePriorityTask time = " ); Serial.println( millis(), DEC );
    unsigned long baseMillis = millis();
    while( (millis() - baseMillis) < 100UL ) {}  /* never enter block state. */
  }
}

void upperPriorityTask( void *execParam )
{
  int count = 1;
  while( 1 )
  {
    xSemaphoreTake( sema, portMAX_DELAY );
    Serial.print( "upperPriorityTask time = " ); Serial.println( millis() ,DEC );
    xSemaphoreGive( sema );

    vTaskDelay( pdMS_TO_TICKS( 10 ) );
  }
}

ESP32_mutex_005.png



以下のデモプログラムは、ミューテックスを使って優先度が低、中、高の3つのタスクを動かした時の出力。上のデモプログラムでは40ms近辺で優先度の逆転が起きているが、今回は1行目辺りから見ていくと、およそ100ms間低い優先度のタスクの出力は行われていないが、優先度の高いタスクは10ms周期で出力している。低い優先度のタスクに、優先度の高いタスクの優先度が継承されたと思われる。

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

volatile xSemaphoreHandle mux;

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

  // Create mutex
  mux = xSemaphoreCreateMutex();

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

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

  /* configure take task3. */
  xTaskCreatePinnedToCore(
    upperPriorityTask,  /* task name */
    "",     /* task name string */
    configMINIMAL_STACK_SIZE,   /* stack size */
    NULL,   /* execute parameter */
    4,      /* task priority : 0 to 24. 0 is lowest priority. */
    NULL,   /* task handle pointer */
    1       /* core ID */
  );
  vTaskDelete( NULL );  /* delete loopTask. */
}

void loop()
{
}

void lowerPriorityTask( void *execParam )
{
  while( 1 )
  {
    xSemaphoreTake( mux, portMAX_DELAY );
    Serial.print( "lowerPriorityTask time = " ); Serial.println( millis(), DEC );
    xSemaphoreGive( mux );

    vTaskDelay( pdMS_TO_TICKS( 1 ) );
  }
}

void middlePriorityTask( void *execParam )
{
  while( 1 )
  {
    vTaskDelay( pdMS_TO_TICKS( 20 ) );
//    Serial.print( "middlePriorityTask time = " ); Serial.println( millis(), DEC );
    unsigned long baseMillis = millis();
    while( (millis() - baseMillis) < 100UL ) {}  /* never enter block state. */
  }
}

void upperPriorityTask( void *execParam )
{
  int count = 1;
  while( 1 )
  {
    xSemaphoreTake( mux, portMAX_DELAY );
    Serial.print( "upperPriorityTask time = " ); Serial.println( millis() ,DEC );
    xSemaphoreGive( mux );

    vTaskDelay( pdMS_TO_TICKS( 10 ) );
  }
}

ESP32_mutex_006.png


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:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

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

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