キュー:紹介と基本的なサービス
RTOSRevealedシリーズを表示する
キューは以前の記事で紹介されました。メールボックスよりもタスク間で単純なメッセージを渡すためのより柔軟な手段を提供します。
キューの使用
Nucleus SEでは、キューはビルド時に構成されます。アプリケーションには最大16個のキューを構成できます。キューが構成されていない場合、キューに関連するデータ構造やサービス呼び出しコードはアプリケーションに含まれません。
キューは単にストレージの場所のセットであり、それぞれがタイプ ADDR の単一のデータアイテムを保持するのに十分な大きさです。 、複数のタスクで安全に利用できるようにアクセスが制御されます。すべての場所がいっぱいになるまで、タスクはキューに繰り返し書き込むことができます。タスクはキューから読み取ることができ、データは通常、先入れ先出し(FIFO)ベースで受信されます。完全なキューに送信しようとしたり、空のキューから読み取ろうとしたりすると、API呼び出しとNucleus SE構成で選択したオプションによっては、エラーまたはタスクの一時停止が発生する可能性があります。
キューとパイプ P>
Nucleus SEはパイプもサポートします。これは以前の記事でも紹介されており、今後の記事で詳しく説明されています。キューとパイプの主な違いは、メッセージのサイズです。キューは、単一の ADDR で構成されるメッセージを伝送します –これらは通常ポインターになります。パイプは、任意のバイト数のメッセージを伝送します。サイズはアプリケーションのパイプごとに固定され、構成時に設定されます。
キューの構成
キューの数
Nucleus SEのほとんどの側面と同様に、キューの構成は主に #define によって制御されます。 nuse_config.h のステートメント 。キー設定は NUSE_QUEUE_NUMBER です 、アプリケーションに構成されているキューの数を決定します。デフォルト設定は0(つまり、キューは使用されていません)で、16までの任意の値に設定できます。値が間違っていると、コンパイル時エラーが発生し、 nuse_config_check.h <でのテストによって生成されます。 / strong> (これは nuse_config.c に含まれています したがって、このモジュールでコンパイルされます)結果として #error コンパイル中のステートメント。
ゼロ以外の値を選択することは、キューの「マスターイネーブル」です。これにより、いくつかのデータ構造がそれに応じて定義およびサイズ設定されます。これについては、次の記事で詳しく説明します。また、APIを有効にする設定をアクティブにします。
APIの有効化
Nucleus SEのすべてのAPI関数(サービス呼び出し)には、有効な #define があります。 nuse_config.h の記号 。キューの場合、これらは次のとおりです。
NUSE_QUEUE_SEND
NUSE_QUEUE_RECEIVE
NUSE_QUEUE_JAM
NUSE_QUEUE_RESET
NUSE_QUEUE_INFORMATION
NUSE_QUEUE_COUNT
デフォルトでは、これらはすべて FALSE に設定されています 、したがって、各サービスコールを無効にし、実装コードを含めることを禁止します。アプリケーションのキューを構成するには、使用するAPI呼び出しを選択し、それらの有効化記号を TRUE に設定する必要があります。 。
これは、デフォルトのnuse_config.hファイルからの抜粋です。
#define NUSE_QUEUE_NUMBER 0 / *
システム - 0-16 * /
/ *サービスコールイネーブラー* /
の#define NUSE_QUEUE_SEND FALSE
の#define NUSE_QUEUE_RECEIVE FALSEの#define NUSE_QUEUE_JAMのFALSE
の#define NUSE_QUEUE_RESET FALSE
#define NUSE_QUEUE_INFORMATION FALSE
#define NUSE_QUEUE_COUNT FALSE
キューAPI関数が有効で、キューが構成されていない場合( NUSE_Queue_Count()を除く)、コンパイル時エラーが発生します。 これは常に許可されています)。コードで有効にされていないAPI呼び出しを使用すると、アプリケーションに実装コードが含まれていないため、リンク時間エラーが発生します。
キューサービスコール
Nucleus RTOSは、キューに関連する10個のサービス呼び出しをサポートし、次の機能を提供します。
-
メッセージをキューに送信します。 NUSE_Queue_Send()によって実装されます NucleusSEで。
-
キューからメッセージを受信します。 NUSE_Queue_Receive()によって実装されます NucleusSEで。
-
キューの先頭にメッセージを送信します。 NUSE_Queue_Jam()によって実装されます NucleusSEで。
-
タスクを中断(リセット)せずに、キューを未使用の状態に復元します。 NUSE_Queue_Reset()によって実装されます NucleusSEで。
-
指定されたキューに関する情報を提供します。 NUSE_Queue_Information()によって実装されます NucleusSEで。
-
アプリケーションに(現在)構成されているキューの数を返します。 NUSE_Queue_Count()によって実装されます NucleusSEで。
-
アプリケーションに新しいキューを追加します(作成します)。 NucleusSEには実装されていません。
-
アプリケーションからキューを削除します(削除)。 NucleusSEには実装されていません。
-
アプリケーション内の(現在)すべてのキューへのポインターを返します。 NucleusSEには実装されていません。
-
キューで中断されているすべてのタスクにメッセージを送信します(ブロードキャスト)。 NucleusSEには実装されていません。
これらの各サービス呼び出しの実装について詳しく調べます。
キューの書き込みおよび読み取りサービス
キューで実行できる基本的な操作は、キューにデータを書き込むことです。これは、送信と呼ばれることもあります。 –そしてそこからデータを読み取る–これは受信とも呼ばれます 。キューの先頭にデータを書き込むこともできます。これはジャミングとも呼ばれます。 。 NucleusRTOSとNucleusSEはそれぞれ、これらの操作のための3つの基本的なAPI呼び出しを提供します。これについては、ここで説明します。
キューへの書き込み
キューに書き込むためのNucleusRTOS API呼び出しは非常に柔軟であり、操作をすぐに完了できない場合は、無期限に、またはタイムアウトで一時停止することができます。つまり、キュー全体に書き込もうとします。 Nucleus SEは、タスクの一時停止がオプションであり、タイムアウトが実装されていないことを除いて、同じサービスを提供します。
Nucleus RTOSは、キューにブロードキャストする機能も提供しますが、これはNucleusSEではサポートされていません。これについては、次の記事の「実装されていないAPI」で説明しています。
キューに送信するためのNucleusRTOSAPI呼び出し
サービスコールプロトタイプ:
STATUS NU_Send_To_Queue(NU_QUEUE * queue、VOID * message、
UNSIGNED size、UNSIGNED suspend);
パラメータ:
キュー –ユーザー提供のキュー制御ブロックへのポインター
メッセージ –送信するメッセージへのポインタ
サイズ – 未署名の数 メッセージ内のデータ要素。キューが可変長メッセージをサポートする場合、このパラメーターは、キューでサポートされるメッセージサイズ以下である必要があります。キューが固定サイズのメッセージをサポートしている場合、このパラメーターは、キューでサポートされているメッセージサイズと完全に同じである必要があります。
サスペンド –タスクサスペンドの仕様。 NU_NO_SUSPEND の可能性があります または NU_SUSPEND またはタイムアウト値
返品:
NU_SUCCESS –通話は正常に完了しました
NU_INVALID_QUEUE –キューポインタが無効です
NU_INVALID_POINTER –メッセージポインタがNULLです
NU_INVALID_SIZE –メッセージサイズは、キューでサポートされているメッセージサイズと互換性がありません
NU_INVALID_SUSPEND –非タスクスレッドからサスペンドが試行されました
NU_QUEUE_FULL –キューがいっぱいで、サスペンドが指定されていません
NU_TIMEOUT –指定されたタイムアウト値で一時停止した後もキューはまだいっぱいです
NU_QUEUE_DELETED –タスクが一時停止されている間にキューが削除されました
NU_QUEUE_RESET –タスクが一時停止されている間にキューがリセットされました
キューに送信するためのNucleusSEAPI呼び出し
このAPI呼び出しは、Nucleus RTOSAPIの主要な機能をサポートしています。
サービスコールプロトタイプ:
STATUS NUSE_Queue_Send(NUSE_QUEUE queue、ADDR * message、
U8 suspend);
パラメータ:
キュー –使用するキューのインデックス(ID)
メッセージ –送信するメッセージへのポインタ。これは ADDR タイプの単一変数です。
サスペンド –タスクサスペンドの仕様。 NUSE_NO_SUSPEND の可能性があります または NUSE_SUSPEND
返品:
NUSE_SUCCESS –通話は正常に完了しました
NUSE_INVALID_QUEUE –キューインデックスが無効です
NUSE_INVALID_POINTER –メッセージポインタがNULLです
NUSE_INVALID_SUSPEND –非タスクスレッドから、またはAPI呼び出しのブロックが有効になっていないときにサスペンドが試行されました
NUSE_QUEUE_FULL –キューがいっぱいで、サスペンドが指定されていません
NUSE_QUEUE_WAS_RESET –タスクが一時停止されている間にキューがリセットされました
NucleusSEによるキューASendの実装
NUSE_Queue_Send()のコードの大部分 API関数(パラメーターチェック後)は、API呼び出しのブロック(タスクの一時停止)のサポートが有効になっているかどうかに応じて、条件付きコンパイルによって選択されます。ここでは、2つのバリアントを別々に見ていきます。
ブロッキングが有効になっていない場合、このAPI呼び出しのコードは非常に単純です。
if(NUSE_Queue_Items [queue] ==NUSE_Queue_Size [queue])/ *キューがいっぱい* / {return_value =NUSE_QUEUE_FULL;} else / *キュー要素が使用可能* / {NUSE_Queue_Data [queue] [NUSE_Queue_Head [queue] ++] =*メッセージ; if(NUSE_Queue_Head [queue] ==NUSE_Queue_Size [queue]){NUSE_Queue_Head [queue] =0; } NUSE_Queue_Items [queue] ++; return_value =NUSE_SUCCESS;}
この関数は、キューに空きがあることを確認し、 NUSE_Queue_Head [] を使用するだけです。 キューのデータ領域にメッセージを保存するためのインデックス。
ブロッキングを有効にすると、コードはより複雑になります:
do {if(NUSE_Queue_Items [queue] ==NUSE_Queue_Size [queue])/ *キューがいっぱい* / {if(suspend ==NUSE_NO_SUSPEND){return_value =NUSE_QUEUE_FULL; } else {/ *タスクをブロックする* / NUSE_Queue_Blocking_Count [queue] ++; NUSE_Suspend_Task(NUSE_Task_Active、(queue <<4)| NUSE_QUEUE_SUSPEND); return_value =NUSE_Task_Blocking_Return [NUSE_Task_Active]; if(return_value!=NUSE_SUCCESS){suspend =NUSE_NO_SUSPEND; }}} else {/ *使用可能なキュー要素* / NUSE_Queue_Data [queue] [NUSE_Queue_Head [queue] ++] =* message; if(NUSE_Queue_Head [queue] ==NUSE_Queue_Size [queue]){NUSE_Queue_Head [queue] =0; } NUSE_Queue_Items [queue] ++; if(NUSE_Queue_Blocking_Count [queue]!=0){U8インデックス; / *このキューでタスクがブロックされているかどうかを確認します* / NUSE_Queue_Blocking_Count [queue]-; for(index =0; indexコードの説明が役立つ場合があります:
コードは do…while で囲まれています ループ。パラメータの一時停止の値が NUSE_SUSPEND である間継続します。 。
キューがいっぱいで一時停止の場合 NUSE_NO_SUSPEND に設定されています 、API呼び出しは NUSE_QUEUE_FULL で終了します 。サスペンドが NUSE_SUSPEND に設定されている場合 、タスクは一時停止されています。戻り時(つまり、タスクがウェイクアップされたとき)、戻り値が NUSE_SUCCESS の場合 、(キューのリセットではなく)メッセージが読み取られたためにタスクがウェイクアップされたことを示します。コードは先頭にループバックします。
キューがいっぱいでない場合、提供されたメッセージは NUSE_Queue_Head [] を使用して保存されます キューのデータ領域にメッセージを格納するためのインデックス。キューで一時停止されている(受信を待機している)タスクがあるかどうかがチェックされます。待機中のタスクがある場合、最初のタスクがウェイクアップされます。 一時停止 変数は NUSE_NO_SUSPEND に設定されています API呼び出しは NUSE_SUCCESS で終了します 。
埋め込み