ESP32でマルチタスクを行う為の、とりあえずここまで判った事 by freeRTOS 21タスク目 [ESP32]
現在実用ガイドを読みながら編集中、、、書いて有る事を信用しない様に!
http://www.profdong.com/elc4438_spring2016/USINGTHEFREERTOSREALTIMEKERNEL.pdf
ESP32はRTOSができるらしい、、、
排他制御について
〇 クリティカルセクションとスケジューラーの一時停止、、、2
● スケジューラーの一時停止
クリティカルセクションはスケジューラーの一時停止でも実現できる。スケジューラーの一時停止はスケジューラーの”Locking”とも知られている、、、?
基本的にクリティカルセクションは、割り込みや他のタスクからコードがアクセスされる領域を保護する。クリティカルセクションの実装をスケジューラーの一時停止で行った場合、他のタスクからのみ領域を保護する。この事はつまり割り込みからのアクセスは有効のままである。
単純に割り込み禁止で実現するクリティカルセクションの実装でその処理の実行時間が掛かる場合、スケジューラーの一時停止で実現するクリティカルセクションに置き換える事ができる。しかしスケジューラーの一時停止ではスケジューラーの再開に時間が掛かるので、それぞれの方法についてどちらを選ぶかは十分考慮する必要がある。
スケジューラーはvTaskSuspendAll関数の呼び出しで一時停止させられる。その時点からコンテキストスイッチ(タスクの切り替え)は停止するが、割り込みは許可されたままである。スケジューラーが一時停止中に割り込みがコンテキストスイッチを要求したなら、コンテキストスイッチの要求はペンディングされ、スケジューラの再開時に実行される。
FreeRTOSの関数はスケジューラーの一時停止中に使われるべきではない。
※一時停止の解除の関数は別だろうけれど。
スケジューラーの再開はxTaskResumeAll関数を呼ぶことで行われる。
● vTaskSuspendAll関数
プロトタイプは以下になる。
● xTaskResumeAll関数
プロトタイプは以下になる。
(1) 戻り値:スケジューラーが一時停止中に受けたコンテキストスイッチの要求はペンディングされ、スケジューラーが再開されたタイミングで行われる。事前にペンディングされたコンテキストスイッチはxTaskResumeAll関数の終了直前に実行され pdTRUEを返す。それ以外のケースでは pdFALSEを返す。
vTaskSuspendAllの呼び出しとxTaskResumeAllの呼び出しはカーネルによってカウントされている。カウントが0に戻る事で、スケジューラーは再開される。
使い方は以下の様になる。
※μiTRONで言うところのdis_dsp、ena_dspに該当すると思う。
前回の例題 http://hamayan.blog.so-net.ne.jp/2018-03-06 を作りかえてtaskENTER_CRITICALをvTaskSuspendAllに、taskEXIT_CRITICALをxTaskResumeAllとしたものを動かしてみた。
https://github.com/hamayanShowa-ele/ArduinoShare/tree/main/ESP32freeRTOS_TASK_ID_021
が、リセットを繰り返し正常に動かない。
をコメントアウトするとリセットされないので、Serial.printと何かあるのかもしれない。
http://www.profdong.com/elc4438_spring2016/USINGTHEFREERTOSREALTIMEKERNEL.pdf
ESP32はRTOSができるらしい、、、
排他制御について
〇 クリティカルセクションとスケジューラーの一時停止、、、2
● スケジューラーの一時停止
クリティカルセクションはスケジューラーの一時停止でも実現できる。スケジューラーの一時停止はスケジューラーの”Locking”とも知られている、、、?
基本的にクリティカルセクションは、割り込みや他のタスクからコードがアクセスされる領域を保護する。クリティカルセクションの実装をスケジューラーの一時停止で行った場合、他のタスクからのみ領域を保護する。この事はつまり割り込みからのアクセスは有効のままである。
単純に割り込み禁止で実現するクリティカルセクションの実装でその処理の実行時間が掛かる場合、スケジューラーの一時停止で実現するクリティカルセクションに置き換える事ができる。しかしスケジューラーの一時停止ではスケジューラーの再開に時間が掛かるので、それぞれの方法についてどちらを選ぶかは十分考慮する必要がある。
スケジューラーはvTaskSuspendAll関数の呼び出しで一時停止させられる。その時点からコンテキストスイッチ(タスクの切り替え)は停止するが、割り込みは許可されたままである。スケジューラーが一時停止中に割り込みがコンテキストスイッチを要求したなら、コンテキストスイッチの要求はペンディングされ、スケジューラの再開時に実行される。
FreeRTOSの関数はスケジューラーの一時停止中に使われるべきではない。
※一時停止の解除の関数は別だろうけれど。
スケジューラーの再開はxTaskResumeAll関数を呼ぶことで行われる。
● vTaskSuspendAll関数
プロトタイプは以下になる。
void vTaskSuspendAll( void );
● xTaskResumeAll関数
プロトタイプは以下になる。
portBASE_TYPE xTaskResumeAll( void );
(1) 戻り値:スケジューラーが一時停止中に受けたコンテキストスイッチの要求はペンディングされ、スケジューラーが再開されたタイミングで行われる。事前にペンディングされたコンテキストスイッチはxTaskResumeAll関数の終了直前に実行され pdTRUEを返す。それ以外のケースでは pdFALSEを返す。
vTaskSuspendAllの呼び出しとxTaskResumeAllの呼び出しはカーネルによってカウントされている。カウントが0に戻る事で、スケジューラーは再開される。
使い方は以下の様になる。
vTaskSuspendAll(); /* suspend scheduler */ PORTA |= 0x01; xTaskResumeAll(); /* resume scheduler */
※μiTRONで言うところのdis_dsp、ena_dspに該当すると思う。
前回の例題 http://hamayan.blog.so-net.ne.jp/2018-03-06 を作りかえてtaskENTER_CRITICALをvTaskSuspendAllに、taskEXIT_CRITICALをxTaskResumeAllとしたものを動かしてみた。
https://github.com/hamayanShowa-ele/ArduinoShare/tree/main/ESP32freeRTOS_TASK_ID_021
void setup() { Serial.begin( 115200 ); Serial.println( "FreRTOS Test." ); /* 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( upperPriorityTask, /* 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 */ ); vTaskDelete( NULL ); /* delete loopTask. */ } void loop() { } void lowerPriorityTask( void *execParam ) { int count = 1; while( 1 ) { vTaskSuspendAll(); Serial.print( "lowerPriorityTask count = " ); Serial.println( count++,DEC ); xTaskResumeAll(); vTaskDelay( pdMS_TO_TICKS( 1 ) ); } } void upperPriorityTask( void *execParam ) { int count = 1; while( 1 ) { Serial.print( "upperPriorityTask count = " ); Serial.println( count++,DEC ); vTaskDelay( pdMS_TO_TICKS( 10 ) ); } }
が、リセットを繰り返し正常に動かない。
Serial.print( "lowerPriorityTask count = " ); Serial.println( count++,DEC );
をコメントアウトするとリセットされないので、Serial.printと何かあるのかもしれない。
ITRONプログラミング入門 H8マイコンとHOSで始める組み込み開発
- 出版社/メーカー: オーム社
- 発売日: 2005/04/23
- メディア: Kindle版
リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))
- 作者: 高田 広章
- 出版社/メーカー: CQ出版
- 発売日: 2004/02
- メディア: 単行本
2018-03-07 12:59
nice!(0)
コメント(0)
コメント 0