LoginSignup
2
1

More than 3 years have passed since last update.

Windowsシミュレータで学ぶuITRON (2) - イベントフラグ

Last updated at Posted at 2019-09-12

はじめに

uITRON(FreeRTOSベース)Windowsシミュレータ - Qiita
https://qiita.com/imagou/items/42c687402e6e58fccddb

今回のお題は、何かあったことを伝えるイベントフラグです。

本編

1. 環境

こちらの記事を参照ください。

2. 動かしてみる

こちらは初回記事を参照。

2-1. タスクでのイベント設定・待ち

改めて「2-2. 送信タスク・受信タスク」の動作を確認してください。

2-2. 割り込みでのイベント設定

次にコンソールで「cyclic」と入力してみます。

[TimerTask]: DELAY 3000ms
cyclic
[SendTask]: RECV EVENT (00000001)
[SendTask]: Cyclic Timer Expired (1)
[TimerTask]: DELAY 3000ms
[SendTask]: RECV EVENT (00000001)
[SendTask]: Cyclic Timer Expired (2)
[SendTask]: RECV EVENT (00000001)
[SendTask]: Cyclic Timer Expired (3)
[SendTask]: RECV EVENT (00000001)
[SendTask]: Cyclic Timer Expired (4)
[TimerTask]: DELAY 3000ms
[SendTask]: RECV EVENT (00000001)
[SendTask]: Cyclic Timer Expired (5)

どうやら、1000msecおきに「Cyclic Timer Expired」が発生するようになったようです。

3. 解説

3-1. 概要

イベントフラグとは、前述したように「何かが発生したことを伝える仕組み」です。

型は32-bitであり、それぞれのビットにイベントを割り当てることができます。

3-2. コードによる説明

以降は、プログラムコード - main.cを引用して説明します。

3-2-1. イベント定義

イベントの定義は以下。

/*--- Event ---*/
#define EVENT_ALL       (0x00FFFFFF)    /* FreeRTOS仕様制限で、最大で24-bit */
#define EVENT_CYCLIC    (0x00000001)
/* Reserved bit1 - bit15 */
#define EVENT_STOP      (0x00010000)
#define EVENT_RESTART   (0x00020000)

コメントにあるように、FreeRTOS制限で24-bitしか使えないのですが(笑)、日本語で書くと以下の割り当てとなっています。

bit 説明
bit0 CYCLICイベント(周期タイマを開始するイベント)
bit1 - bit15 予約(数値を通知するイベント)
bit16 停止イベント
bit17 再開イベント

3-2-2. イベントフラグ生成

cre_flg()で生成します。

    T_CFLG cflg;
    cflg.flgatr = TA_WSGL;
    cflg.iflgptn = 0;
    cre_flg(FLAG_ID(SEND), &cflg);

cre_flg()のパラメータは下表:

パラメータ番号 名称 説明
第1パラメータ イベントフラグID 単なるID。
以降はこのIDでもってイベントフラグ設定・待ちを実施。
第2パラメータ T_CFLG構造体変数 以下で説明

T_CFLGのメンバは下表:

名称 指定可能な値 説明
flgatr TA_WSGL | TA_WMUL イベントフラグ属性。
それぞれ、1つのタスクで待つか・複数のタスクで待つか。
たいていの場合はTA_WSGLでよい。
iflgptn イベントフラグ初期値 左記の通り。たいていの場合は0でよいだろう。

※なお、flgatrはこれ以外の値も指定可能(だが、TA_WSGLで必要十分と考える)。

3-2-3. イベントフラグ設定

通常のタスクではset_flg()を使います。

        /* Numeric Event (1 To 15) */
        if ((0 < num) && (num < 16)) {
            set_flg(FLAG_ID(SEND), (1 << num));
        }
#define EQUALS_(x) (0 == strcmp(str, #x))
        /* Suspend */
        else if (EQUALS_(stop)) {
            set_flg(FLAG_ID(SEND), EVENT_STOP);
        }
        /* Resume */
        else if (EQUALS_(start)) {
            set_flg(FLAG_ID(SEND), EVENT_RESTART);
        }

上記コードでは、以下のイベントを設定しています:

  • 数値が指定されたら、対応するビットを立てたイベント
  • 「stop」「start」が指定されたら、それぞれ停止・再開イベント

対して、割り込みではiset_flg()を用います。

static void UserCyclicHandler(void* params)
{
    /* Just to remove compiler warning. */
    (void)params;

    iset_flg(FLAG_ID(SEND), EVENT_CYCLIC);
}

こちらは、CYCLICイベントを設定しています。

3-2-4. イベント待ち

wai_flg()を使用します。

        FLGPTN flgptn;
        wai_flg(FLAG_ID(SEND), EVENT_ALL, TWF_ORW, &flgptn);
        DEBUG_PRINT("[%s]: RECV EVENT (%08X)", __func__, flgptn);

        /* Suspend Task */
        if (flgptn & EVENT_STOP) {
            sus_tsk(TASK_ID(RECV));
            continue;
        }
        /* Resume Task */
        if (flgptn & EVENT_RESTART) {
            rsm_tsk(TASK_ID(RECV));
            continue;
        }

        /* Cyclic Event */
        if (flgptn & EVENT_CYCLIC) {
            static int32_t expired = 0;
            DEBUG_PRINT("[%s]: Cyclic Timer Expired (%d)", __func__, ++expired);
            continue;
        }

wai_flg()のパラメータで重要なものは以下:

パラメータ番号 指定可能な値 説明
第2パラメータ 待ち合わせるビットパターン 本デモではすべてのビットを指定
第3パラメータ TWF_ANDW / TWF_ORW 指定したビットがすべて立つまで待つ / いずれか1つが立つまで待つ
第4パラメータ 受信したビットパターン

第4パラメータflgptnでもって、それ以降の判定を実施しています。

また、数値用イベントのコードは抜粋していませんので、コードを直接参照ください(雑)。

3-3. TBD

TBD(今後追加していく予定)

おわりに

1ビットだけでは情報が足りない場合は、メールボックス(メッセージ)を使いましょう(次回への伏線)。

参考

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