IOポートでLEDを光らせる

まずは、OS:uIRONを使ってLEDを単純に点滅させる処理でマルチタスクOSを理解

 

OSを使わずに作った以前の同じ処理を、uIRONを使った処理で作り比較と体験をしてみる。

割と複雑にもなりますが、幾通りもの処理方法で出来るその最初の方法です。


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のサービスコールです。
遅らせる時間を設定してあるので、その時間が来ると帰ってきて処理する。

 

スポンサーリンク
  • facebook
  • twtter
  • google+
  • hatena