Previous: 7.2. ミューテックスの作成 |
Up: 7. ミューテックス |
Next: 8. メモリ管理 |
バイナリセマフォの場合は、バイナリセマフォを作成した直後は、セマフォがまだ与えられていない状態です。一方ミューテックスの場合は、ミューテックスを作成した直後の状態ですでに、ミューテックスが与えられている状態です。USARTについて考えてみると、USARTは初期状態では誰も使用していないので、どのタスクでもミューテックスを取って、USARTを使用することができるということになります。
ミューテックスを取るためにはxSemaphoreTake関数を使用し、ミューテックスを戻すためにはxSemaphoreGive関数を使用します。
サンプルプログラムの割込み処理用タスクのための関数であるvHandlerTask関数では、以下のように、メッセージの表示の前後をxSemaphoreTake関数とxSemaphoreGive関数で挟み込んでいます。これによりミューテックスをとれるときにはすぐにメッセージを表示するが、とれないときはとれるまで待つことになります。メッセージの表示後はxSemaphoreGive関数でミューテックスを必ず戻しておきます。
void vHandlerTask(void *pvParameters) { ~~~~~~~~~~~~ ? while(1) ??? { ~~~~~~~~~~~~ ????? //Take mutex ????? xSemaphoreTake(xMutex, portMAX_DELAY); ????? //Print message through COM ????? print("Handler task called.\r\n"); ????? //Give mutex back ????? xSemaphoreGive(xMutex); ??? } } |
サンプルプログラムの割り込まれるタスク側の関数であるvLowPriorityTask関数も、同様のメッセージの表示の前後をxSemaphoreTake関数とxSemaphoreGive関数で挟み込んでいます。これによりvHandlerTask関数と同様に、ミューテックスをとれるときだけメッセージを表示するという処理ができることになります。
void vLowPriorityTask(void *pvParameters) { ? int8_t *pcTaskNumber; ? pcTaskNumber = (int8_t *)pvParameters; ? while(1) ??? { ????? //Take mutex ????? xSemaphoreTake(xMutex, portMAX_DELAY); ????? //Print message through COM ????? cprintf("**Low Priority Task**\r\n"); ????? //Give mutex back ????? xSemaphoreGive(xMutex); ??? } } |
サンプルプログラムの実行結果は以下の通りです。
ミューテックスを使用した場合、割込みを停止するわけではありませんから重要な割込みを阻害することはありませんし、スケジューラも動作していますので、より優先させるべきタスクがある場合には優先して実行させることができます。
Handler task called. **Low Priority Task** Handler task called. **Low Priority Task** **Low Priority Task** **Low Priority Task** **Low Priority Task** Handler task called. **Low Priority Task** |
Previous: 7.2. ミューテックスの作成 |
Up: 7. ミューテックス |
Next: 8. メモリ管理 |