マルチタスクって何ですか…?
こうした悩みを解決します。
以前、delay関数を深堀りすると、リアルタイムOSにたどり着くという記事を書きました。
そこで出てきたタスクという概念。実際に動かして学んでいこうというのが本記事です。
タスクとは
タスクというのは一連の処理をまとめたものです。
これまではmain関数から始まり、通信・演算・制御などの機能を割込みを駆使して回すのが一般的でした。
逐次的に処理が行われ、これがいわゆるシングルタスクです。
一方で、処理毎にタスクという形で並列的に配置し、1つのプログラムを構成しているのがマルチタスクです。
シングルタスクの問題点
で、シングルタスクは何が問題かと言うと、何かを処理している際に他の処理ができない、ということです。
たとえば、演算の割込み内で重い計算させているうちに、Bluetooth通信している機器から文字が送られてきたとします。
割込み処理中の計算が終わるまでバッファに受信文字列がたまり続け、文字化けやオーバーフローするなど動作不良を起こすことがあります。
だから、割込み内の処理は最低限に、と先輩にはよく言われたものです。
その点、マルチタスクにすると機能毎に切り分けられるので、互いに影響を及ぼす可能性が低くすることができるのは利点です。
タスクの作り方
xTaskCreatePinnedToCore( task_one ,"task_one",2048,NULL,2,&taskhandle[0],0);
こんな感じでタスクを作ることができます。
引数の先頭から、
タスクコード(=関数名)、名称(何でもOK)、スタックサイズ、タスクパラメータ、タスクの優先順位、タスクハンドル、コア番号
となっています。
詳細は公式を参照ください。
作ったタスクは下記のように関数を宣言して使います。
void task_one(void *args) {
while (1) {
delay(200);
Serial.print("a");
}
}
マルチタスクの動作
マルチタスクと言っても、複数のアドレスを参照できないので、複数のタスクが同時に動いているわけではないです※。
(※シングルコアの場合。マルチコアの場合はコアの数だけ同時に動きます)
タイムスライスと言って、タスク毎に処理時間を区切って切替えながら実行する仕組みとなっています。
ESP32では、CONFIG_FREERTOS_HZで定義される時間間隔(通常は1ms)でタスクが切り替えられます。
タスク間通信
編集中
コア間通信
編集中
コメント