ESP32はRTOSができるらしい、、、
その前に、ESP32はCPUコアが二つ搭載されているらしい。
たまにこの2つのコアをしてマルチタスクと呼ばれたりもしているが、もちろんそれぞれのコアで何かが動いていればマルチタスクですが、それとは別にFreeRTOSが既に動いているとの話。
なので、ESP IDF環境で構築されたESP Arduinoも、FreeRTOSが動いているとのこと。
2つのコアの内、具体的にはRF関連の処理は主にコア0、setupやloopはコア1で動いている。
FreeRTOSのWikiPedia
https://ja.wikipedia.org/wiki/FreeRTOS
ここにはまだ、ESP32のコアの天使るなんとかは掲載されていないみたいだ。
μiTRONなら、RTOSが起動するまでにコンフィギュレーションをするところだけど、すでに動いているのでその辺はすっ飛ばして動かすことができる。
さっそく適当なタスクを生成してみよう。
ここでは2番の端子にLEDを接続しているとする。
1.TaskHandle_t構造体が、ITRONで言うところのTask Control Blockなのだろう。
なので、タスクの数だけ変数が必要となる。
2.関数xTaskCreatePinnedToCoreの引数に、タスクに関する情報をポチポチ入れていく事となる。
それぞれの引数を見ていくと、
1番目が起動時関数
2番目が何かのエイリアス?
3番目がタスクスタックサイズで、あまり小さいとヤバいと思う。
※サイズはワードサイズらしく、ESP32が32bitCPUであれば1ワード=4byteとなる。
4番目が起動時引数。但し優先度を1にすると何故か正しく引き渡せない。
5番目がタスクプライオリティで1~25まで指定可能であり、数字が小さいほど優先度が低いらしい
6番目がどのコアを使うかを指定しており、この引数のみESP32独自の様子。
3.先にも書いたけれどloop自体もタスクであり、初期化時に4096×4byteのスタックを与えられて、優先度1でコア1で動作している。と思ったら4096ではなく8192と書かれているソースも見つけてしまって、混乱している、、、
4.delay関数はブロッキングされておらず、別タスクへのディスパッチが行われるdly_tskと同じ動作をする。なので、安心して待ちにはdelay関数が使える。
5.作成したledBlinkTaskの引数で、先の起動時引数を受け取っている。
※動きだけ見れば、まったくマルチタスクである実感は無いけれど、マルチタスクであろう。
※xTaskCreatePinnedToCore関数で引き渡した情報を、タスク中から参照する方法が有りそうだけれど、イマイチよく判らない。FreeRTOSのマニュアルを読まないとダメか。
※優先度を1にすると何故か実行時引数が正しく渡せない、、、なぜ?とりあえず2以上にする事。
※まあでも、これだけ判ればマルチタスクし放題だね!
![ITRONプログラミング入門 H8マイコンとHOSで始める組み込み開発 ITRONプログラミング入門 H8マイコンとHOSで始める組み込み開発]()
![リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17)) リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))]()
その前に、ESP32はCPUコアが二つ搭載されているらしい。
たまにこの2つのコアをしてマルチタスクと呼ばれたりもしているが、もちろんそれぞれのコアで何かが動いていればマルチタスクですが、それとは別にFreeRTOSが既に動いているとの話。
なので、ESP IDF環境で構築されたESP Arduinoも、FreeRTOSが動いているとのこと。
2つのコアの内、具体的にはRF関連の処理は主にコア0、setupやloopはコア1で動いている。
FreeRTOSのWikiPedia
https://ja.wikipedia.org/wiki/FreeRTOS
ここにはまだ、ESP32のコアの天使るなんとかは掲載されていないみたいだ。
μiTRONなら、RTOSが起動するまでにコンフィギュレーションをするところだけど、すでに動いているのでその辺はすっ飛ばして動かすことができる。
さっそく適当なタスクを生成してみよう。
ここでは2番の端子にLEDを接続しているとする。
TaskHandle_t taskHandle[1]; /* typedef void * TaskHandle_t; */ const int ledPin = 2; void setup() { Serial.begin( 115200 ); /* configure led blink task. */ unsigned long executeParameter = 1000UL; /* delay time */ xTaskCreatePinnedToCore( ledBlinkTask, /* task name */ "ledBlinkTask", /* task name string */ 256, /* stack size */ &executeParameter, /* execute parameter */ 2, /* task priority : 0 to 24. 0 is lowest priority. */ &taskHandle[0], /* タスクハンドルポインタ */ 1 /* core ID */ ); } void loop() { Serial.println( "hello world." ); delay( 1000 ); } /* led blink */ void ledBlinkTask( void *execParam ) { unsigned long dly = *(unsigned long *)execParam; pinMode( ledPin, OUTPUT ); digitalWrite( ledPin, LOW ); /* turn off led. */ while( 1 ) { digitalWrite( ledPin, ( digitalRead(ledPin) ) ? LOW : HIGH ); /* toggle led. */ delay( dly ); } }
1.TaskHandle_t構造体が、ITRONで言うところのTask Control Blockなのだろう。
なので、タスクの数だけ変数が必要となる。
2.関数xTaskCreatePinnedToCoreの引数に、タスクに関する情報をポチポチ入れていく事となる。
それぞれの引数を見ていくと、
1番目が起動時関数
2番目が何かのエイリアス?
3番目がタスクスタックサイズで、あまり小さいとヤバいと思う。
※サイズはワードサイズらしく、ESP32が32bitCPUであれば1ワード=4byteとなる。
4番目が起動時引数。
5番目がタスクプライオリティで1~25まで指定可能であり、数字が小さいほど優先度が低いらしい
6番目がどのコアを使うかを指定しており、この引数のみESP32独自の様子。
3.先にも書いたけれどloop自体もタスクであり、初期化時に4096×4byteのスタックを与えられて、優先度1でコア1で動作している。と思ったら4096ではなく8192と書かれているソースも見つけてしまって、混乱している、、、
4.delay関数はブロッキングされておらず、別タスクへのディスパッチが行われるdly_tskと同じ動作をする。なので、安心して待ちにはdelay関数が使える。
5.作成したledBlinkTaskの引数で、先の起動時引数を受け取っている。
※動きだけ見れば、まったくマルチタスクである実感は無いけれど、マルチタスクであろう。
※xTaskCreatePinnedToCore関数で引き渡した情報を、タスク中から参照する方法が有りそうだけれど、イマイチよく判らない。FreeRTOSのマニュアルを読まないとダメか。
※まあでも、これだけ判ればマルチタスクし放題だね!

ITRONプログラミング入門 H8マイコンとHOSで始める組み込み開発
- 出版社/メーカー: オーム社
- 発売日: 2005/04/23
- メディア: Kindle版

リアルタイムOSと組み込み技術の基礎―実践μITRONプログラミング (TECHI (Vol.17))
- 作者: 高田 広章
- 出版社/メーカー: CQ出版
- 発売日: 2004/02
- メディア: 単行本