2017-01-27 16 views
1

私はFreeRTOSを私のプロジェクトに使用していますが、私はドキュメントを読んでいます。理解できないことがあります。 スケジューラは仕事を実行し、イベントを待っていたタスクのブロックを解除し、準備完了状態にある優先度の高いタスクを選択するように、目盛り割り込みがトリガされるとコンテキストが切り替わることを知っています。しかし、ティック割り込みの前にタスクがブロックするとどうなりますか?このドキュメントでは、コンテキスト切り替えが即座に行われることを示唆しているようです(たとえば、vTaskDelay()を呼び出してCPUタイムスライスを解放する優先順位が異なる2つのタスク)。それはどうやって起こるの?私は検索しましたが、私の質問に対する答えは見つかりませんでした。FreeRTOSコンテキスト切り替え

EDIT FreeRTOS(SAMD21のCortex-M0 +)の私のポートにportYIELD()マクロがので、これは、スケジューラの実行とは別に(コンテキスト切り替えを実行するために使用される機構であり、単にSVCall例外を要求することに使用されますティック割り込みに)?

+1

あなたが求めているが、それはタイムスライスがオーバーされます前に、スレッドがプロセッサを放棄した場合、RTOSはすぐにスケジューラを実行する必要があります正確にわかりません。 –

+0

@FiddlingBitsはい、それは私が思うものですが、それの痕跡がドキュメントにありません。これは、定期的なティックごとに実行されるISRについてのみ話しますが、ティックの間でコンテキストの切り替えはどうなりますか?スケジューラが引き継ぎ、コンテキスト切り替えを実行しますか?もしそうなら、割込み(ソフトウェア)はそれを行うために起動しますか? – Luca

+0

SVCは、最新のM0ポートでは使用されなくなりました。しかし私は、SVC割り込みが実際のコンテキスト切り替えを行うためにPendSV割り込みをトリガしていることを期待しています。 –

答えて

3

taskYIELDに関するドキュメントがあります。この関数はコンテクストの切り替えを要求するために使うことができるので、ダニを待つ必要はありません。コンテキスト切り替えは特権操作であるため、ソフトウェア割り込みによって行われることがよくあります。あなたの場合、PendSVとSVCall。

すべてのタスクがブロックされている場合(例:vTaskDelay)、FreeRTOSはIdle Taskを実行しています。 vTaskDelayは内部でportYIELDを使用してコンテキスト切り替えを要求します。現在のタスクを続行する方法がないためです。

また、そのモードでFreeRTOSを理解するには、Preemptive multitaskingについて知っておく必要があります。

編集2016年1月29日:

  • 呼び出し遅延機能は、内部taskYIELD/portYIELDを呼び出す原因となります。したがって、あなたの現在のタスクはブロックされ、FreeRTOSは実行可能なタスクがない場合、実行可能(ブロックされていない)またはアイドルタスクに再優先します。
  • xQueueReceiveには2つの可能性があります。キューにはいくつかの要素があるため、POPedされています。キューに要素がないため、タスクはblocked stateに切り替えられ、YIELDが呼び出されるため、FreeRTOSは別のタスクに再スケジュールします。
  • xQueueSendには2つの可能性があります。キューに空きがないため、スペースがなくなるまでタスクはブロックされます。空の要素が少なくとも1つあるため、キューにプッシュすることができます。

キューからの要素またはキューからの要素の受信は、他のより優先度の高いタスク、つまりopositeを実行しているが、現在ブロックされています。 FreeRTOSはすぐに再スケジュールします。

これは割り込みハンドラからも行うことができます。あなたはハンドラタスクを持つことができます、それはいくつかのキューを待っています。割り込みから、いくつかの要素をキューに入れます。割り込みが終了すると、FreeRTOSはそのキューで待機しているタスクに再スケジュールされます。そのタスクに十分高い優先度を持つための前提条件があります。これは、短時間の操作であるため、割り込みではあまり処理していない、クリーンアップしてキューにアイテムを送信するだけの利点があります。 割込みの処理は、xTimerPendFunctionCallFromISRでも行うことができます。これは、割込みを処理するための別の方法です。

FreeRTOS fundamentalsもお読みください。そこにはいくつかの章があり、それは読解をinterrestingです。

+0

タスクがブロックする場合は、taskYIELD()を呼び出す必要はありません。タスクがブロックされている場合、どうすればよいですか? – Richard

+0

タスクがブロックすると、ブロックされているため、タスクから何かを呼び出す方法がありません。 RTOSはブロックされたタスクを実行していません。 – j123b567

1

TaskDelayなどのOSコールやアイテムのキューへの送信やリソースの解放が発生すると、他のタスクが実行可能になった場合にOSが動作し、優先度の高いタスクが実行可能な場合は、現在のタスクを控除します。基本的には、実行準備が整っている最優先タスクが実行されます。タイムスライスは、等しい優先度と最高優先度の2つ以上のタスクが実行可能な場合にのみ発生します。

はい割り込みが実行されます。 cortex-mでは、PENDSV割り込みはコンテキストスイッチを実行します。あなたは、現在のタスクブロックを実行するときに別のタスクに切り替えるには何をすべきか

+0

[OK]を、私はvTaskDelay()現在のタスクがtaskYield()を呼び出し、(ソフトウェア)を呼び出すスケジューラをさせる、トリガされた中断した場合、その作業を行います。アイテムをキューに入れた場合(またはバイナリセマフォまたは別の同期イベントを与える場合)、カーネルは他の優先度の高いタスクがそのキューで待機していたかどうかを確認します。 これらのすべてのケースでは、毎回チェックを実行し、最終的に割り込みをトリガする関数が呼び出されていますか? – Luca

+0

私はそれがかなり正しいと思います。呼び出された関数はスケジューラを起動し、スケジューラを起動します。外部割り込みはまた、別のタスクを準備させることができるOS呼び出しを行うことができます。 –

1

を求めていますか?あるいは、コンテキストスイッチがどのように実行されるかのメカニズムについて質問していますか?それは本当に明確ではありません。

あなたはどのように答えは何もありませんつのタスクブロックし、別のタスクに切り替えることを求めている場合は、それはRTOSがあなたのために何をするかの基礎です。例えばvTaskDelay()やブロック時間を指定してxQueueReceive()を呼び出すと、タスクはBlocked状態になります。タスクがブロックされている場合は実行できませんので、RTOSのスケジューリングアルゴリズムは実行する次のタスクを選択し、実行中のタスクを開始します。

+0

私は関係する力学を知りたい。それはどうやって起こるの? – Luca

+0

@ルーカ私が[私の答え](http://stackoverflow.com/questions/41898581/freertos)に提案しているので、[FreeRTOSの基礎](http://www.freertos.org/implementation/main.html)をお読みください。 -context-switching/41899897#41899897)。 – j123b567

関連する問題