目次

タスク間通信


 USOは、タスク間通信を実現する機能は持ちません。

 タスク間で、情報交換するには、グローバル変数を使います。

 グローバル変数を使う場合は、次の指針で定義するとよいでしょう。



1ビット単位の情報交換

 1ビットで充分な情報は、イベントフラグ、信号などです。  USOは、Cで動作するので、次のように8ビットで表現できる変数の  中に1ビット単位の記憶領域を確保します。 typedef union { struct { unsigned B0:1; unsigned B1:1; unsigned B2:1; unsigned B3:1; unsigned B4:1; unsigned B5:1; unsigned B6:1; unsigned B7:1; } BIT ; unsigned char DR ; } FLAGSP ; FLAGSP xflags ; #define FLAG0 xflags.BIT.B0 #define FLAG1 xflags.BIT.B1 #define AFLAG xflags.BIT.B2 #define BFLAG xflags.BIT.B3 2つのタスクを交互に動かしたい場合は、次のように定義します。 #define OFF 0 #define ON OFF+1 void tsk1_proc(void) { if ( FLAG == OFF ) { /* 何か動作を記述 */ FLAG0 = ON ; } } void tsk2_proc(void) { if ( FLAG == ON ) { /* 何か動作を記述 */ FLAG0 = OFF ; } } フラグをOFFにして、システムコールsta_tskで2つのタスクをREADY  にすれば、タスク1、タスク2の順で交互に動作を繰り返します。 FLAG = OFF ; sta_tsk( TSK_ID1 , TTS_READY ) ; sta_tsk( TSK_ID2 , TTS_READY ) ;  1ビットのフラグを利用して、2個のLEDを交互に点滅する場合は  次のようにタスクを定義します。 #define OFF 0 #define ON OFF+1 void tsk0_proc(void) { if ( ENABLE_LED == ON ) { /* 1秒周期 */ wai_tsk( 100 ); } else { sus_tsk( TSK_ID1 ); sus_tsk( TSK_ID2 ); rsm_tsk( TSK_ID3 ); } } void tsk1_proc(void) { if ( FLAG == OFF ) { LED_LEFT = LED_ON ; LED_RIGHT = LED_OFF ; } } void tsk2_proc(void) { if ( FLAG == ON ) { LED_LEFT = LED_OFF ; LED_RIGHT = LED_ON ; } } void tsk3_proc(void) { LED_LEFT = LED_OFF ; LED_RIGHT = LED_OFF ; slp_tsk(); }

1、2バイトの情報交換->変数

 1、2バイトの情報交換では、グローバル変数を用意して対処します。  1ビットのフラグを利用して、2個のLEDを交互に点滅する場合は  次のようにグローバル変数を定義し、利用します。 #define OFF 0 #define ON OFF+1 unsigned char led_pat[3] = {0x00,0x01,0x02}; #define OFF_PATTERN 0 #define RIGHT_ON_PATTERN 1 #define LEFT_ON_PATTERN 2 void tsk0_proc(void) { if ( ENABLE_LED == ON ) { /* 1秒周期 */ wai_tsk( 100 ); } else { sus_tsk( TSK_ID1 ); sus_tsk( TSK_ID2 ); rsm_tsk( TSK_ID3 ); } } void tsk1_proc(void) { if ( FLAG == OFF ) { LED_BITS = led_pat[RIGHT_ON_PATTERN]; } } void tsk2_proc(void) { if ( FLAG == ON ) { LED_BITS = led_pat[LEFT_ON_PATTERN]; } } void tsk3_proc(void) { LED_BITS = led_pat[OFF_PATTERN]; slp_tsk(); }

3バイト以上の情報交換->配列利用

 他のコンピュータから、コマンドを与えられて動作するような  場合には、コマンドとパラメータが必要になります。  配列を利用して、受信バッファを構成するのが定石です。  コマンドを解釈し、他のタスクに指示を与えるための専用タスク  を用意して、コマンドインタプリタとします。 char sbuf[16] ; char cmd ; char sub_cmd ; void tsk0_proc(void) { /* 受信バッファにデータなければ、そのまま抜ける */ if ( SFLAG == OFF ) return ; /* フラグ処理 */ SFLAG = OFF ; /* Unkownコマンドならば、そのまま抜ける */ if ( is_valid_cmd( *(sbuf+0) ) == NO ) return ; /* branch */ switch ( *(sbuf+0) ) { /* ID設定 */ case 'I' : cmd = *(sbuf+1) ; sub_cmd = *(sbuf+2) ; rsm_tsk( TSK_ID1 ) ; break ; /* SPAN設定 */ case 'S' : cmd = *(sbuf+1) ; sub_cmd = *(sbuf+2) ; rsm_tsk( TSK_ID2 ) ; break ; } } void tsk1_proc(void) { char stype ; char snum ; /* 形式取得 */ stype = cmd ; /* シリアル番号 */ snum = 0 ; if ( '0' <= sub_cmd && sub_cmd <= '9' ) { snum = sub_cmd - '0' ; } if ( 'A' <= sub_cmd && sub_cmd <= 'F' ) { snum = sub_cmd - 'A' + 10 ; } /* EEPROMへ保存 */ store_eeprom( stype , snum ); /* 終了 */ slp_tsk() ; } void tsk2_proc(void) { char snum ; /* 10の位 */ snum = cmd - '0' ; snum *= 10 ; /* 1の位 */ snum += (sub_cmd - '0') ; /* EEPROMへ保存 */ store_eeprom( SPAN_ADDRESS , snum ); /* 終了 */ slp_tsk() ; }
目次

inserted by FC2 system