1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Windowsシミュレータで学ぶuITRON (6) - アラームハンドラ

Posted at

はじめに

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

今回のお題は、周期ハンドラに続くタイマ機能である、アラームハンドラです。

本編

1. 環境

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

2. 動かしてみる

2-1. アラームハンドラの開始

コンソールで「alarm」と入力してみましょう(入力後にEnterを押してください)。

[2020/05/01 14:19:56.131] [TimerTask]: DELAY 3000ms
alarm
[2020/05/01 14:19:59.131] [TimerTask]: DELAY 3000ms
[2020/05/01 14:20:02.131] [TimerTask]: DELAY 3000ms
[2020/05/01 14:20:02.767] [UserAlarmHandler]: Alarm Timer Expired (1)
[2020/05/01 14:20:05.132] [TimerTask]: DELAY 3000ms
[2020/05/01 14:20:08.133] [TimerTask]: DELAY 3000ms

入力してから5000msec後、UserAlarmHandlerAlarm Timer Expired (n)を出力します(カッコ内の数値は満了回数)。

周期ハンドラと異なり、満了は1回のみです。

2-2. アラームハンドラの停止

次は、コンソールで「alarm」を入力した後、再度「alarm」投入してみましょう。

[2020/05/01 14:26:32.239] [TimerTask]: DELAY 3000ms
alarm
[2020/05/01 14:26:35.240] [TimerTask]: DELAY 3000ms
alarm
[2020/05/01 14:26:38.241] [TimerTask]: DELAY 3000ms
[2020/05/01 14:26:41.241] [TimerTask]: DELAY 3000ms
[2020/05/01 14:26:44.241] [TimerTask]: DELAY 3000ms

この場合、前述の満了ログは出力されません。

3. 解説

3-1. 概要

アラームハンドラは、指定時間経過後、何らかの処理を実施する仕組みです。
一般的にはワンショットタイマと呼ばれるものです。

(「ワンショット」という名称からも明らかですが)周期ハンドラとの違いは、1回の満了で終了する点です。

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

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

3-2-1. アラームハンドラ生成

cre_alm()で生成します。

    T_CALM calm;
    calm.almatr = TA_HLNG;
    calm.almhdr = UserAlarmHandler;
    cre_alm(ALARM_ID(USER), &calm);

このパラメータは下表:

パラメータ番号 名称 説明
第1パラメータ アラームハンドラID 単なるID。
以降はこのIDでもって開始・停止を実施。
第2パラメータ T_CALM構造体変数 下表で説明。

T_CALMのメンバは下表:

名称 指定可能な値 説明
almatr TA_HLNG 属性。高級言語を使用。
almhdr void func(void*) 満了時に呼び出すハンドラ関数。

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

3-2-2. アラームハンドラ開始・停止

それぞれsta_alm()stp_alm()を使います。

        /* Alarm */
        else if (EQUALS_(alarm)) {
            T_RALM ralm;
            ref_alm(ALARM_ID(USER), &ralm);
            if (!(ralm.almstat))    sta_alm(ALARM_ID(USER), 5000);
            else                    stp_alm(ALARM_ID(USER));
        }

またref_alm()を用い、アラームハンドラが起動しているか参照していますが、こちらの説明は割愛。

3-2-3. ハンドラ関数

(しつこいですが)ハンドラは非タスクコンテキスト、すなわち割り込みから呼ばれるので、簡潔な処理に留めないといけません。

今回はあまり有用な例ではなく、単にログを吐くだけです。

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

    static int32_t expired = 0;
    DEBUG_PRINT("[%s]: Alarm Timer Expired (%d)", __func__, ++expired);
}

おわりに

経験上、周期ハンドラよりも有用と感じますので、ぜひ使い方をマスターしてください!
(というほど難しい機能でもありませんが)

参考

Micro-ITRON4.0 Specification (in Japanese)
http://www.ertl.jp/ITRON/SPEC/mitron4-j.html

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?