STM32のFreeRTOSでミューテックスの使い方を、サンプルコードと合わせてわかりやすく解説します。
STM32のFreeRTOSのミューテックス
使い方の前に、STM32のFreeRTOSのミューテックスの仕様について説明しておきます。イメージとしてはCMSIS RTOS v1とv2の間を取ったような仕様となっていて、ポイントは2つあります。
1つ目は取り扱えるミューテックスの種類です。v1におけるミューテックスは再帰的なミューテックスのみであるのに対し、v2では通常のミューテックスと再帰的なミューテックスの両方がありますが、STM32ではv2の仕様を踏襲しています。
2つ目は関数名ですが、これはv1を踏襲した名称になっています。v1の関数名を使うと通常のミューテックスが生成されるので混乱しないように注意しましょう。再帰的なミューテックスを使う場合は、独自の関数があるのでそちらを利用します。
本記事では、この動作を前提に通常のミューテックスを取り扱います。
作成するプログラム
それでは今回のゴールを確認しておきましょう。今回はミューテックスを使って、LEDが点滅するプログラムを作ります。LEDを点灯するスレッドと、LEDを消灯するスレッドを用意し、ミューテックスを使うことで、スレッドが1つずつ実行されることで、LEDの点滅を実現します。
前提条件
前提条件は目次の記事を参照してください。
プログラムの作成
スレッドの作成
まずはスレッドを作っていきましょう。
- Pinout & Configurationsタブ→Middleware→FREERTOS→Configurationタブ→Tasks and Queues
- 下記の設定を参考にスレッドを3つ作成してください
プライオリティが同じでないと動かないのでよく確認してください
ミューテックスの作成
次はミューテックを作ります。
- Pinout & Configurationsタブ→Middleware→FREERTOS→Configurationタブ→Mutexes
- 下記の図を参考にミューテックスを作成してください
設定項目はバイナリセマフォと一緒です。
設定が終わったらコードを自動生成してください。
スレッドの実装
コードを自動生成できたらスレッドを実装していきます。各スレッドはミューテックスを取得し、取得できたらLEDを点灯(消灯)し、ミューテックスをリリースする、を繰り返します。
main.c:SetLEDThread
void SetLEDThreadFunc(void const * argument) { /* USER CODE BEGIN 5 */ /* Infinite loop */ for(;;) { if (osMutexWait(LEDMutexHandle, osWaitForever) == osOK) { HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET); osDelay(1000); osMutexRelease(LEDMutexHandle); osThreadYield(); } } /* USER CODE END 5 */ }
main.c:ResetLEDThread
void ResetLEDThreadFunc(void const * argument) { /* USER CODE BEGIN ResetLEDThreadFunc */ /* Infinite loop */ for(;;) { if (osMutexWait(LEDMutexHandle, osWaitForever) == osOK) { HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); osDelay(1000); osMutexRelease(LEDMutexHandle); osThreadYield(); } } /* USER CODE END ResetLEDThreadFunc */ }
osMutexWait()でミューテックスの取得をします。第1引数がミューテックスのIDです。第2引数で取得待ち時間を指定し、osWaitForeverとすることで、取得できるまでずっと待ちます。
osMutexRelease()でミューテックスのリリースをします。引数でミューテックスのIDを指定します。
プログラムの作成は以上です。実際に動かしてLEDが点滅することを確認してみてください。
まとめ
はじめに、STM32のFreeRTOSはCMSIS RTOSの仕様と異なることを説明しました。CMSIS RTOS v1の仕様では再帰的なミューテックスが作られますが、STM32では通常のミューテックスが作られます。
ここではこの動作を前提に、ミューテックスの使い方をサンプルコードを使って説明しました。使い方自体はCMSIS RTOS v1と同じなので、再帰的でないことに注意すれば、使い勝手は悪くないものと思います。
再帰的なミューテックスについては別のAPIを使う必要があります。それについては別記事を用意してありますので、そちらをご参照ください。
関連:STM32のFreeRTOSの再帰的なミューテックスの使い方