FreeRTOS ソフトウェア タイマー


1. ソフトウェアタイマーの紹介

1. ソフトウェアタイマの概要
ソフトウェアタイマは時間を設定し、設定した時間になると指定された関数を実行するもので、タイマから呼び出される関数をタイマのコールバック関数と呼びます。コールバック関数の 2 つの実行間の間隔は、タイマーのタイミング期間と呼ばれます. つまり、タイマーのタイミング期間が経過したときにコールバック関数が実行されます。

2. コールバック関数記述時の注意事項
ソフトウェアタイマのコールバック関数はタイマサービスタスク内で実行されるため、タスクをブロックする API 関数をコールバック関数内で呼び出してはいけません! たとえば、タイマー コールバック関数は vTaskDelay()、vTaskDelayUnti() を呼び出してはならず、ゼロ以外のブロッキング時間でキューまたはセマフォにアクセスする一部の API 関数も呼び出すことができません。

2. タイマーサービス/デーモンタスク

1. タイマーサービスタスクとキュー
タイマーは、FreeRTOS カーネルに属さないオプション機能で、タイマーサービス (ま​​たはデーモン) タスクによって提供されます。FreeRTOS は多くのタイマー関連の API 関数を提供します。そのほとんどは FreeRTOS キューを使用してコマンドをタイマー サービス タスクに送信します。このキューは、タイマー コマンド キューと呼ばれます。タイマー コマンド キューは、FreeRTOS のソフトウェア タイマーに提供されており、ユーザーが直接アクセスすることはできません。次の図は、このプロセスを示しています。

ここに画像の説明を挿入

上の図の左側の部分はユーザー アプリケーションの一部であり、ユーザーが作成したユーザー タスクで呼び出されます。図の右側はタイマー サービス タスクのタスク関数で、タイマー コマンド キューはユーザー アプリケーション タスクとタイマー サービス タスクを接続します。この例では、アプリケーション プログラムが関数 xTimerReset() を呼び出し、その結果、リセット コマンドがタイマー コマンド キューに送信され、タイマー サービス タスクがこのコマンドを処理します。アプリケーションは、xQueueSend() のようなキュー操作関数を直接呼び出す代わりに、関数 xTimerReset() を介して間接的にタイマー コマンド キューにリセット コマンドを送信します。

2. タイマー関連の設定
以上から、ソフトウェアタイマーにはタイマーサービスタスクとタイマーコマンドキューがあることがわかります.この2つを設定する必要があります.設定方法は先ほど説明したFreeRTOSCofig.hと同じです.関連する構成 FreeRTOSConfig.h ファイルにも配置されており、関連する構成は次のとおりです。

(1) configUSE_TIMERS
ソフトウェア タイマーを使用する場合、マクロ configUSE_TIMERS を 1 に設定する必要があります。1 に設定すると、FreeRTOS スケジューラーの起動時にタイマー サービス タスクが自動的に作成されます。

(2) configTIMER_TASK_PRIORITY は
、ソフトウェア タイマー サービス タスクのタスク優先度を設定します。これは 0 ~ (configMAX_PRIORITIES-1) です。優先順位は、実際のアプリケーション要件に従って設定する必要があります。タイマー サービス タスクの優先度が高く設定されている場合、
タイマー コマンド キュー内のコマンドとタイマー コールバック関数は時間内に処理されます。

(3) configTIMER_QUEUE_LENGTH
タイマーコマンドキューのキュー長を設定するマクロです。

(4) configTIMER_TASK_STACK_DEPTH
このマクロは、タイマー サービス タスクのタスク スタック サイズを設定するために使用されます。単位はバイトではなくワードです。、STM32 の場合、1 ワードは 4 バイトです。タイマーのコールバック関数はタイマーサービスタスクで実行されるため、タイマーのコールバック関数に合わせてタスクスタックのサイズを設定する必要があります。

3. ワンショットタイマーと定期タイマー

ソフトウェアタイマには、ワンショットタイマと周期タイマの2種類があり、ワンショットタイマの場合、タイマコールバック関数はタイミング1sなど1回実行され、タイミングタイムアップでコールバック関数が実行されます。一度、タイマーは実行を停止します。ワンショット タイマーの場合、手動で再起動できます (対応する API 関数を呼び出すだけです) が、ワンショット タイマーは自動的に再起動できません。逆に、定期タイマーは一度起動すると、コールバック関数の実行後に自動的に再起動するため、定期的にコールバック関数が実行されます。次の図は、ワンショット タイマーと周期的タイマーの違いを示しています。
ここに画像の説明を挿入
図の Timer1 は、タイマー周期が 100 のワンショット タイマーであり、Timer2 は、タイマー周期が 200 の周期的タイマーです。

