Top -> FreeRtos -> inter-task.html
タスク間通信
[Getting Started]
* Queues
* Binary Semaphores
* Counting Semaphores
* Mutexes, and
* Recursive Mutexes/l>
FreeRTOS eBook は待ち行列、2進セマフォ、 mutexes と計数セマフォについての追加の
インフォメーションを単純な事例とともに例題プロジェクトも提供する。
待ち行列
待ち行列はタスク間通信の主要な形式です。 これらはタスクとタスクの間で、また割り込みとタスクの間でメッセージを送るために使われる。 ほとんどの場合これらはスレッドセーフなFIFO(先入れ先出し)バッファとして使用されます。
待ち行列は固定長の「アイテム」を含むことができます − 各アイテム長と待ち行列のアイテムの最大値は待ち行列の作成時に定義する。
アイテムは参照によってではなく、実体のコピーによって待ち行列の中に置かれます。 そのため待ち行列の中に置かれる各アイテムサイズは最小限であることが望ましい。 コピーによって待ち行列の中にアイテムを置くことは、2つのタスクが同時にデータにアクセスすることができないようにアプリケーションデザインを単純化します。 待ち行列はすべての排他制御に注意を要します。
もし大きいアイテムを待ち行列に入れることを望むなら、代わりにそれぞれの項目へのポインタを待ち行列に入れたいと思うかもりれません− しかしアプリケーションがそのデータの所有者がどのタスクあるいは割り込みであるかを明白に知っていなければなりません。
待ち行列 API 関数はブロックタイム指定が可能です。 ブロックタイムはタスクがブロック状態でデータが待ち行列の上に利用可能になるのを待つ「チック値」を指します。(待ち行列が空の場合でタスクが待ち行列から読み込もうとしている)、あるいは(タスクが待ち行列に書き込もうとしている)しかし待ち行列がすでにいっぱいのケース。
同じ待ち行列上に複数のタスクがブロック状態にあるとき、その中の最高優先順位を持っているタスクが最初にブロックを解除される。
待ち行列関連の API 関数のリストはユーザドキュメントの待ち行列管理のセクションを参照してください。 FreeRTOS / デモ / コモン / Minimal ディレクトリでファイルを検索するとこれらの使用法の多数の例を見ることができる。
割り込みは「FromISR」で終わらない API 関数を使ってはならないことに注意を払ってください。
待ち行列に書いて読み込みます。 この例で待ち行列は5つの項目を持つために作成されました、そして待ち行列は決していっぱいになりません。

バイナリ セマフォ
バイナリのセマフォが排他制御と同期の両目的のために使用される。
バイナリのセマフォと mutexes は非常に似ていますが、微妙な差を持っています:
Mutexes は優先度継承メカニズムを含みますがバイナリセマフォは持ちません。 同期(タスクの間にあるいはタスクと割り込みの間に)を実行するにはバイナリセマフォが最良の選択ですが、単純な相互排除を実行するにはmutexes がもっと良い選択です。
mutex の排他処理メカニズムとしての方法はバイナリセマフォのためのそれと同様です。
このサブセクションは同期のためにバイナリセマフォを使うことを説明するだけです。
セマフォ API 機能はブロックタイムが指定されるのを妨げません。 もしセマフォがすぐに利用可能で無いなら、タスクはセマフォを「take」しようと試みてブロック状態に入る、ブロックタイムは「チック」での最大値を指定します。 1つ以上のタスクが同じセマフォでブロックするなら、セマフォが利用可能になる次のとき、最高優先順位を持っているタスクからブロック解除される。
バイナリセマフォはただ1つのアイテム項目を持つ待ち行列であると考えてください。 従って待ち行列はただ空であるか、あるいはフルであることが表現できるだけです(それ故バイナリ)。 タスクと割り込みは待ち行列が何を保持しているかを気にしません − ただ待ち行列が空であるか、あるいはフルであるかどうか知りたいだけです。 このメカニズムは(例えば)タスクを割り込みに同期させるために利用することができます。
タスクが周辺機器にサービスをするために使われるケースを考えてください。 周辺機器をポーリングすることはCPUリソースを無駄にして他のタスクが実行するのを邪魔するでしょう。 従って、タスクが大部分の時間をブロック状態にあることは望ましい。(他のタスクの実行を可能にします)
そして、何かすべき事があるときだけ自身を実行する。 これは、バイナリセマフォを使用して、'take'セマフォをしようとしたとき、タスクブロックすることによって実現されます。 割り込みルーチンが周辺機器のためにそのように書かれます。
周辺機器がサービスを提供するとき、それはただセマフォを「give」。 タスクは常にセマフォ(待ち行列を空にする方向で待ち行列からの読み取る)を「take」するが、決してそれを「give」しない。 割り込みは常にセマフォ(フルにする方向で待ち行列に書き込みます)を「give」しますが、決してそれを「take」しません。 xSemaphoreGiveFromISR () ドキュメンテーションページに提供されたソースコードはこれをいっそう明確してあります。
タスク優先順位付けがタイムリーな方法で周辺機器がサービスを得ることを保証する
代わりのアプローチはセマフォの代わりに待ち行列を使うことです。 割り込みルーチンは周辺機器のイベントと結び付いたデータを取り込んで、それを待ち行列の上のタスクに送ることができます。 タスクはデータが待ち行列上に利用可能になるとブロック解除され、待ち行列からデータを取り出して、必要とされるデータ処理を行ないます。 この2番目のスキームは、可能な限り短く割り込みを許します-タスク内での代わりに処理をポストする。
セマフォ関連の API 機能のリストはユーザドキュメントの Semaphores / Mutexes のセクションを見てください。 FreeRTOS / デモ / コモン / Minimal ディレクトリでファイルを検索することは、それらの使用法の多くの例を見つけることができるでしょう。 割り込みが「FromISR」で終わらない API 機能を使ってはならないことに注意を払ってください。
セマフォをタスクを割り込みに同期させるために使います。 割り込みはセマフォを「give」するだけです、一方タスクはセマフォを「take」するだけです。

