LoginSignup
3
2

More than 3 years have passed since last update.

Windowsシミュレータで学ぶuITRON (1) - タスク操作

Last updated at Posted at 2019-09-06

はじめに

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

にて、せっかくuITRONを体験できる環境を作りましたんで、体験してみましょう。

今回のお題は、RTOSの肝である「タスク」です。

本編

1. 環境

前回記事を参照ください。

2. 動かしてみる

ビルド方法はこちら

後はF5押下などしてやれば、コンソールウインドウでデモプログラムが動きます。

2-1. タイマタスク

放置しておくと、コンソールで以下が出力されるはずです。

[TimerTask]: DELAY 3000ms
[TimerTask]: DELAY 3000ms
[TimerTask]: DELAY 3000ms
[TimerTask]: DELAY 3000ms

TimerTaskとやらが、3000msecおきに動作しているらしい、ということがわかるかと思います。
(当方の環境ですと3000msecより相当長いですが、その解析は後回し)

2-2. 送信タスク・受信タスク

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

[TimerTask]: DELAY 3000ms
[TimerTask]: DELAY 3000ms
10
[SendTask]: RECV EVENT (00000400)
[RecvTask]: RECV MESSAGE (10,1)

どうやら「10」がSendTaskからRecvTaskに通知されているようです。

そこで次は、「stop」を入力後、再度「10」を入力してみます。

[TimerTask]: DELAY 3000ms
stop
[SendTask]: RECV EVENT (00010000)
10
[SendTask]: RECV EVENT (00000400)
[TimerTask]: DELAY 3000ms

おや?今回はRecvTaskが動いていませんね。

次に「start」を入力します。

[TimerTask]: DELAY 3000ms
start
[SendTask]: RECV EVENT (00020000)
[RecvTask]: RECV MESSAGE (10,2)

お察しの通り、RecvTaskが動き出し、先ほどの「10」を受信しています。

2-3. もっと動かしたくなったら

使い方を読んでください(雑)。

3. コードによる解説

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

なお、実際に裏で動いているのはFreeRTOSですので、その制限を受けています。

3-1. タスク生成

cre_tsk()を使います。

#define CREATE_TASK(name, act, func) {   \
    T_CTSK ctsk_;   \
    ATR tskatr_ = TA_HLNG;  \
    if (act) tskatr_ |= TA_ACT; \
    ctsk_.tskatr = tskatr_;                 /* タスク属性 */ \
    ctsk_.exinf = NULL;                     /* タスク起動時パラメータ */ \
    ctsk_.task = func;                      /* タスク関数 */ \
    ctsk_.itskpri = TASK_PRI(name);         /* タスクの優先度 */   \
    ctsk_.stksz = sizeof(TASK_STACK(name)); /* タスクスタックサイズ */   \
    ctsk_.stk = TASK_STACK(name);           /* タスクスタック(静的に確保しておく必要あり) */    \
    cre_tsk(TASK_ID(name), &ctsk_); \
}

マクロ定義しちゃってますが、要は以下を指定して、タスクを生成しています。

  • タスク属性(TA_ACT指定で即「実行可能状態」となる)
  • タスク関数
  • 優先度
  • スタックとそのサイズ

3-2. タスク起動・中断・再開

3-2-1. タスク起動

    CREATE_TASK(TIMER, FALSE, TimerTask);

とあるように、TimerTask - タイマタスクは遅延起動しているので、sta_tsk()を明示的に呼ぶ必要があります。

    /* タイマタスクは遅延起動 */
    /* sta_tsk()を使いたいがためだけにこうしている */
    sta_tsk(TASK_ID(TIMER), NULL);

3-2-2. タスク中断・再開

それぞれsus_tsk()rsm_tsk()を使います。

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

3-2-3. 補足

uITRONでは「待ち状態 - WAITING」「強制待ち状態 - SUSPENDED」の区別があります。
関数との関係はこちら:

  • 「待ち状態」から「実行可能状態 - READY」とするのがsta_tsk()
  • 「実行状態」などから「強制待ち状態」とするのがsus_tsk()
  • 「強制待ち状態」から「実行可能状態」とするのがrsm_tsk()

しかしながら、FreeRTOSには「SUSPENDED」状態しかないらしく、よってsta_tsk()rsm_tsk()の本シュミレータ上の実装は同じです。

3-3. タスク遅延

dly_tsk()を使います。

    while (1) {
        RELTIM tim = 3000;
        DEBUG_PRINT("[%s]: DELAY %dms", __func__, tim);
        dly_tsk(tim);
    }

3-4. TBD

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

おわりに

簡単(フワフワっとした)なタスク操作の説明でした。

読むだけでなく、実際に動かしてみると、より理解が深まるかと思います!

参考

FreeRTOS API categories
https://www.freertos.org/a00106.html

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

3
2
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
3
2