目次
2.3. バイナリセマフォの使用プロセスと関連する API 関数
例証します:
内容について:
1) 以下の内容は主に概念的な理解とステップ分析です。
2) 個人的なサンプルコードはまだありませんので、FreeRTOS の公式サンプルコードを使用します。
3) テスト用コードを移植したい場合は、以下のコンテンツに個人的なテスト用サンプルコードはありませんので、他を探してください。
その他について:
1) オペレーティングシステム: win10
2) プラットフォーム: keil 5 mdk
3) 言語: C 言語
4) ボード:STM32シリーズをFreeRTOSに移植
1. セマフォ
1.1. セマフォの概要
1) セマフォは同期の問題を解決するメカニズムであり、共有リソースへの秩序あるアクセスを実現できます。
2) セマフォ リソースの数は共有リソースの数を表します (カウント値と呼ばれ、0 より大きいカウント値はセマフォ リソースがあることを示します)。
3) セマフォの解放は共有リソースを放棄することを意味し、カウント値は+1されます(共有リソースに空きが多すぎるため)。
4) セマフォの取得は共有リソースを占有していることを示し、カウント値は -1 になります(共有リソースの空きが少なくなったため)
5) セマフォの計算値を制限する: 最大値を制限する 最大値が 1 に制限されている場合 --> バイナリ セマフォ、最大値が 1 以外の場合 --> カウント セマフォです。
1.2. セマフォの特性
1) カウント値のみを格納し、他のデータは格納できません。セマフォを作成するには、セマフォ構造体を割り当てるだけで済みます。
2) セマフォ解放時はブロックできずカウント値が+1され、カウント値が最大値に達すると失敗を返します。
3) セマフォを取得します。カウント値は -1 です。リソースがない場合はブロックできます。
2. バイナリセマフォ
2.1. バイナリ セマフォの概要
1) バイナリ セマフォの本質はキュー長 1 のキューであるため、キューは空か満杯の 2 つの状況でのみ存在できます。これがバイナリ値の意味です。
2) バイナリ セマフォは通常、相互排他アクセスまたはタスクの同期に使用されます。相互排他セマフォに似ていますが、バイナリ セマフォは優先順位の反転の問題を引き起こす可能性があるため、バイナリ セマフォは主にタスクの同期に使用されます。
2.2. バイナリセマフォ関数の取得と解放
1) バイナリ セマフォ関数の解放: xSemaphoreGive (タスク内)、xSemaphoreGiveFromISR (割り込み内)
2) バイナリ セマフォ関数を取得します: xSemaphoreTake (タスク内)、xSemaphoreTakeFromISR (割り込み内)
3) Give はフラグを「full」に設定することと同等 --> 1 と同等、Take はフラグを「empty」に設定することと同等 --> 0 と同等
2.3. バイナリセマフォの使用プロセスと関連する API 関数
1) まずバイナリ セマフォを作成します --> バイナリ セマフォを解放 --> バイナリ信号を取得します
2) 関連する API 関数 (以下の図 1 を参照):
図1
2.4. 理解するためにバイナリ セマフォ関数を作成する
関数名:SemaphoreHandle_t xSemaphoreCreateBinary(void)
または、次の図 2 に示すように、キュー作成関数を使用して別のパラメーターを置き換えます。
図2
戻り値:
戻り値は NULL です。これは、作成に失敗したことを意味します。
戻り値は、その他の値として、バイナリ信号のハンドルが作成時に正常に返されたことを示します。
2.5. バイナリセマフォの解放について
関数名:BaseType_t xSemaphoreGive(xSemaphore)
パラメータ:
xSemaphore、意味: 取得するセマフォ ハンドル
2.6. バイナリセマフォを理解する
関数名:BaseType_t xSemaphoreTake(xSemaphore, xBlockTime)
パラメータ:
xSemaphore、意味: 取得するセマフォ ハンドル
xBlockTime、意味: ブロック時間
戻り値:
pdTRUE、意味: セマフォの取得に成功しました
pdFALSE、意味: タイムアウト、セマフォの取得失敗
3. カウンティングセマフォ
3.1. セマフォのカウントの概要
カウンティング セマフォは、キューの長さが 1 より大きいキューと同等であるため、カウンティング セマフォは複数のリソースに対応できます。これは、カウンティング セマフォの作成時に決定されます。
3.2. セマフォのカウントに適用される機会
1) イベントのカウント: 各イベントが発生すると、イベント処理関数はカウント セマフォを解放し (カウント値 + 1)、他のタスクはカウント セマフォを取得します (カウント値 - 1)。 0;
2) リソース管理: セマフォは有効なリソースの数を表します。タスクはリソース制御を取得する前に、まずセマフォ (セマフォ カウント値 - 1) を取得する必要があります。カウント値が 0 の場合は、使用可能なリソースが存在しないことを意味します。タスクがリソースを使い果たした場合 その後、セマフォを解放する必要があります(カウント値+1)。セマフォが作成されるとき、カウント値はリソースの最大数より大きくなければなりません。
3.3. カウンティングセマフォ関数の作成
関数名: xSemaphoreCreateCounting(uxMaxCount, uxlnitalCount)
3.4. セマフォの現在の数値サイズ関数を取得する
関数名:xSemaphoreGetCount(xSemaphore)
3.5. カウンティングセマフォの解放と取得
同じバイナリ セマフォですが、これ以上の説明はありません。
4. 優先順位の切り替え
4.1. 優先度切り替えとは何ですか?
優先度の高いタスクはゆっくりと実行され、優先度の低いタスクが最初に実行されます。優先順位の切り替えはプリエンプティブ カーネルでは非常に一般的ですが、リアルタイム オペレーティング システムでは優先順位の切り替えは許可されていません。優先順位の切り替えにより、予想されるタスクの許可順序が破壊され、未知の重大な結果につながる可能性があるためです。
4.2. 優先順位が反転する理由
1) タスク A、B、C の 3 つがあるとします。タスク A の優先度が最も高く(ABC のタスクの中で、以下同じ)、タスク B の優先度が中、タスク C の優先度が最も低く、タスク A とタスクの両方が優先されます。 C はバイナリ値です。セマフォが適用されます。タスク B は他の機能 (情報の印刷など) を実行します。
2) タスク C が最初に作成されるため、C が最初に実行されます (この時点ではタスク A が準備完了したばかりで、タスク B はまだ準備ができていません)。タスク A はバイナリ セマフォにも適用されますが、タスク C はこの時点ですでに占有されています。時間になり、タスク A はそれに適用できません。 はブロックして待つことしかできません。この時点では、タスク B の準備ができています。タスク B はバイナリ セマフォに適用されず、タスク C より優先度が高いため、タスク B はタスクをプリエンプトしますC; このとき、タスク A が優先されます。レベル > タスク B の優先順位ですが、タスク B が先に実行されます。
3) 優先度の高いタスクが優先度の低いタスクによってブロックされ、優先度の高いタスクのスケジューリングが遅れます。ただし、他の中優先度のタスクが CPU リソースを占有する可能性があります。現象からすると、高優先度のタスクよりも中優先度のタスクの方が優先度が高いように見えます。
4.3. 優先度反転の解決
1) 優先度の継承(相互排他セマフォ)
2) 優先上限
5. 相互に排他的なセマフォ
5.1. 相互排他的セマフォとは何ですか?
相互排他的なセマフォは、実際には優先順位の継承を備えたバイナリ セマフォであり、同期アプリケーションに最適です。相互排他的セマフォは、相互排他的アクセスを必要とするアプリケーションに適しています。
5.2. 優先順位の継承とは何ですか?
低優先度タスクがミューテックス セマフォを保持している場合、高優先度タスクもミューテックス セマフォを取得しようとすると、高優先度タスクはブロックされます。ただし、この優先度の高いタスクの優先度は、それ自体と同じ優先度に引き上げられます。
注意点:
1) ミューテックス セマフォは割り込みサービス関数では使用できません 理由: 1. ミューテックス セマフォにはタスク優先度継承機構がありますが、割り込みはタスクではなくタスク優先度がないため、ミューテックス セマフォはタスクにのみ使用できます。割り込みサービス関数内; 2. 割り込みサービス関数は、相互に排他的なセマフォを待機する必要があるため、ブロッキング状態に入るまでのブロッキング時間を設定できません。
2) 相互に排他的なセマフォを作成する場合、セマフォは一度アクティブに解放されます。