LoginSignup
2
1

More than 3 years have passed since last update.

Windowsシミュレータで学ぶuITRON (3) - メールボックス

Last updated at Posted at 2019-09-17

はじめに

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

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1