mt_cont.hファイル

(Mini-c マルチタスク化)

 マルチタスクを実現する為のプログラムで、マルチタスクをスタートさせる プログラム、タスクの切り替えを行うプログラム、タスクを終了させ休眠タスクに 設定をする為のプログラム及び、タスクの初期化、データ交換のためのプログラム が有ります。

void set_task_st(int task_no,int st)
この関数は、”C”ソースファイルの中で  task_init( ) の関数の中でタスクの 初期化の為に使用します。
set_task_st(0,ACTIVE)
set_task_st(1,SLEEP)
この様に記述しますと、”タスク0”が動作し、”タスク1”が休眠状態で、 スタートします。

void sleep_task(int task_no)
 この関数で、タスクを休止状態にします。

void ractive_task(int task_no)
 この関数で、休止状態のタスクを再び動作状態にします。ただし、注意の必要な 点として次の事が有ります。タスクには、スリープとアクティブの2つの状態が有 り、いつでも自由に切り替える事ができます。ただし、自分自信をスリープ状態に 切り替えても、タスク実行時間が終了するまで止まる事が無いため、問題が起こる 可能性が有ります。自分自信をスリープ状態にする為には、関数から抜けるように すれば、その時点でタスクが時間に関係無く停止しスリープ状態になります。この 場合、再びアクティブ状態になった時は関数の最初から実行が始まります。

int  task_cc_read( )
 この関数は、タスクカウンターの値を読み出します。タスクカウンターはタスクが 切り替えられる度に、1ずつカウントアップします。例えば4個のタスクが動作して いると、その中の1個のタスクでタスクカウンターの値を読み出しを繰り返している と、その値は”0.5ms*4=2ms”おきに、その値が”4”ずつアップします。 この事を利用すれば、精度はかなり低い事を我慢すればタイマーとして使用できます。

int  commu_write(int buff_no,int data)  1=ok 0=no
 この関数は、タスク間のデータの受け渡しを行うバッファーにデータを書き込み ます。戻り値が”1”であれば、データの書き込みが成功しています。戻り値が ”0”の場合はバッファーが使用中の為、データの書き込みに失敗した事を意味し ます。データの書き込みを行いますと、フラグが”1”にセットされます。

int  commu_flag(int buff_no)	1=有 0=無
 この関数は、データを受け取る側が、バッファーにデータが入っているかチェック を行うためのものです。”1”であればデータが有り、”0”ならばデータは無しで す。

int  commu_read(int buff_no)
 この関数は、実際にバッファーよりデータを読み出します。この関数を実行する前 に必ずフラグをチェックを行い、データがバッファーに入っている事を確認して下さ い。なお、データの読み出しを行いますと、フラグが”0”にリセットされます。


MT_INIT
 このプログラムは、システムエリアを(タスク間通信バッファー等)を初期化し、 各タスクのスタックエリアを初期化します。

相対アドレス内容
 0各タスクスタートアドレス
−3下記 TASK_STOP アドレス
−5各タスクスタートアドレス

各スタックエリアは最初に上記の表のように、セットされ”スタックポインター バッファー”は、”−5”になり各タスクがスタートします。各タスクが関数を 抜け出た場合は、−3の”TASK_STOP”プログラムが実行され、もう一 度この状態に戻されてから、タスクが休止状態になります。

TASK_START
 このプログラムにより、マルチタスクがスタートします。実装されているタスク のナンバーの最も小さいものを撰び、スタックポインターバッファーの値をスタック ポインターにセットし、”RET”命令でタスクをスタートします。

TASK_STOP
 このプログラムは、タスクが関数を抜け出して終了したときの処理を行います。 スタックエリアを初期かし最初と同じ内容にしてから、タスクを休止状態にして から、次のタスクに切り替えます。

TASK_CHANG
 このプログラムは、タスクの切り替えを行っています。CTCの”0”のタイ マー割り込みを使用し、500μsごとに実行中のスタックポインターの値をそ のバッファーにセーブし、次のタスクのバッファーの値をスタックポインターに セットし”RET”命令で次のタスクをスタートします。

目次に戻る



/*==============================================================*/
/*								*/
/*		マルチタスクコントロール			*/
/*		(1タスク 0.5ms)				*/
/*		mt_cont.h	Vr1.00				*/
/*								*/
/*	void set_task_st(int task_no,int st)			*/
/*	  set_task_st(0,ACTIVE),set_task_st(1,SLEEP)		*/
/*	void sleep_task(int task_no)				*/
/*	void ractive_task(int task_no)				*/
/*	int  task_cc_read( )					*/
/*	int  commu_write(int buff_no,int data)  1=ok 0=no	*/
/*	int  commu_flag(int buff_no)	1=有 0=無		*/
/*	int  commu_read(int buff_no)				*/
/*								*/
/*==============================================================*/

