mt_cont.hファイル
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 | 各タスクスタートアドレス |
|---|
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