前回は3つのスレッドでバイナリセマフォを使った挙動を確認しました。
今回はバイナリセマフォをミューテックスに置き換えてみます。
置き換えるだけなので新たにプロジェクトをつくるのも手間を省き、前回つくったものに追加、変更を加えてみることにしました。
ミューテックスを追加する
IDEを起動し Project Explorer の F401RtosV2ThreeThreadSemaphore.ioc ファイルをダブルクリックします。
FREERTOS Mode and Configuration – Configuration の Mutexesタブをクリックします。
上の Mutexes の Addボタンを押し New Mutexウィンドウが出るので OKボタンを押します。
一度ビルドしておきます。
属性にオプションを追加する
main.c の以下の構造体に追加します。
/* Definitions for myMutex01 */
osMutexId_t myMutex01Handle;
const osMutexAttr_t myMutex01_attributes = {
.name = "myMutex01",
};
以下の1行を追加します。
/* Definitions for myMutex01 */
osMutexId_t myMutex01Handle;
const osMutexAttr_t myMutex01_attributes = {
.name = "myMutex01",
.attr_bits = osMutexPrioInherit, // ここを追加しておく
};
これは優先度継承プロトコルを追加するものです。
セマフォでは獲得と開放という表現を使いましたが、ミューテックスではロック、アンロックという表現を使っています。
優先度継承プロトコルは、ミューテックスをロックしているタスクの優先度を、ロックを待っているタスクの優先度の中で一番高い優先度に一時的に変更することで優先度逆転を防ぎます。
セマフォをミューテックスに置き換える
osSemaphoreAcquire()をコメントにして代わりに osMutexAcquire() を実装します。
osSemaphoreRelease()をコメントにして代わりに osMutexRelease() を実装します。
void StartTaskHigh(void *argument)
{
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)
{
HAL_UART_Transmit(&huart2, "H enters critical section.\r", 27, 10);
// osSemaphoreAcquire(myBinarySem01Handle, osWaitForever);
osMutexAcquire(myMutex01Handle, osWaitForever);
doWorkH();
HAL_UART_Transmit(&huart2, "H leaves critical section.\r", 27, 10);
// osSemaphoreRelease(myBinarySem01Handle);
osMutexRelease(myMutex01Handle);
HAL_UART_Transmit(&huart2, "H delay 1000ms.\r", 16, 10);
osDelay(1000);
}
/* USER CODE END 5 */
}
void StartTaskLow(void *argument)
{
/* USER CODE BEGIN StartTaskLow */
/* Infinite loop */
for(;;)
{
HAL_UART_Transmit(&huart2, "L enters critical section.\r", 27, 10);
// osSemaphoreAcquire(myBinarySem01Handle, osWaitForever);
osMutexAcquire(myMutex01Handle, osWaitForever);
doWorkL();
HAL_UART_Transmit(&huart2, "L leaves critical section.\r", 27, 10);
// osSemaphoreRelease(myBinarySem01Handle);
osMutexRelease(myMutex01Handle);
}
/* USER CODE END StartTaskLow */
}
ビルドして動かしてみる
ビルドして挙動を確認してみます。
以下は Tera Term の通信ログです。
(1)か(3)のパターンしかなく、(2)の優先度逆転がなくなりました。
セマフォによる優先度逆転が起こる可能性があるシステムでは、ミューテックスが有効であることがわかりました。
ミューテックスはいかがでしたか?
お疲れさまでした。