メールボックス:紹介と基本的なサービス
RTOSRevealedシリーズを表示する
メールボックスは以前の記事で紹介されました。これらはおそらく、Nucleus SEによってサポートされている、信号に続く2番目に簡単なタスク間通信方法です。これらは、タスク間で単純なメッセージを渡すための低コストでありながら柔軟な手段を提供します。
メールボックスの使用
Nucleus SEでは、メールボックスはビルド時に設定されます。アプリケーションには最大16個のメールボックスが構成されている場合があります。メールボックスが構成されていない場合、メールボックスに関連するデータ構造やサービス呼び出しコードはアプリケーションに含まれません。
メールボックスは単なる保存場所であり、 ADDR タイプの単一の変数を保持するのに十分な大きさです。 、複数のタスクで安全に利用できるようにアクセスが制御されます。 1つのタスクがメールボックスに書き込むことができます。その後、それはいっぱいになり、タスクがメールボックスで読み取りを行うか、メールボックスがリセットされるまで、タスクはそれに送信できません。完全なメールボックスに送信しようとしたり、空のメールボックスから読み取ろうとしたりすると、API呼び出しとNucleus SE構成で選択したオプションによっては、エラーやタスクの中断が発生する可能性があります。
メールボックスとキュー
一部のOS実装では、メールボックスが実装されていないため、代わりにシングルエントリキューの使用をお勧めします。このようなキューはメールボックスと同じ機能を提供するため、これは合理的に聞こえます。ただし、キューはメールボックスよりもかなり複雑なデータ構造であり、データ(ヘッドポインターとテールポインターなど)、コード、および実行時間でかなり多くのオーバーヘッドが発生します。
NucleusRTOSと同様にNucleusSEを使用すると、両方のオブジェクトタイプを選択でき、自分で決定できます。
アプリケーションに複数のキューが含まれているが、おそらく単一のメールボックスが含まれている場合は、別のアプローチを検討する価値があります。そのメールボックスをキューに置き換えると、わずかなデータオーバーヘッドが発生しますが、メールボックス関連のAPIコードはすべて削除されます。アプリケーションを双方向で構成し、メモリフットプリントとパフォーマンスを比較するのは非常に簡単です。
キューについては、今後の記事で説明します。
メールボックスの構成
メールボックスの数
Nucleus SEのほとんどの側面と同様に、メールボックスの構成は主に #define によって制御されます。 nuse_config.h のステートメント 。キー設定は NUSE_MAILBOX_NUMBER です 、アプリケーションに構成されているメールボックスの数を決定します。デフォルト設定は0(つまり、メールボックスは使用されていません)で、16までの任意の値に設定できます。値が間違っていると、コンパイル時エラーが発生し、 nuse_config_check.h <でのテストによって生成されます。 / strong> (これは nuse_config.c に含まれています したがって、このモジュールでコンパイルされます)結果として #error コンパイル中のステートメント。
ゼロ以外の値を選択することは、メールボックスの「マスターイネーブル」です。これにより、いくつかのデータ構造がそれに応じて定義およびサイズ設定されます。これについては、次の記事で詳しく説明します。また、APIを有効にする設定をアクティブにします。
APIの有効化
Nucleus SEのすべてのAPI関数(サービス呼び出し)には、有効な #define があります。 nuse_config.h の記号 。メールボックスの場合、これらは次のとおりです。
NUSE_MAILBOX_SEND
NUSE_MAILBOX_RECEIVE
NUSE_MAILBOX_RESET
NUSE_MAILBOX_INFORMATION
NUSE_MAILBOX_COUNT
デフォルトでは、これらはすべて FALSE に設定されています 、したがって、各サービスコールを無効にし、実装コードを含めることを禁止します。アプリケーションのメールボックスを構成するには、使用するAPI呼び出しを選択し、それらの有効化記号を TRUE に設定する必要があります。 。
これは、デフォルトの nuse_config.h からの抜粋です。 ファイル。
/ * 内のメールボックスの数 システム-0-16 * / #define NUSE_MAILBOX_NUMBER 0 / *サービスコールイネーブラー:* / #define NUSE_MAILBOX_SEND FALSE #define NUSE_MAILBOX_RECEIVE FALSE #define NUSE_MAILBOX_RESET FALSE #define NUSE_MAILBOX_INFORMATION FALSE #define NUSE_MAILBOX_COUNT FALSE
メールボックスAPI関数が有効で、メールボックスが構成されていない場合( NUSE_Mailbox_Count()を除く)、コンパイル時エラーが発生します。 これは常に許可されています)。コードで有効にされていないAPI呼び出しを使用すると、アプリケーションに実装コードが含まれていないため、リンク時間エラーが発生します。
メールボックスサービスコール
Nucleus RTOSは、メールボックスに関連する9つのサービス呼び出しをサポートし、次の機能を提供します。
-
メールボックスにメッセージを送信します。 NUSE_Mailbox_Send()によって実装されます NucleusSEで。
-
メールボックスからメッセージを受信します。 NUSE_Mailbox_Receive()によって実装されます NucleusSEで。
-
タスクを中断(リセット)せずに、メールボックスを未使用の状態に復元します。 NUSE_Mailbox_Reset()によって実装されます NucleusSEで。
-
指定されたメールボックスに関する情報を提供します。 NUSE_Mailbox_Information()によって実装されます NucleusSEで。
-
アプリケーション用に(現在)構成されているメールボックスの数を返します。 NUSE_Mailbox_Count()によって実装されます NucleusSEで。
-
アプリケーションに新しいメールボックスを追加します(作成します)。 NucleusSEには実装されていません。
-
アプリケーションからメールボックスを削除します(削除)。 NucleusSEには実装されていません。
-
アプリケーション内の(現在の)すべてのメールボックスへのポインターを返します。 NucleusSEには実装されていません。
-
メールボックスで一時停止されているすべてのタスクにメッセージを送信します(ブロードキャスト)。 NucleusSEには実装されていません。
これらの各サービス呼び出しの実装について詳しく調べます。
メールボックスの書き込みおよび読み取りサービス
メールボックスで実行できる基本的な操作は、メールボックスへのデータの書き込みです。これは、送信と呼ばれることもあります。 または投稿 –そしてそこからデータを読み取る–これは受信とも呼ばれます 。 NucleusRTOSとNucleusSEはそれぞれ、これらの操作のための2つの基本的なAPI呼び出しを提供します。これについては、ここで説明します。
メールボックスへの書き込み
メールボックスに書き込むためのNucleusRTOS API呼び出しは非常に柔軟であり、操作をすぐに完了できない場合は、無期限に、またはタイムアウトで一時停止することができます。つまり、メールボックス全体に書き込もうとします。 Nucleus SEは、タスクの一時停止がオプションであり、タイムアウトが実装されていないことを除いて、同じサービスを提供します。
Nucleus RTOSは、メールボックスにブロードキャストする機能も提供しますが、これはNucleusSEではサポートされていません。これについては、未実装のAPI で説明します。 次の記事で。
メールボックスに送信するためのNucleusRTOSAPI呼び出し
サービスコールプロトタイプ:
ステータスNU_Send_To_Mailbox(NU_MAILBOX *メールボックス、VOID *メッセージ、 署名されていない一時停止);
パラメータ:
メールボックス –使用するメールボックスへのポインタ
メッセージ –4つの署名されていないである送信されるメッセージへのポインタ 要素
一時停止 –タスクサスペンドの仕様。 NU_NO_SUSPEND の可能性があります または NU_SUSPEND またはタイムアウト値
返品:
NU_SUCCESS –通話は正常に完了しました
NU_INVALID_MAILBOX –メールボックスポインタが無効です
NU_INVALID_POINTER –メッセージポインタは NULL
NU_INVALID_SUSPEND –非タスクスレッドからサスペンドが試行されました
NU_MAILBOX_FULL –メールボックスがいっぱいで、一時停止が指定されていません
NU_TIMEOUT –指定された期間中断した後もメールボックスがいっぱいです
NU_MAILBOX_DELETED –タスクの一時停止中にメールボックスが削除されました
NU_MAILBOX_WAS_RESET –タスクが一時停止されている間にメールボックスがリセットされました
メールボックスに送信するためのNucleusSEAPI呼び出し
このAPI呼び出しは、Nucleus RTOSAPIの主要な機能をサポートしています。
サービスコールプロトタイプ:
STATUS NUSE_Mailbox_Send(NUSE_MAILBOXメールボックス、ADDR *メッセージ、 U8サスペンド);
パラメータ:
メールボックス –使用するメールボックスのインデックス(ID)
メッセージ –送信するメッセージへのポインタ。これは ADDR タイプの単一変数です。
一時停止 –タスクサスペンドの仕様。 NUSE_NO_SUSPEND の可能性があります または NUSE_SUSPEND
返品:
NUSE_SUCCESS –通話は正常に完了しました
NUSE_INVALID_MAILBOX –メールボックスインデックスが無効です
NUSE_INVALID_POINTER –メッセージポインタは NULL
NUSE_INVALID_SUSPEND –非タスクスレッドから、またはAPI呼び出しのブロックが有効になっていないときにサスペンドが試行されました
NUSE_MAILBOX_FULL –メールボックスがいっぱいで、一時停止が指定されていません
NUSE_MAILBOX_WAS_RESET –タスクが一時停止されている間にメールボックスがリセットされました
メールボックス送信のNucleusSE実装</ strong>
NUSE_Mailbox_Send()のコードの大部分 API関数(パラメーターチェック後)は、API呼び出しのブロック(タスクの一時停止)のサポートが有効になっているかどうかに応じて、条件付きコンパイルによって選択されます。ここでは、2つのバリアントを別々に見ていきます。
ブロッキングが有効になっていない場合、このAPI呼び出しのロジックは非常に単純であり、コードの説明はほとんど必要ありません。
if(NUSE_Mailbox_Status [mailbox])/ *メールボックスがいっぱいです* / {return_value =NUSE_MAILBOX_FULL;} else / *メールボックスが空です* / {NUSE_Mailbox_Data [mailbox] =* message; NUSE_Mailbox_Status [mailbox] =TRUE; return_value =NUSE_SUCCESS;}
メッセージは、 NUSE_Mailbox_Data [] の適切な要素に保存されます 使用中であるとマークされたメールボックス。
ブロッキングを有効にすると、コードはより複雑になります:
do {if(!NUSE_Mailbox_Status [mailbox])/ *メールボックスが空です* / {NUSE_Mailbox_Data [mailbox] =* message; NUSE_Mailbox_Status [mailbox] =TRUE; if(NUSE_Mailbox_Blocking_Count [mailbox]!=0){U8インデックス; / *タスクがブロックされているかどうかを確認します* / / *このメールボックスで* / NUSE_Mailbox_Blocking_Count [mailbox]-; for(index =0; indexいくつかの説明が役立つかもしれません:
コードは do…while で囲まれています ループ。パラメータが一時停止している間継続します 値は NUSE_SUSPEND 。
メールボックスが空の場合、提供されたメッセージが保存され、メールボックスのステータスが変更されて、メールボックスがいっぱいであることを示します。メールボックスで一時停止されている(受信を待機している)タスクがあるかどうかがチェックされます。待機中のタスクがある場合、最初のタスクがウェイクアップされます。 一時停止 変数は NUSE_NO_SUSPEND に設定されています API呼び出しは NUSE_SUCCESS で終了します 。
メールボックスがいっぱいで一時停止の場合 NUSE_NO_SUSPEND に設定されています 、API呼び出しは NUSE_MAILBOX_FULL で終了します 。 一時停止の場合 NUSE_SUSPEND に設定されました 、タスクは一時停止されています。戻り時(つまり、タスクがウェイクアップされたとき)、戻り値が NUSE_SUCCESS の場合 、(メールボックスのリセットではなく)メッセージが読み取られたためにタスクがウェイクアップされたことを示します。コードは先頭にループバックします。
埋め込み