RX66N + FreeRTOSの環境で開発をしております。
FreeRTOSがらみの質問なので場違いかもしれませんが、アドバイスいただけたらお願いします。
まず、OSの設定としては
・プリエンプティブスケジュール(configUSE_PREEMPTION=1)
・タイムスライスOFF(configUSE_TIME_SLICING=0)
で使用しています。
同じ優先度のタスクAとタスクBがあり、タスクAがRunning、タスクBがBlocked状態とします。
この時タスクAがタスクBのBlocked状態を解除するシステムコールを呼んだとします。
タスクの状態としてはAがRunning、BがReadyになると思いますが、
タスクAがBlockedに入る前にタスクBに遷移するのは仕様ですか?
また、上記のように同じ優先度の2つのタスクがRunningとReadyステータスだった場合、
割込みやより優先度の高いタスクの実行により切り替わることはありますか?
同じ優先度でタイムスライスがオフであれば、実行中のタスクがBlockedに入るまでもう一方のタスクには
切り替わらないつもりでいたので戸惑っております。
(以前使用していたitron準拠のOSではそのような動きはしなかった認識です)
よろしくお願い致します。
■環境
・RX66N
・RX ファミリ Renesas FreeRTOS
・e2studio
・CC-RX v3
JoさんNoMaYさんシェルティさんこんにちは。ふぐりんです。
私も実験してみました。ちょっと長くなりますが、せっかく実験したんでご報告します。(じつは失敗談とか書きたいことがいっぱいあるんですが、時間がw)
【結果】うーん、Joさんのおっしゃる現象「タスクAがBlockedに入る前にタスクBに遷移する」は再現しませんでした。「タスクAがBlockedに入ったらタスクBに遷移する」でした。
【材料】機材:Target Board for RX65N環境:CS+/CCRX v3.05.00ソフト:kern-gt(sh-goto)さんのFreeRTOSデモを利用させていただきました。(楽ちんでした)FreeRTOS Ver10.1.1 DemoProject for Renesas RX65N (CS+,CC-RX)https://github.com/kern-gt/Demo_FreeRTOS_v10.1.1_for_Renesas_RX65N_with_CSplus_CC-RXあとmkogax(私)の GG for CCRX(EMU版) も追加してhttps://github.com/mkogax/GG_for_CCRXテストプログラムを組んで実験しました。
【実験】TaskG:無限ループ内で1msecディレイしながらコンソールチェック。コンソールからの指示でTaskGからイベントフラグセット。TaskA:無限ループ内でイベント待ち。イベント待ちタイムアウトは1msec。*カーネルtickは1000Hz(1msec周期)、タスク優先度はどちらも1(同じ)。
ソース抜粋:
void vTaskG(void *pvParameters) // TaskG { while(1) { gg_con_Check(); // console processing (returns immediately if nothing is done) GG_TP_OFF(100); // オシロのCH1をOFF vTaskDelay(1/portTICK_PERIOD_MS); } } int C_test(int argc, char **argv) // testコマンド実行部(コンソールから't'改行で実行) { GG_TP_ON(100); // オシロのCH1をON xEventGroupSetBits(xCreatedEventGroup, 1); // イベントフラグ(b0)をON GG_TP_OFF(100); // オシロのCH1をOFF GG_TP_ON(100); // オシロのCH1をON return 0; } void vTaskA(void *pvParameters) // TaskA { while(1) { // イベント待ち(自動クリア,TMO=1msec) xEventGroupWaitBits(xCreatedEventGroup, 1, 1, 1, 1/portTICK_PERIOD_MS); GG_TP_ON(903); // オシロのCH2をON dummy(500); // ダミー負荷(20usec弱) GG_TP_OFF(903); // オシロのCH2をOFF } }
結果:TaskGでイベントセットしたあとBlockedになったら(vTaskDelay()したら)、TaskAはRunningになる(xEventGroupWaitBits()から抜ける)。
TaskA(CH2=紫)は1msec周期でタイムアウトしたところ(カーネルtick)でONしますが、イベント発生すると1msec(カーネルtick)以外のところでONします。(TaskGのdelay抜けとTaskAのタイムアウトのどちらが先かは・・審議中)
拡大
ちなみに以下の条件で同じ結果でした。(1)configUSE_PREEMPTION=0,configUSE_TIME_SLICING=0(2)configUSE_PREEMPTION=1,configUSE_TIME_SLICING=0(3)configUSE_PREEMPTION=0,configUSE_TIME_SLICING=1(4)configUSE_PREEMPTION=1,configUSE_TIME_SLICING=1
【実験2】
タイムスライスはtick単位でしか観測してないと思うんで、あまり関係ないかも・・というのが私の感想です。でその確認でTaskGのdelay待ち無しの実験もしてみました。
下記3条件では、TaskAはピクリとも動きませんでいた。(1)configUSE_PREEMPTION=0,configUSE_TIME_SLICING=0(2)configUSE_PREEMPTION=1,configUSE_TIME_SLICING=0(3)configUSE_PREEMPTION=0,configUSE_TIME_SLICING=1
下記条件の時だけTaskAが動きました。(4)configUSE_PREEMPTION=1,configUSE_TIME_SLICING=1
TaskAは1msec周期で動くだけに見えます。(イベントセットと無関係?)
そこでTaskAのタイムアウトを3msecに変えたら・・TaskAは3msec周期で動いてますが、TaskGにイベントセットされると、3msec周期と無関係に直後のtickでTaskAに切り替わってます。
うーん、なんかきちんと説明付けられる気がするけどもうおなかいっぱい・・
ふぐりんさん、こんにちは。
お忙しいなか実験していただきありがとうございます。こちらでもこのような単純ケースで確認してみたいと思いながらなかなか時間がとれずできていませんでした。質問だけして何も進められておらず、皆さまには申し訳ありません。
再現しませんでしたか。そうなるとより優先度の高いタスクでOSのシステムコールが使われることが影響しているのかもしれません。
OSの設定関連だと、configUSE_PREEMPTION、configUSE_TIME_SLICING以外に関係しそうなものはないですよね。
Joさんこんにちは!だいたい今の季節はヒマなのでバッチこいです。とはいえ私も普段はNORTiとかTOPPERSとか使ってるんで、NoMaYさんシェルティさんみたいなFreeRTOSの専門家じゃないです。すいませんwうーん、他のタスクとか割込みが関係するかもですか・・ないともいえないですかねえ。昨晩からFreeRTOSの中を(わからないなりに)ちょっとだけのぞいてみて、Yieldというのを発行する条件判断がそのへんを左右しそうなんですが、Yield発行(予約)しても、その実行処理(ソフト割込み)が入るまでに他の割り込みによってさらに状態が変化する可能性はあるわけで・・「ほんとにこれどうなるんだ?」ってのが今のところの感想です。読込みが浅いからとは思いますが・・ちなみに chatGPT で 「RTOSでいうところのyieldってなんですか?」って質問すると結構詳しく教えてくれました。(ほんとかどうかはわかんないけど)