SSブログ

某4月23日号のプログラムのパクリ [Smalight OS]

某誌の4月23日号では、タスク1でスイッチのスキャンを行い、スイッチが押されたらタスク2とタスク3に通達。
タスク2はタスク1からの通達を切欠に500ms周期でLEDを点滅させる電子サイコロ?プログラムを実行。
タスク3は、30秒間スイッチが押されなければ、二つのLEDを1秒周期で点滅させるデモプログラムを実行させる。
と言うお題目が出されていました。

んで、電子サイコロの所は凝った所でタカが知れているので、適当に作成し、お題目に沿って作成してみたのが以下のコードです(*´ー`)。
面倒だし、表示し切れないので、オリジナルではないプログラムと、コメントはあらかた削除しています。

システムタイマーの更新は10ms周期で行うので、config.cの例の所も修正してね。

そうそう、元のプログラムでは二つのタスク(tsk02、tsk03)との同期には両方共イベントフラグを使用していましたが、このプログラムではtsk02の同期にカウンタセマフォを利用する事で、tsk02が動作中も複数の新たな要求を記憶できるメリットがあります。
まあ両方共イベントフラグでやっても良いんですけれどね、その場合は1イベントしか記憶できないので、tsk02が点滅中に一回のみスイッチの入力が有効になります。
しかし、二つのタスクが一つのイベントフラグ待ちになる可能性が有るのに、クリア属性は如何なものか?とは思うけれど。

あと、折角イベントフラグ使ってタスク間の同期(通信はしていないと思うが)の解説をしているのに、何故か大域変数を使って、やっぱりそっちでも同期を取ろうとしているのも、なんだかなぁ!と思ったりして。

#include "slos.h"
#include "reg.h"
#include "sfr_r825.h"
#define TID_SW_SCAN		1	/**/
#define TID_LED_ON_OFF	2	/**/
#define TID_DEMO		3	/**/
#define FID_DEMO		1	/**/
#define SEMID_LED_ON_OFF	1	/**/
#define FLG_PTN_SW_ON	0x0001	/*待ちフラグパターン*/

void tsk01(void);
void tsk02(void);
void tsk03(void);
void TimerRA_Int(B mode);
void init_timerRA(void);

void uinit(void)
{
	init_clock();		
	init_LED();
	systim_init();
	evtflg_init();
	EVTFLG_ATTR(FID_DEMO, (EVFLG_TA_AND + EVFLG_TA_CLR + EVFLG_TA_TFIFO));
	sem_init();
	SEM_ATTR(SEMID_LED_ON_OFF, 0, SEM_TA_TFIFO);  /*セマフォの初期状態は0とする*/
	init_timerRA();
}

void tsk01( void )
{
	unsigned char old_sw;

	old_sw = p1_7;
	while( 1 )
	{
		tslp_tsk( 50 );
		if( old_sw == 0 && p1_7 == 1 )	/*立ち上がりエッジの検出*/
		{
			sig_sem( SEMID_LED_ON_OFF );
			set_flg( FID_DEMO, FLG_PTN_SW_ON );
		}
		old_sw = p1_7;
	}
}

void tsk02( void )
{
	int i;
	W tim;
	static const int loop_pattern[] =
	{ 1,3,5,2,4,6,3 };

	while( 1 )
	{
		wai_sem( SEMID_LED_ON_OFF );	/*カウンタセマフォとして利用する*/
		tim = get_tim();	/*システムタイマーの値を取得*/
		for( i = loop_pattern[ tim % 7 ]; i > 0; i-- )
		{
			p2_0 = 0;	/*LED点灯*/
			tslp_tsk( 250 );
			p2_0 = 1;	/*LED消灯*/
			tslp_tsk( 250 );
		}
	}
}

void tsk03(void)
{
	W	ercd;
	int count = 0;

	while( 1 )
	{
		ercd = twai_flg( FID_DEMO, FLG_PTN_SW_ON, 500 );
		if( ercd == E_TMOUT )	/*タイムアウトした時*/
		{
			if( ++count >= 60 )	/*その数を数え、60(30秒)を超える時、LEDの点滅を開始する。*/
			{
				count = 60;
				p2_0 ^= 1;	/*LED点滅*/
				p2_1 = p2_0;	/*LED点滅*/
			}
		}
		else
		{
			count = 0;
		}
	}
}

void init_timerRA(void)
{
  /*削除*/
    trapre = 250 - 1;	/* Counts an internal count source */
    tra = 50 - 1;		/* Counts an underflow of the Timer RA prescaler register */ 
  /*削除*/
}

  /*以下、大体同じ*/


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。