2つのタスク
続いて2つのタスクを走らせてみます。
LEDを点灯、時間をおいて消灯などで点滅をしたので、2つの点滅時間の違うタスクを作ってみます。
2つのタスク=マルチタスクです
同じようにもう一つのタスクとしてdelyで遅らせる点滅のプログラムを作り、dely時間の違う2つの違う点滅を作って走らせる
実験回路
IOポートでLEDを光らせる と同じ
プログラム
*.c
/* ------------------------------------------------------------------------
IOポートでLEDを光らせる
Task1 : P1-4 1秒間隔で点灯
Task2 : P1-5 0.25秒間隔で点灯
間隔時間に サービスコール=dly_tsk( ) 使用
2タスクを平行に走らせる
------------------------------------------------------------------------ */
#include "itron.h"
#include "kernel.h"
#include "kernel_id.h"
#include "h83664f.h"
/* メイン関数 */
int main()
{
sta_hos();
return 0;
}
/* 初期化ハンドラ */
void Initialize(VP_INT exinf)
{
/* ポート初期化設定 */
IO.PMR1.BYTE=0x00; /* 全て0にセットし、ポート使用に設定 0000 0000*/
IO.PCR1=0xFF; /* 全て1にセットし、出力に設定 1111 1111 */
IO.PUCR1.BYTE=0x00; /* 全て0にセットし、プルアップなし*/
// act_tsk(TSKID_SAMPLE1);
}
/* タスク1 */
void Task1(VP_INT exinf)
{
for ( ; ; )
{
IO.PDR1.BIT.B4 = 1; /* P14 */
dly_tsk(1000); /*1秒待つ */
IO.PDR1.BIT.B4=0; /* P15 */
dly_tsk(1000); /*1秒待つ */
}
}
void Task2(VP_INT exinf)
{
for ( ; ; )
{
IO.PDR1.BIT.B5=0; /* P15 */
dly_tsk(250); /*0.25秒待つ */
IO.PDR1.BIT.B5=1; /* P15 */
dly_tsk(250); /*0.25秒待つ */
}
}
*.cfg
/* ------------------------------------------------------------------------ */
/* Hyper Operating System V4 サンプルプログラム */
/* コンフィギュレーションファイル */
/* ------------------------------------------------------------------------ */
INCLUDE("\"sample.h\"");
INCLUDE("\"ostimer.h\"");
INCLUDE("\"h8t_sci.h\"");
/* HOS 独自の設定 */
HOS_KERNEL_HEAP(0); /* カーネルヒープの設定(省略時 0) */
HOS_TIM_TIC(1024, 125); /* タイムティックの設定(省略時 1/1 ) */
HOS_MAX_TPRI(8); /* 最大優先度(省略時 16) */
HOS_MIN_INTNO(19); /* 使用する割り込み番号の最小値(省略時 0) */
HOS_MAX_INTNO(23); /* 使用する割り込み番号の最大値(省略時 0) */
HOS_MAX_TSKID(8); /* 最大タスクID番号(省略時静的生成に必要なだけ) */
/* OS タイマ */
ATT_INI({TA_HLNG, 0, OsTimer_Initialize});
ATT_ISR({TA_HLNG, 0, 19, OsTimer_TimerHandler});
/* サンプルプログラム */
ATT_INI({TA_HLNG, 0, Initialize});
CRE_TSK(TSKID_SAMPLE1, {TA_HLNG|TA_ACT, 1, Task1, 1, 256, NULL});
CRE_TSK(TSKID_SAMPLE2, {TA_HLNG|TA_ACT, 2, Task2, 2, 256, NULL});
*h
/* ------------------------------------------------------------------------ */
/* Hyper Operating System V4 サンプルプログラム */
/* */
/* ------------------------------------------------------------------------ */
#ifndef __PROJECT_HOS__sample_h__
#define __PROJECT_HOS__sample_h__
void Initialize(VP_INT exinf);
void Task1(VP_INT exinf);
void Task2(VP_INT exinf);
#endif /* __PROJECT_HOS__sample_h__ */
dly()を使って1秒間隔を作ったTask1 、 同じもので間隔時間0.25秒のTask2を作ります。
2つを登録して実行する。優先順位は1と2にしました。両方1にもできますが。
LED点滅のTask1の下に 同じようなTask2が増えただけですが、2つのプログラムです。
当然、どちらか1つだけでも動きますが、2つ両方も走らせることができる
CRE_TSK(TSKID_SAMPLE1, {TA_HLNG|TA_ACT, 1, Task1, 1, 256, NULL});
// CRE_TSK(TSKID_SAMPLE2, {TA_HLNG|TA_ACT, 2, Task2, 1, 256, NULL});
cfgファイルでcreateタスクの1つをコメントアウトすると、1つだけの実行になる。この2つの実行を簡単に切り替えられるところもμITRONを使った特徴です。
実行結果
2つは違うタスクで点滅プログラムは別ですが、平行してTask1、Task2が走ります。
Task1 | ● ○ ○ ○ ● ○ ○ ○ ● |
Task2 | ● ● ● ● ● ● ● ● ● |
同時に違うLEDの点滅動作の2つが平行して実行されているのがわかる。
タスクが1つ増えただけですが、2つ同時に動くと楽しいです(^^
main()のループ処理に慣れていると、右手と左手で別々のことをしているように見えて、最初しばらくはマルチタスクは違和感があります。。
Task1、Task2 共に無限ループで、出口はないように感じますがタスクが違うのでマルチタスクなら同時に走って当然です。
dely()は遅らせる時間なので指定時間に返って来てまた処理したらいいだけなので、OSなしのループで遅らせとは別物です。
実際のタスク内の処理は
IOで出力の切り替え、時間をおく、またIOで出力の切り替え の繰り返しなので、時間がきてIOの切り替えしてるだけの軽い処理なのでタスク3つでも4つでも実行できるはずです。
2つ以上の実行を独立して作りたいことはよくあり、各タスクの処理はOSがやってくれるのでこの点はやはり格段にいいです。
このような処理をOS使わない場合は、割り込み処理などを使うので面倒な設定がでてきますが、μITRONを使うとちょっとおもしろくなってくるところです。
マルチタスクでもマイコンが同時に処理できるのは1つなので、処理がぶつかると優先順位と待ちの状態が関係して複雑になりますが、待ち状態に関連するところは後で登場です。
マルチタスクらしい処理と実行なのでちょっと楽しいところです。
- twtter
- google+
- hatena