4. ソフトウェアタイマーをリセットする

タイマーの実行中にソフトウェア タイマーをリセットする必要がある場合があります. ソフトウェア タイマーをリセットすると、タイミング サイクルが到着した時点が再計算されます. この新しい時点は、タイマーがリセットされた時点を基準として計算されます.ソフトウェアタイマーが最初に開始される時点。次の図は、このプロセスを示しています. Timer1 は、タイミング周期が 5 秒のワンショット タイマーです:
ここに画像の説明を挿入
上の図では、タイマーのリセット プロセスを示しています. これは、キーを押して LCD バックライトをオンにする例です.ウェイクアップ キーが押されたとき、アプリケーション プログラムが LCD バックライトをオンにすると、LCD バックライトがオンのときに、ウェイクアップ ボタンが 5 秒以内に再度押されない場合、自動的にオフになると想定しています。5 秒以内にウェイクアップ ボタンを押すと、押した瞬間からさらに 5 秒間 LCD バックライトが点灯します。

FreeRTOS は、次の表に示すように、ソフトウェア タイマーをリセットする 2 つの API 関数を提供します。
ここに画像の説明を挿入

1. 関数 xTimerReset()

ソフトウェア タイマーをリセットします。この機能はタスクでのみ使用でき、割り込みサービス機能では使用できません。この関数はマクロであり、実際に実行されるのは xTimerGenericCommand() 関数です。関数のプロトタイプは次のとおりです。

BaseType_t xTimerReset( TimerHandle_t xTimer, 
						TickType_t xTicksToWait )

パラメータ:
xTimer:リセットするソフトウェア タイマーへのハンドル。
xTicksToWait:ブロッキング時間を設定します. 関数 xTimerReset () を呼び出してソフトウェア タイマーを開始することは、実際には tmrCOMMAND_RESET コマンドをタイマー コマンド キューに送信することです. メッセージをキューに送信しているため、入力するためのブロッキング時間を設定する必要があります。待ち行列。

戻り値:
pdPASS:ソフトウェア タイマーが正常にリセットされました。これは、コマンドが正常に送信されたことを意味します。
pdFAIL:ソフトウェアタイマーリセット失敗、コマンド送信失敗。

2. 関数 xTimerResetFromISR()

この関数は xTimerReset() の割り込みバージョンであり、この関数は割り込みサービス関数で使用されます! この関数はマクロであり、実際に実行されるのは xTimerGenericCommand() 関数です。関数のプロトタイプは次のとおりです。

BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
							   BaseType_t * pxHigherPriorityTaskWoken );

パラメータ:
xTimer:リセットするソフトウェア タイマーへのハンドル。
pxHigherPriorityTaskWoken:この関数を終了した後にタスクを切り替えるかどうかを覚えておいてください。この変数の値関数は自動的に設定されます。ユーザーが設定する必要はありません。ユーザーはこの値を保存するための変数を提供するだけで済みます。この値が pdTRUE の場合、割り込みサービス関数を終了する前にタスク切り替えを実行する必要があります。

戻り値:
pdPASS:ソフトウェア タイマーが正常にリセットされました。これは、コマンドが正常に送信されたことを意味します。
pdFAIL:ソフトウェアタイマーリセット失敗、コマンド送信失敗。

5. ソフトウェア タイマーを作成する

ソフトウェア・タイマを使用する前に、ソフトウェア・タイマを作成してください ソフトウェア・タイマ作成関数を次の表に示します。
ここに画像の説明を挿入

1. 関数 xTiemrCreate()

この関数は、ソフトウェア タイマーを作成するために使用され、必要なメモリは動的メモリ管理方法によって割り当てられます。新しく作成されたソフトウェア タイマーは休止中、つまり実行されていません。関数 xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() および xTimerChangePeriod() は、新しく作成されたタイマーをアクティブにすることができます. この関数のプロトタイプは次のとおりです:

TimerHandle_t xTimerCreate( const char * const pcTimerName,
						    TickType_t xTimerPeriodInTicks,
						    UBaseType_t uxAutoReload,
						    void * pvTimerID,
						    TimerCallbackFunction_t pxCallbackFunction )