#define		ACTIVE	0x01		//活性タスク
#define		SLEEP	0x03		//休眠タスク


void set_task_st(int task_no,int st)
{
#asm
		LD	HL,2
		ADD	HL,SP
		LD	A,(HL)		;タスクステータス
		LD	HL,4
		ADD	HL,SP
		LD	C,(HL)		;タスクNo
		LD	B,0
		LD	HL,TASK_ST_0
		ADD	HL,BC
		LD	(HL),A
#endasm
}

void sleep_task(int task_no)
{
#asm
		LD	HL,2
		ADD	HL,SP
		LD	C,(HL)			;タスクNo
		LD	B,0
		LD	HL,TASK_ST_0
		ADD	HL,BC
		LD	A,00000011B		;タスク休眠
		LD	(HL),A
#endasm
}

void ractive_task(int task_no)
{
#asm
		LD	HL,2
		ADD	HL,SP
		LD	C,(HL)			;タスクNo
		LD	B,0
		LD	HL,TASK_ST_0
		ADD	HL,BC
		LD	A,00000001B
		LD	(HL),A			;タスク再スタート
#endasm
}

int  task_cc_read( )
{
#asm
		LD	HL,(TASK_CC)		;タスクサイクルカウンターリード
#endasm
}

int  commu_write(int buff_no,int data)
{
#asm
		LD	HL,4			;フラグチェック
		ADD	HL,SP
		LD	C,(HL)
		LD	B,0
		LD	HL,COMMU_FLAG_0
		ADD	HL,BC
		LD	A,(HL)
		OR	A
		JR	NZ,COMMU_WRITE_1

		LD	HL,2			;データ書き込み
		ADD	HL,SP
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		LD	A,C
		ADD	A,C
		LD	C,A
		LD	HL,COMMU_DATA_0
		ADD	HL,BC
		LD	(HL),E
		INC	HL
		LD	(HL),D

		LD	HL,4			;フラグ書換
		ADD	HL,SP
		LD	C,(HL)
		LD	HL,COMMU_FLAG_0
		ADD	HL,BC
		LD	A,1
		LD	(HL),A

		LD	L,1			;戻り値セット
		JR	COMMU_WRITE_2
COMMU_WRITE_1:	LD	L,0
COMMU_WRITE_2:	LD	H,0

#endasm
}

int  commu_flag(int buff_no)
{
#asm
		LD	HL,2			;フラグチェック
		ADD	HL,SP
		LD	C,(HL)
		LD	B,0
		LD	HL,COMMU_FLAG_0
		ADD	HL,BC
		LD	L,(HL)
		LD	H,0
#endasm
}

int  commu_read(int buff_no)
{
#asm
		LD	HL,2			;データ読みだし
		ADD	HL,SP
		LD	A,(HL)
		LD	C,A
		ADD	A,C
		LD	C,A
		LD	B,0
		LD	HL,COMMU_DATA_0
		ADD	HL,BC
		LD	E,(HL)
		INC	HL
		LD	D,(HL)

		LD	HL,2			;フラグ書換
		ADD	HL,SP
		LD	C,(HL)
		LD	HL,COMMU_FLAG_0
		ADD	HL,BC
		LD	(HL),B

		LD	L,E			;戻り値セット
		LD	H,D
#endasm
}

/*=============================================================*/

#asm

;***************************************************************
;
;	タスクシステム初期化
;
;***************************************************************

MT_INIT:	LD	A,7
		LD	(TASK_NO),A
		LD	HL,0
		LD	(TASK_CC),HL
		LD	A,0
		LD	(TASK_ST_0),A
		LD	(TASK_ST_1),A
		LD	(TASK_ST_2),A
		LD	(TASK_ST_3),A
		LD	(TASK_ST_4),A
		LD	(TASK_ST_5),A
		LD	(TASK_ST_6),A
		LD	(TASK_ST_7),A
		LD	(COMMU_FLAG_0),A
		LD	(COMMU_FLAG_1),A
		LD	(COMMU_FLAG_2),A
		LD	(COMMU_FLAG_3),A
		LD	(COMMU_FLAG_4),A
		LD	(COMMU_FLAG_5),A
		LD	(COMMU_FLAG_6),A
		LD	(COMMU_FLAG_7),A

