目次
2.4. ulTaskGenericNotifyTake 関数
2.5. xTaskGenericNotifyWait 関数
例証します:
内容について:
1) 以下の内容は主に概念的な理解とステップ分析です。
2) 個人的なサンプルコードはまだありませんので、FreeRTOS の公式サンプルコードを使用します。
3) テスト用コードを移植したい場合は、以下のコンテンツに個人的なテスト用サンプルコードはありませんので、他を探してください。
その他について:
1) オペレーティングシステム: win10
2) プラットフォーム: keil 5 mdk
3) 言語: C 言語
4) ボード:STM32シリーズをFreeRTOSに移植
1. タスク通知
1.1. タスク通知とは何ですか?
タスクへの通知に使用され、タスク制御ブロック内の構造体メンバー ulNotifiedValue が通知値になります。
1.2. タスク通知の長所と短所
アドバンテージ:
1) より効率的であり、タスク通知を使用してイベントまたはデータをタスクに送信すると、キュー、イベント フラグ グループ、またはセマフォを使用するよりもはるかに速くなります。
2) 使用するメモリが少ないため、他の方法を使用する場合はそれに対応した構造体を作成する必要がありますが、タスク通知を使用する場合は構造体を作成する必要がありません。
短所:
1) データを ISR に送信できない (中断) ISR には構造体がないため (構造体メンバー ulNotifiedValue を介して)、データを ISR に送信できません。ただし、ISR はタスク通知を使用してタスクにデータを送信できます。
2) 複数のタスクをブロードキャストすることはできず、タスク通知は指定されたタスクによってのみ受信および処理できます。
3) 複数のデータをキャッシュすることはできません。タスク通知はタスク通知値を更新することでデータを送信します。タスク構造内にタスク通知値は 1 つだけあり、保存できるデータは 1 つだけです。
4) ブロックされた送信はサポートされていないため、送信者はブロック状態に入って待機することはできません。
1.3. タスク通知値の更新方法
1) 受け付けたタスクの通知値を上書きしません。
2) 受け入れられたタスクの通知値をオーバーライドします。
3) 受け入れられたタスク通知値の 1 つ以上のビットを更新します。
4) タスク受付通知値を増加します。
種類は次のとおりです。
1) カウント値(数値累計、型セマフォ)
2) 対応するビット、1 に設定 (イベント フラグ グループと同様)
3) 任意の値 (キューと同様に、上書きをサポートするかどうかをサポート)
上記の更新方法は、タスク通知の特性を合理的かつ柔軟に利用する限り、状況によってはキュー、セマフォ、およびイベント フラグ グループを置き換えることができます。
1.4. タスク通知値の状態
各タスクにはタスク制御ブロック TCB という構造があり、以下の図 1 に示すように 2 つの構造メンバー変数があります。
図1
注: uint32_t タイプは通知値を表すために使用され、uint8_t タイプは通知ステータスを表すために使用されます。
1.5. タスク通知ステータス
以下の図 2 に示すように、タスク通知ステータスには 3 つの値があります。
図2
名前、タスクは通知を待っていません。意味: タスク通知のデフォルトの初期化状態
名前、通知待ち、意味: 受信者は準備ができており (この時点で受信タスク通知関数が呼び出されています)、送信者からの通知を待っています。
名前、受信待ち、意味: 送信者が送信済み (この時点で送信タスク通知関数が呼び出されている)、受信者が受信するのを待っています
1.6. タスク通知方法の種類
コード:
typedef enum
{ eNoAction = 0, /* 通知値を更新せずにタスクを通知します。*/ eSetBits, /* タスクの通知値にビットを設定します。*/ eIncrement, /* タスクの通知値をインクリメントします。*/ eSetValueWithOverwrite, /* 前の値がタスクによってまだ読み取られていない場合でも、タスクの通知値を特定の値に設定します。*/ eSetValueWithoutOverwrite /* 以前の値がタスクによって読み取られている場合は、タスクの通知値を設定します。*/ } eNotifyAction;
パラメータの意味:
名前、eNoAction、意味: 操作なし
名前、eSetBits、意味: 指定されたビットを更新する
名前、eIncrement、意味: 通知値 +1
名前、eSetValueWithOverwrite、意味: 上書きモードで通知値を更新
名前、eSetValueWithoutOverwrite、意味: 通知値を上書きせずに更新する
2. タスク通知関連のAPI関数
2.1. 一般的に使用される通知 API 関数
以下の図 4 に示すように:
図4
2.2. 通知値を使用した通知機能の送信
コード:
BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify,
UBaseType_t uxIndexToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t * pulPreviousNotificationValue ) PRIVILEGED_FUNCTION;
パラメータの意味:
名前、xTaskToNotify、意味: タスク通知を受信するタスク ハンドル
名前、uxIndexToNotify、意味: タスクの指定された通知
名前、ulValue、意味: タスク通知値
名称、eAction、意味:通知方法(通知値関係方法)
名前、pulPreviousNotificationValue、意味: 更新前にタスク通知値を保存するために使用されます (NULL は保存されません)
2.3. 通知を受信するためによく使用される API 関数
関数名: ulTaskNotifyTask()
機能: タスク通知を取得します。この関数を終了するときにタスク通知値を 0 または -1 にクリアするように設定できます。タスク通知がバイナリ セマフォまたはカウント セマフォとして使用される場合、この関数を使用してセマフォを取得します。
関数名: xTaskNotifyWait()
機能: ulTaskNotifyTask よりも複雑なタスク通知を取得します。通知値を取得し、通知値の指定されたビットをクリアできます。
2.4. ulTaskGenericNotifyTake 関数
コード:
#define ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ) \
ulTaskGenericNotifyTake( ( tskDEFAULT_INDEX_TO_NOTIFY ), ( xClearCountOnExit ), ( xTicksToWait ) )
パラメータの意味:
名前、tskDEFAULT_INDEX_TO_NOTIFY、意味: タスクの指定された通知
名前、xClearCountOnExit、意味: 指定されたタスクが通知を正常に受信した後、通知値を 0 または -1 にクリアします。pdTRUE --> 通知値を 0 にクリアし、pdFALSE --> 通知値を -1 に設定します。
名前、xTicksToWait、意味: タスク通知の待機をブロックする最大時間値
戻り値の意味:
戻り値、0、意味: 受信失敗
戻り値、0 以外、意味: 受信成功、タスク通知の通知値を返します。
2.5. xTaskGenericNotifyWait 関数
コード:
#define xtasknotifywait(ulbitstocleAnentry、ulbitstoclearonexit、pulnotificationValue、xtickstowait)\
xtaskgenericnotifywait(tskdefault_index_to_notify、(ulbitocleAnotifizationvalue)、(Xickstowait)、
パラメータの意味:
名前、tskDEFAULT_INDEX_TO_NOTIFY、意味: タスクの指定された通知
名前、ulBitsToClearOnEntry、意味: 指定されたタスクによって通知されたビットのクリアを待機中
名前、ulBitsToClearOnExit、意味: 待機が成功した後に、指定されたタスク通知値ビットをクリアします。
名前、pulNotificationValue、意味: 通知値を取得するために使用されます (使用されない場合は NULL に設定されます)
名前、xTicksToWait、意味: タスク通知の待機をブロックする最大時間値
戻り値の意味:
戻り値、pdTRUE、意味: タスク通知の成功を待ちます。
戻り値、pdFALSE、意味: タスク通知の待機に失敗しました
注: この関数は、通知値の指定されたビット値を取得し、通知値をクリアするために使用されます。シミュレーション キューおよびイベント フラグ グループに適しています。タスクを取得するには、この関数を使用します。
2.6. 最適な使用場面
1) タスク通知をセマフォとして使用する場合、セマフォを取得する関数: ulTaskNotifyTask() を使用します。
2) タスク通知をイベントフラググループまたはキューとして使用する場合、xTaskNotifyWait()関数を使用して取得します。