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
以下のデモプログラムは、ミューテックスを使って優先度が低、中、高の3つのタスクを動かした時の出力。上のデモプログラムでは40ms近辺で優先度の逆転が起きているが、今回は1行目辺りから見ていくと、およそ100ms間低い優先度のタスクの出力は行われていないが、優先度の高いタスクは10ms周期で出力している。低い優先度のタスクに、優先度の高いタスクの優先度が継承されたと思われる。
https://github.com/hamayanShowa-ele/ArduinoShare/tree/main/ESP32freeRTOS_TASK_ID_024_02
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 ) ); } }
以下のデモプログラムは、ミューテックスを使って優先度が低、中、高の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 ) ); } }
ITRONプログラミング入門 H8マイコンとHOSで始める組み込み開発
- 出版社/メーカー: オーム社
- 発売日: 2005/04/23
- メディア: Kindle版
リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))
- 作者: 高田 広章
- 出版社/メーカー: CQ出版
- 発売日: 2004/02
- メディア: 単行本
2018-03-08 11:15
nice!(0)
コメント(0)
コメント 0