カウンティングセマフォ
バイナリセマフォが長さ1の待ち行列とみなされることができるのとちょうど同じように、計数セマフォが1より大きい長さの待ち行列とみなすことができます。 同じように、セマフォのユーザは待ち行列にストアされるデータに興味を持っていません − ただ待ち行列が空であるか否かだけです。
カウンティングセマフォの典型的な2つ用途:
  1. カウンティング・イベント。
    このシナリオで、イベントが起こるとイベントハンドらーがセマフォを「give」します(セマフォカウント値を増加させること)、
    そしてイベントを処理するたびに、ハンドラータスクがセマフォを「take」する(セマフォカウント値を減少させます)。
    カウント値は起こったイベントの数と処理された数の差違です
    この場合、セマフォが作られるときカウント値はゼロであることが前提です。
  2. 資源管理。
    このシナリオではカウント値は利用可能なリソースの数を表します。 リソースのコントロールを得るためにタスクは最初にセマフォを得なくてはなりません − セマフォカウント値を減少させる。 カウント値がゼロに達するとフリーなリソースが残っていない事を示す。 タスクがリソース使用を終了したらセマフォを「gives」する − セマフォカウント値を増加させる。 この場合、セマフォが作られるとき、リソース数とカウント値が等しいように設定する。
セマフォ関連の API 機能のリストはユーザドキュメントの Semaphores / Mutexes のセクションを見てください。 FreeRTOS / デモ / コモン / Minimal ディレクトリでファイルを検索することはこれらの使用法の多くの例を見つけることができるでしょう。 割り込みが「FromISR」で終わらない API 機能を使ってはならないことに注意を払ってください。

ミューテックス
ミューテックス は優先度継承メカニズムを含むバイナリセマフォです。 同期を実行するためには、バイナリセマフォがもっと良い選択であるのに対して(タスク間にあるいはタスクと割り込みの間)、
単純な排他処理を実行するためにはmutexes はもっと良い選択です (それ故「MUT 'ual」 EX 'clusionです)。
排他処理に使われるときmutex はリソースをガードするためのトークンのように振る舞います。 タスクがリソースにアクセスしようとした時、最初に(「take」)トークンを得なくてはならない. またリソースを使い終わったとき、それは、トークン「give」を返さなくてはなりません。
他のタスクに同じリソースにアクセスする機会を許すために。
Mutexesはセマフォアクセス API 関数と同じものを使います、同じくブロックタイムの指定が許されます。 ブロックタイムはタスクがブロック状態を入っている最大「チック」数を示します。
もし mutex がすぐに利用可能ではないなら、 mutex を「take」しようと試みるときブロック状態に入ります。 バイナリセマフォと異なりmutexes は優先権継承します。 もし高優先順位タスクが、より低い優先権タスクによって保持される mutex の(トークン)を得ようと試みてブロックする。
それでトークンを持っているタスクの優先権はブロックしているタスクのそれに一時的に引き上げられます。 このメカニズムはより高い優先権タスクはブロック状態が可能な最も短い時間で終わることを保証して、すでに起こった「優先権反転」を最小にするよう設計されます。
優先度継承は優先度反転を治しません! それはただ若干のシチュエーションでその効果を最小にします。 ハードリアルタイムアプリケーションは第一に優先権反転が起きないように設計されるべきです。
mutex は共用資源へのアクセスをガードするために使います。

回帰的な Mutexes
recursively に使われた mutex が繰り返して所有者によって「taken」されることができます。 所有者がそれぞれの成功した xSemaphoreTakeRecursive
() のリクエストのために xSemaphoreGiveRecursive () に呼び出すまで、 mutex は再び利用可能になりません。
例えば、もしタスクが成功裏に同じ mutex 5回を 'takes'するなら、それが同じく正確に5回 mutex を「given」するまで、
mutex は他のいかなるタスクにも利用可能にはならないでしょう。
このタイプのセマフォは優先権継承機構を使います。
それでセマフォを「take」しているタスクが常にセマフォを「give」しなくてはなりません。
Mutex タイプセマフォが割り込みサービスルーチンの中から使えません。

TOPページ