パラメータ:
pcTimerName:ソフトウェア タイマー名。名前は文字列の文字列で、デバッグに使用されます。
xTimerPeriodInTicks:ソフトウェア タイマーのタイマー周期。単位はクロック ティック数です。ms の単位は、portTICK_PERIOD_MS を使用してティックに変換できます。たとえば、タイマー期間が 100 クロック ティックの場合、xTimerPeriodInTicks は 100 です。タイマー期間が 500 ミリ秒の場合、xTimerPeriodInTicks は (500/portTICK_PERIOD_MS) に設定できます。
uxAutoReload:タイマー モード、ワンショット タイマーまたは定期タイマーを設定しますか? このパラメータが pdTRUE の場合、定期的なタイマーが作成されることを意味します。pdFALSE の場合は、ワンショット タイマーを作成することを意味します。
pvTimerID:タイマー ID 番号 一般に、各タイマーにはコールバック関数があり、タイマーのタイミング期間が終了すると実行されます。ただし、FreeRTOS は同じコールバック関数を共有する複数のタイマーもサポートしており、コールバック関数内のタイマーの ID 番号に従って異なるタイマーが処理されます。
pxCallbackFunction:タイマー コールバック関数。この関数は、タイマーのタイミング期間が終了したときに呼び出されます。

戻り値:
NULL:ソフトウェア タイマーの作成に失敗しました。
その他の値:正常なソフトウェア タイマー ハンドルを作成します。

2. 関数 xTimerCreateStatic()

この関数はソフトウェア タイマーを作成するために使用され、必要なメモリはユーザーが割り当てる必要があります。新しく作成されたソフトウェア タイマーは休止中、つまり実行されていません。関数 xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() および xTimerChangePeriodFromISR() は、新しく作成されたタイマーをアクティブにすることができます. この関数のプロトタイプは次のとおりです:

TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
								 TickType_t xTimerPeriodInTicks,
								 UBaseType_t uxAutoReload,
								 void * pvTimerID,
								 TimerCallbackFunction_t pxCallbackFunction,
								 StaticTimer_t * pxTimerBuffer )

パラメータ:
pcTimerName:ソフトウェア タイマー名。名前は文字列の文字列で、デバッグに使用されます。
xTimerPeriodInTicks:ソフトウェア タイマーのタイマー周期。単位はクロック ティック数です。ms の単位は、portTICK_PERIOD_MS を使用してティックに変換できます。たとえば、タイマー期間が 100 クロック ティックの場合、xTimerPeriodInTicks は 100 です。タイマー期間が 500 ミリ秒の場合、xTimerPeriodInTicks は (500/portTICK_PERIOD_MS) に設定できます。
uxAutoReload:タイマー モード、ワンショット タイマーまたは定期タイマーを設定しますか? このパラメータが pdTRUE の場合、定期的なタイマーが作成されることを意味します。pdFALSE の場合は、ワンショット タイマーを作成することを意味します。
pvTimerID:タイマー ID 番号 一般に、各タイマーにはコールバック関数があり、タイマーのタイミング期間が終了すると実行されます。当時の FreeRTOS は、同じコールバック関数を共有する複数のタイマーもサポートしており、コールバック関数では、タイマーの ID 番号に応じて異なるタイマーが処理されていました。
pxCallbackFunction:タイマー コールバック関数。この関数は、タイマーのタイミング期間が終了したときに呼び出されます。
pxTimerBuffer:このパラメーターは、タイマー構造を保存するために使用されるタイプ StaticTimer_t の変数を指します。

戻り値:
NULL:ソフトウェア タイマーの作成に失敗しました。
その他の値:正常なソフトウェア タイマー ハンドルを作成します。

6. ソフトウェアタイマーをオンにする

ソフトウェア タイマーが実行を停止した場合、FreeRTOS によって提供される 2 つの開始関数を使用して、ソフトウェア タイマーを再起動できます. これら 2 つの関数を次の表に示します。
ここに画像の説明を挿入

1. 関数 xTimerStart()

ソフトウェア タイマーを開始します。関数 xTimerStartFromISR() は、この関数の割り込みバージョンであり、割り込みサービス関数で使用できます。ソフトウェア タイマーが実行されていない場合、関数 xTimerStart() を呼び出すと、タイマーの有効期限が計算されます。ソフトウェア タイマーが実行されている場合、関数 xTimerStart() を呼び出した結果は、xTimerReset() と同じです。この関数はマクロであり、実際に実行されるのは xTimerGenericCommand 関数です。関数のプロトタイプは次のとおりです。

