LED点滅処理
基本は IOポートでLEDを光らせる と同じです。
また OSの作る待ち時間も正確なので タイマーで正確な時間稼ぎをする(タイマーA) とも役割が同様。
これをRTOS μITRON を使ってやってみる。
OSなしではメインの中で処理を記述していたのを、μITRONではタスクで処理をする方法。
処理タスクを作る=LED点灯タスク このタスクを設定する、 実行する。
という処理の流れ。
実験回路
IOポートでLEDを光らせる と同じ
プログラム
sample.c
/* ------------------------------------------------------------------------
IOポートでLEDを光らせる
P1-4 と P1-5 が1秒間隔で交互に点灯
間隔時間に サービスコール=dly_tsk( ) 使用
------------------------------------------------------------------------ */
#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--pin20 */
IO.PDR1.BIT.B5=0;
dly_tsk(1000); /*1秒待つ */
IO.PDR1.BIT.B5=1; /* P15--pin21 */
IO.PDR1.BIT.B4=0;
dly_tsk(1000); /*1秒待つ */
}
}
sample.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});
sample.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);
#endif /* __PROJECT_HOS__sample_h__ */
* (最初に) プログラムは主に xx.c ファイル以外に xx.cfg xx.h を必要に応じて編集する
Cファイルで
I/Oポートの初期化設定
void Initialize(VP_INT exinf){
} 内に記述。
main(){ } においても同様な結果でしたが、今のところOSでmain()がどの時点で呼ばれるのか詳しくわかりません。
IOポートでLEDを光らせる
と同様に LEDをつないだ I/Oポート を出力の設定に。
・なにもしない時間稼ぎ関数
OS無しでは無駄ループを回して空白時間を作っていたのを ここでは delyのサービスコールで遅らせます。
dly_tsk(1000); /*1秒待つ */
タスク
/* タスク1 */
void Task1(VP_INT exinf) で LEDの点滅処理を記述
cfgファイルで
タスクの起動
タスク生成
CRE_TSK(TSKID_SAMPLE1, {TA_HLNG|TA_ACT, 1, Task1, 1, 256, NULL});
LED点滅のプログラム(ここではタスクTask1) の実行は cfgファイル CRE_TSKで OSに設定され、実行されている
意識してない処理記述ですが cfg で タスクをOSスタート時に自動起動にしてあります。
CRE_TSK( TASKID_NEW, { TA_HLNG | TA_ACT , 0 , NewTask, 1, ,256 ,NULL)
CRE_TSK 内でタスク生成時に、 TA_ACT 設定で OSスタート時にタスクの自動起動設定
ここ TA_ACT を外し
→CRE_TSK( TASKID_NEW, { TA_HLNG, 0 , NewTask, 1, ,256 ,NULL)
初期化ハンドラのイニシャライズで コメントアウトしている act_tskの実行で起動しても同様。
→ /* 初期化ハンドラ */
void Initialize(VP_INT exinf)
{
act_tsk(TSKID_SAMPLE1);
}
タスクの起動については後でまた登場
実行結果
OSなしの ループを使って遅らせたのと同様の結果です。
プログラムを実行すると ピコピコと2個のLEDが交互に点滅します。間隔を変えるのは delyのサービスコールの 数字を変更します。
一応これでほぼ正確な待ち時間がでてます。(完全にはdelyの使うタイマの刻み値のせいで正確ではない)
間隔時間を扱うことがよくありますがμITRONだと扱いやすいです。
待ち時間もなかなか正確なので タイマーで正確な時間稼ぎをする(タイマーA) とも似ていますが、また後でタイマーなどをμITRONで使用する方法も登場。
μITRON使用で 以前のOSなし との違い
【OSなしの場合】
無駄ループを回して、空白時間を作っていた
void msecwait(int msec) /*なにもしない時間稼ぎ関数*/ のを、
【μITRONの場合】
delyのサービスコールで遅らせています。
時間をおいて点滅させるという効果では同じですが、役割を考えると違いがあります。
【OSなしの場合】
msecwait(int msec)無駄ループでは 空に回っているだけですが、これもループで積算するという立派な処理。
無駄な処理に見えますが、この間は、他の処理は何もできません。
【μITRONの場合】
delyのサービスコールです。
遅らせる時間を設定してあるので、その時間が来ると帰ってきて処理する。
- twtter
- google+
- hatena