;======================================================
		IF	TASK_0

		LD	HL,__TASK_0
		LD	(STAK_START_0 - 1),HL
		LD	(STAK_START_0 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_0 - 3),HL
		LD	HL,STAK_START_0
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_0),HL

		ENDIF
;======================================================
		IF	TASK_1

		LD	HL,__TASK_1
		LD	(STAK_START_1 - 1),HL
		LD	(STAK_START_1 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_1 - 3),HL
		LD	HL,STAK_START_1
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_1),HL

		ENDIF
;======================================================
		IF	TASK_2

		LD	HL,__TASK_2
		LD	(STAK_START_2 - 1),HL
		LD	(STAK_START_2 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_2 - 3),HL
		LD	HL,STAK_START_2
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_2),HL

		ENDIF
;======================================================
		IF	TASK_3

		LD	HL,__TASK_3
		LD	(STAK_START_3 - 1),HL
		LD	(STAK_START_3 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_3 - 3),HL
		LD	HL,STAK_START_3
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_3),HL

		ENDIF
;======================================================
		IF	TASK_4

		LD	HL,__TASK_4
		LD	(STAK_START_4 - 1),HL
		LD	(STAK_START_4 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_4 - 3),HL
		LD	HL,STAK_START_4
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_4),HL

		ENDIF
;======================================================
		IF	TASK_5

		LD	HL,__TASK_5
		LD	(STAK_START_5 - 1),HL
		LD	(STAK_START_5 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_5 - 3),HL
		LD	HL,STAK_START_5
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_5),HL

		ENDIF
;======================================================
		IF	TASK_6

		LD	HL,__TASK_6
		LD	(STAK_START_6 - 1),HL
		LD	(STAK_START_6 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_6 - 3),HL
		LD	HL,STAK_START_6
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_6),HL

		ENDIF
;======================================================
		IF	TASK_7

		LD	HL,__TASK_7
		LD	(STAK_START_7 - 1),HL
		LD	(STAK_START_7 - 5),HL
		LD	HL,TASK_STOP
		LD	(STAK_START_7 - 3),HL
		LD	HL,STAK_START_7
		LD	BC,13
		SCF
		CCF
		SBC	HL,BC
		LD	(STAK_BUFF_7),HL

		ENDIF
;======================================================

		IM	2			;割り込みモード設定
		LD	A,00000001B		;割り込み優先順位設定
		OUT	(IO_INT_CT),A		;SIO > CTC > PIO
		LD	A,HIGH CTC_VECTER	;割り込みベクター設定
		LD	I,A			;上位
		LD	A,LOW CTC_VECTER
		AND	11111000B
		OUT	(IO_CTC_C0),A		;CTCベクター設定

		RET


;***************************************************************
;
;	タスクスタート
;
;***************************************************************

TASK_START:
		LD	A,(TASK_NO)		;TASK_ST_Y チェック
		INC	A
		BIT	3,A
		JR	Z,TASK_START_1
		LD	A,0
TASK_START_1:	LD	(TASK_NO),A
		LD	C,A
		LD	B,0
		LD	HL,TASK_ST_0
		ADD	HL,BC
		LD	A,(HL)
		BIT	0,A
		JR	Z,TASK_START
		BIT	1,A
		JR	NZ,TASK_START

		LD	A,(TASK_NO)		;STAK_BUFF_Y -> SP
		LD	B,A
		ADD	A,B
		LD	C,A
		LD	B,0
		LD	HL,STAK_BUFF_0
		ADD	HL,BC
		LD	B,(HL)
		INC	HL
		LD	H,(HL)
		LD	L,B
		LD	SP,HL			;スタックポインタ変更
;
		LD	A,10010101B		;タイマーセット
		OUT	(IO_CTC_C0),A		;7.3728MHz = 0.5ms
		LD	A,197
		OUT	(IO_CTC_C0),A		;タイマースタート
;
		POP	HL
		POP	DE
		POP	BC
		POP	AF

		EI
		RET


;***************************************************************
;
;	タスクストップ
;
;***************************************************************

