はじめに
uITRON(FreeRTOSベース)Windowsシミュレータ - Qiita
https://qiita.com/imagou/items/42c687402e6e58fccddb
今回のお題は、何かあったことに加え、追加情報を伝えるメールボックスです。
(「何かあったこと」のみであれば、イベントフラグでOK)
本編
1. 環境
こちらの記事を参照ください。
2. 動かしてみる
こちらは初回記事を参照。
2-1. タスクでのメール送受信
改めて「2-2. 送信タスク・受信タスク」の動作を確認してください。
3. 解説
3-1. 概要
メールボックスとは、前述したように**「何かが発生したことに加え、情報を伝える仕組み」**です。
(「メール」って名称からお察しではありますが・・・)
メールの型(メッセージという呼び方をします)はユーザーで自由に決められます。
若干面倒なポイントは以下です:
- ユーザーがメッセージ領域を確保する必要あり
- メッセージの取得・解放もユーザーの責務
3-2. コードによる説明
以降は、プログラムコード - main.c
を引用して説明します。
3-2-1. メッセージ定義・領域確保
メッセージの型と、領域(64個分)の確保箇所は以下です。
/*--- Message ---*/
typedef struct {
T_MSG msg;
ID id;
uint32_t params[1];
} MESSAGE_ENTITY;
#define MESSAGE_SIZE (64)
static MESSAGE_ENTITY g_Messages[MESSAGE_SIZE];
static uint16_t g_MessageIndex = 0;
注意事項として、構造体先頭のT_MSG msg;
は必ず含めてください。RTOSの予約領域です。
3-2-2. メッセージ取得・解放
以下を参照ください。
/* メッセージ取得 */
static MESSAGE_ENTITY* GetUserMessage(void) {
uint16_t index = g_MessageIndex++;
index %= MESSAGE_SIZE;
return &(g_Messages[index]);
}
/* 解放はまだ用意していない */
GetUserMessage()
は、リングバッファとして領域を扱い、返しているだけです。
解放は色々あって未実装ですが、メッセージを同時に64個以上送信することがなければ、なくてもいいかなーと思っています(面倒くさいわけではないですよ!笑)。
3-2-3. メールボックス生成
cre_mbx()
で生成します。
T_CMBX cmbx;
cmbx.mbxatr = TA_TFIFO;
cre_mbx(MAILBOX_ID(RECV), &cmbx);
cre_mbx()
のパラメータは下表:
パラメータ番号 | 名称 | 説明 |
---|---|---|
第1パラメータ | メールボックスID | 単なるID。 以降はこのIDでもってメールボックス送信・受信を実施。 |
第2パラメータ | T_CMBX構造体変数 | 以下で説明 |
T_CMBXのメンバは下表:
名称 | 指定可能な値 | 説明 |
---|---|---|
mbxatr | TA_TFIFO | TA_TPRI | メールボックス属性。 それぞれ、待ちキューの順序をFIFO順とするか、優先度順とするか。 |
※なお、mbxatrはこれ以外の値も指定可能(だが、上記のみで必要十分と考える)。
3-2-4. メールボックスへの送信
snd_mbx()
を使います。
id
にはイベントを数値に変換したもの、params[0]
にはカウンタを渡して送信しています。
MESSAGE_ENTITY* ent;
ent = GetUserMessage();
/* Numeric Event */
/* メッセージIDはイベントを(数値に戻して)設定 */
/* パラメータにカウンタを渡す */
int32_t num = 0;
for (num = 0; !((flgptn >> num) & 1) ; num++) ;
ent->id = (ID)num;
ent->params[0] = ++count;
snd_mbx(MAILBOX_ID(RECV), (T_MSG *)ent);
3-2-5. メールボックスからの受信
rcv_mbx()
を使用します。
T_MSG *msg;
rcv_mbx(MAILBOX_ID(RECV), &msg);
MESSAGE_ENTITY* ent = (MESSAGE_ENTITY*)(msg);
DEBUG_PRINT("[%s]: RECV MESSAGE (%d,%d)", __func__, ent->id, ent->params[0]);
3-3. TBD
TBD(今後追加していく予定)
おわりに
メールボックスは、メッセージ領域の確保が若干面倒なので、
イベントフラグ+外部変数
という使い方をする方も多いように思います(やってることは変わりませんからね)。
が、一応解説してみました。笑
参考
Micro-ITRON4.0 Specification (in Japanese)
http://www.ertl.jp/ITRON/SPEC/mitron4-j.html