ことの顛末
自分がソフトウェア開発を仕事でするようになり、既に40年を超えており、当初はOSなんかないマイコンのプログラムをゼロから作っていました。
いまは様々な開発環境が存在し、その中でも初心者でも入門しやすい
Arduino IDE が存在します。
ここ数年、この開発環境でプログラムを書くことが増えてきており、本当に便利になったと思っています。
でも、開発を続ける中で
「これ、なにか別のプログラムがどこかで動いているんじゃないか?」
と感じることが出てきています。
実際、マイコンプログラムの場合は、最初に様々な初期設定プログラムを書いてマイコンの状態を準備させ、その後に print("hello wold")みたいなプログラムが実行できます。
だから、容易に「めんどくさいことはみんなArduino IDEがやってくれるんだな」と思っていました。
これまでリアルタイム処理は自分でタイマー割り込み使って、イベントを監視し、イベント条件が発生した時、対応するプログラムを処理するという感じでプログラムを作ってきました。
今回、Arduino UNO R4 を購入したことで、FreeRTOS を使ってみようと考えました。
で、サンプルプログラムを読んで、え?これどうなってるん?と最初に感じたのは
loop()関数です。
ここに書くプログラムって for( ; ; )
や do{}while();
等の無限ループという記述はしないんですよね。
つまり、見た目は一回処理したら抜けるプログラムなんです。
で、loop()の最後の命令と、最初の命令の間に、なにかやっているんじゃないか?と考え
他に聞く人もいないのでChatGPT先生に聞いてみました😁
ChatGPT先生への質問
Arduino IDE における loop() について、通常の関数の記述であれば、繰り返さないプログラムであっても loop関数であれば無限に実行されます。この場合、処理の最後の命令後、関数内の先頭の命令に処理が移動する間に、なにかシステムでプログラムが実行されていたりしますか?
との問に、ChatGPT先生は次の様に返してくれました。
ChatGPT先生の回答
Arduino IDEのloop()
関数は、Arduinoボード上で実行されるメインループです。この関数は無限に実行され、処理の最後に到達すると、次のループの開始時に再度実行されます。
loop()
関数が最後の命令を実行し、関数の先頭に戻るまでの間に、Arduinoボード上でさまざまなシステムタスクや処理が実行されます。これには以下のようなことが含まれます:
-
割り込み処理: Arduinoボードは、割り込みを処理するためのハードウェアを備えています。割り込みは、外部からの信号やタイマーなどのイベントに応答するために使用されます。
loop()
関数の実行中に割り込みが発生した場合、Arduinoは割り込み処理を実行し、適切な割り込みハンドラを呼び出します。割り込み処理が終了すると、loop()
関数が再開されます。 -
タイマーイベントの処理: Arduinoボード上のタイマーは、一定の間隔でイベントを発生させることができます。これらのイベントは、
loop()
関数の実行中に発生する可能性があります。タイマーイベントが発生した場合、関連するタイマー割り込みハンドラが実行されることがあります。 -
シリアル通信の処理: Arduinoボードは、シリアルポートを介してコンピュータや他のデバイスとの通信を行うことができます。
loop()
関数の実行中にシリアル通信が発生した場合、受信データの処理や送信データのバッファリングなどが行われることがあります。 -
タスクスケジューリング: Arduinoボード上でマルチスレッドやタスクベースの処理を実行する場合、
loop()
関数の実行中に他のタスクがスケジュールされる可能性があります。タスクスケジューリングにより、異なるタスク間で処理時間が共有されます。
これらのシステムタスクや処理は、loop()
関数の実行と並行して実行されるため、Arduinoボード上でのさまざまな動作を維持します。loop()
関数の実行が速すぎて他の処理を妨げる場合、delay()
関数を使用して適切な待機時間を設定するなどの方法で調整することができます。
ただし、Arduino IDEのloop()
関数は、単一のスレッドで実行されるため、マルチスレッドプログラミングの利点や制御フローを提供するわけではありません。したがって、プログラムがloop()
関数を実行中である限り、他のタスクが並行して実行されるわけではありません。
ということでした。
そして更に、続けて次の質問を投げてみました
ChatGPT先生への続いての質問
FreeRTOS実装時は、FreeRTOSの処理に必要なプログラムがその時に実行されると考えてよいですか?
この問に関して
ChatGPT先生の回答
はい、FreeRTOSを使用する場合、FreeRTOSのタスクスケジューラと関連する処理が実行されます。FreeRTOSはリアルタイムオペレーティングシステムであり、タスクのスケジューリングやコンテキストの切り替え、割り込み処理などを管理するフレームワークです。
FreeRTOSのタスクスケジューラは、vTaskStartScheduler()
が呼び出された時点で開始され、タスクの優先度と実行時間を制御します。各タスクはスケジューラによって割り当てられ、タスク間で実行が切り替わります。
loop()
関数は通常、FreeRTOSのタスクの1つとして実装されます。この場合、FreeRTOSのスケジューラによってloop()
タスクが割り当てられ、他のタスクとの間で実行が切り替わります。各タスクは割り当てられた優先度に従って順番に実行されます。
FreeRTOSでは、loop()
関数以外にも複数のタスクを作成できます。各タスクは異なる処理を担当し、スケジューラによって実行される順序が管理されます。
したがって、FreeRTOSを使用する場合、FreeRTOSのタスクスケジューラによってタスクが実行され、各タスクの実行が切り替わると考えることができます。このように、FreeRTOSは複数のタスクを並行して実行することで、リアルタイム処理やタスクの優先順位を管理します。
でした。
まとめ
やはり、なにかやってました😁
割り込み等の処理をやっている様ですね。
とても勉強になりました😀
それにしても、質問文、ちょっとむずかしいかな?と思ったのですが
しっかりと回答してくれる ChatGPT先生は凄いです!
更に関連質問を続けてすると、その前の回答を踏まえた回答をしてくれるわけです。
普通に人と会話しているのと変わりません!
これまで分からないことがあると、色々な言葉でググって回答を探したものですが
ChatGPT先生なら即座に欲しい回答してくれるので本当に助かってます👍