TASK_STOP:
		DI
		LD	A,00000011B		;タイマー停止
		OUT	(IO_CTC_C0),A

		LD	HL,0			;タスクストップアドレスの設定
		ADD	HL,SP
		DEC	HL
		LD	A,HIGH TASK_STOP
		LD	(HL),A
		DEC	HL
		LD	A,LOW TASK_STOP
		LD	(HL),A
		INC	HL
		INC	HL

		LD	A,(HL)			;タスクアドレスをコピー
		DEC	HL
		DEC	HL
		DEC	HL
		DEC	HL
		LD	(HL),A
		LD	HL,1
		ADD	HL,SP
		LD	A,(HL)
		DEC	HL
		DEC	HL
		DEC	HL
		DEC	HL
		LD	(HL),A

		LD	BC,9			;タスクスタックバッファー設定
		SCF
		CCF
		SBC	HL,BC
		LD	SP,HL			;スタックポインタを復帰
		EI
		LD	(STAK_BUFF),SP
		LD	HL,STAK_BUFF_0
		LD	A,(TASK_NO)
		LD	C,A
		ADD	A,C
		LD	C,A
		LD	B,0
		ADD	HL,BC
		LD	A,(STAK_BUFF)
		LD	(HL),A
		LD	A,(STAK_BUFF + 1)
		INC	HL
		LD	(HL),A

		LD	A,(TASK_NO)		;休眠タスク設定
		LD	C,A
		LD	B,0
		LD	HL,TASK_ST_0
		ADD	HL,BC
		LD	A,00000011B
		LD	(HL),A

		LD	HL,(TASK_CC)		;サイクルカウンター +1
		INC	HL
		LD	(TASK_CC),HL

TASK_STOP_1:	LD	A,(TASK_NO)		;次タスクチェック
		INC	A
		BIT	3,A
		JR	Z,TASK_STOP_2
		LD	A,0
TASK_STOP_2:	LD	(TASK_NO),A
		LD	C,A
		LD	B,0
		LD	HL,TASK_ST_0
		ADD	HL,BC
		LD	A,(HL)
		BIT	0,A
		JR	Z,TASK_STOP_1
		BIT	1,A
		JR	NZ,TASK_STOP_1

		LD	A,(TASK_NO)		;STAK_BUFF_Y -> SP
		LD	B,A
		ADD	A,B
		LD	C,A
		LD	B,0
		LD	HL,STAK_BUFF_0
		ADD	HL,BC
		LD	B,(HL)
		INC	HL
		LD	H,(HL)
		LD	L,B
		LD	SP,HL			;スタックポインター変更

		LD	A,10010101B		;タイマーセット
		OUT	(IO_CTC_C0),A		;7.3728MHz = 0.5ms
		LD	A,197
		OUT	(IO_CTC_C0),A		;タイマースタート

		POP	HL
		POP	DE
		POP	BC
		POP	AF

		EI
		RET



;***************************************************************
;
;	タスクチェンジ(タイマー"0"割り込み処理)
;
;***************************************************************

TASK_CHANG:
		PUSH	AF
		PUSH	BC
		PUSH	DE
		PUSH	HL

		LD	A,00000011B		;タイマー停止
		OUT	(IO_CTC_C0),A

		LD	(STAK_BUFF),SP		;SP -> STAK_BUFF_X
		EI
		LD	A,(TASK_NO)
		LD	B,A
		ADD	A,B
		LD	B,0
		LD	C,A
		LD	HL,STAK_BUFF_0
		ADD	HL,BC
		LD	A,(STAK_BUFF)
		LD	(HL),A
		INC	HL
		LD	A,(STAK_BUFF + 1)
		LD	(HL),A			;タスクスタックポインタ退避

		LD	HL,(TASK_CC)		;サイクルカウンター +1
		INC	HL
		LD	(TASK_CC),HL

TASK_CHANG_1:	LD	A,(TASK_NO)		;次タスクチェック
		INC	A
		BIT	3,A
		JR	Z,TASK_CHANG_2
		LD	A,0
TASK_CHANG_2:	LD	(TASK_NO),A
		LD	C,A
		LD	B,0
		LD	HL,TASK_ST_0
		ADD	HL,BC
		LD	A,(HL)
		BIT	0,A
		JR	Z,TASK_CHANG_1
		BIT	1,A
		JR	NZ,TASK_CHANG_1

		LD	A,(TASK_NO)		;STAK_BUFF_Y -> SP
		LD	B,A
		ADD	A,B
		LD	C,A
		LD	B,0
		LD	HL,STAK_BUFF_0
		ADD	HL,BC
		LD	B,(HL)
		INC	HL
		LD	H,(HL)
		LD	L,B
		LD	SP,HL			;スタックポインター変更

		LD	A,10010101B		;タイマーセット
		OUT	(IO_CTC_C0),A		;7.3728MHz = 0.5ms
		LD	A,197
		OUT	(IO_CTC_C0),A		;タイマースタート

		POP	HL
		POP	DE
		POP	BC
		POP	AF

		EI
		RETI

#endasm


目次に戻る