BaseType_t xTimerStart( TimerHandle_t xTimer, 
						TickType_t xTicksToWait )

パラメータ:
xTimer:開始するソフトウェア タイマーのハンドル。
xTicksToWait:ブロッキング時間を設定します. 関数 xTimerStart() を呼び出してソフトウェア タイマーを開始することは、実際には tmrCOMMAND_START コマンドをタイマー コマンド キューに送信することです. メッセージをキューに送信しているため、入力するためのブロッキング時間を設定する必要があります.待ち行列。

戻り値:
pdPASS:ソフトウェア タイマーが正常に有効になりました。これは、コマンドが正常に送信されたことを意味します。
pdFAIL:ソフトウェアタイマーの起動に失敗し、コマンドの送信に失敗しました。

2. 関数 xTimerStartFromISR()

この関数は、割り込みサービス関数で使用される関数 xTimerStart() の割り込みバージョンです. この関数はマクロであり、実際に実行されるのは関数 xTimerGenericCommand() です. この関数のプロトタイプは次のとおりです.

BaseType_t xTimerStartFromISR(  TimerHandle_t xTimer,
								BaseType_t * pxHigherPriorityTaskWoken );

パラメータ:
xTimer:開始するソフトウェア タイマーのハンドル。
pxHigherPriorityTaskWoken:この関数を終了した後にタスクを切り替えるかどうかをマークします. この変数の値関数は自動的に設定されます. ユーザーはそれを設定する必要はありません. ユーザーはこの値を保存するための変数を提供するだけで済みます. この値が pdTRUE の場合、割り込みサービス関数を終了する前にタスク切り替えを実行する必要があります。

戻り値:
pdPASS:ソフトウェア タイマーが正常に有効になりました。これは、コマンドが正常に送信されたことを意味します。
pdFAIL:ソフトウェアタイマーの起動に失敗し、コマンドの送信に失敗しました。

7. ソフトウェア タイマーを停止する

ソフトウェア タイマーを開始する API 関数があるため、ソフトウェア タイマーを停止する関数も存在する必要があります. FreeRTOS は、次の表に示すように、ソフトウェア タイマーを停止するための 2 つの API 関数も提供します。
ここに画像の説明を挿入

1. 関数 xTimerStop()

この関数はソフトウェア タイマーを停止するために使用されます。この関数はタスクで使用されます。割り込みサービス関数では使用できません。この関数は、関数 xTimerGenericCommand() を実際に呼び出すマクロです。関数のプロトタイプは次のとおりです。

BaseType_t xTimerStop ( TimerHandle_t xTimer, 
						TickType_t xTicksToWait )

パラメータ:
xTimer:停止するソフトウェア タイマーのハンドル。
xTicksToWait:ブロッキング時間の設定. 関数 xTimerStop() を呼び出してソフトウェア タイマーを停止することは、実際には tmrCOMMAND_STOP コマンドをタイマー コマンド キューに送信することです. メッセージをキューに送信しているため、入力するためのブロッキング時間を設定する必要があります。待ち行列。

戻り値:
pdPASS:ソフトウェア タイマーが正常に停止しました。これは、コマンドが正常に送信されたことを意味します。
pdFAIL:ソフトウェアタイマー停止失敗、コマンド送信失敗。

2. 関数 xTimerStopFromISR()

この関数は xTimerStop() の割り込みバージョンであり、この関数は割り込みサービス関数で使用されます! この関数はマクロであり、実際に実行されるのは xTimerGenericCommand() 関数です。関数のプロトタイプは次のとおりです。

BaseType_t xTimerStopFromISR(   TimerHandle_t xTimer,
								BaseType_t * pxHigherPriorityTaskWoken );

パラメータ:
xTimer:停止するソフトウェア タイマーのハンドル。
pxHigherPriorityTaskWoken:この関数を終了した後にタスクを切り替えるかどうかをマークします. この変数の値関数は自動的に設定されます. ユーザーはそれを設定する必要はありません. ユーザーはこの値を保存するための変数を提供するだけで済みます. この値が pdTRUE の場合、割り込みサービス関数を終了する前にタスク切り替えを実行する必要があります。

戻り値:
pdPASS:ソフトウェア タイマーが正常に停止しました。これは、コマンドが正常に送信されたことを意味します。
pdFAIL:ソフトウェアタイマー停止失敗、コマンド送信失敗。

おすすめ

転載: blog.csdn.net/Dustinthewine/article/details/130416916