#pragma section @@CODE ROM_CODE /****************************************************************************** タスクシステム? なるほど、iTRONにはコンフィギュレータがあるはずだ。 →作りました ctr_mcu_config.rb 参照。 task_config.hが作成されます。 *****************************************************************************/ #include "renge_task_intval.h" #include "renge_task_immediate.h" #include "..\WDT.h" //****************************************************************************** bit renge_flg_interval; bit renge_task_interval_run_force; extern task_info tasks[]; //****************************************************************************** static void renge_task_immed_init(); /****************************************************************************** 初期化。 ・タスクシステムの動的部分の初期化 ・インターバルタイマ *****************************************************************************/ void renge_init(){ renge_task_immed_init(); /* イベントタイマのセットなど 今回はRTCを流用しているのでコメントアウト #define renge_tick 19xxxxxxx [ms] renge_interval_init(); → RTC_init(); */ } /****************************************************************************** システムチックを進める *****************************************************************************/ /* void renge_interval(){ // RTCがやってくれる →__interrupt void int_rtc_int(); } */ /****************************************************************************** コンパイル時に決まっている、インターバル起動のタスク そのうち、逐次起動と混ぜるかもしれない。 強制起動のフラグの件。後で整理 *****************************************************************************/ err renge_task_interval_run(){ task_info *current_task; // インターバル起動 if( renge_flg_interval == 1 ){ renge_flg_interval = 0; for( current_task = tasks; current_task != &tasks[TSK_LAST]; current_task += 1 ){ if( current_task -> dispatch_type == INTERVAL ){ if( current_task -> interval == 0 ){ current_task -> interval = current_task -> task(); }else{ current_task -> interval -= 1; } } } } // ***_TRIG等で強制起動 if( renge_task_interval_run_force ){ renge_task_interval_run_force = 0; // とりあえず、何が何でもフラグ消しちゃうけど... for( current_task = tasks; current_task != &tasks[TSK_LAST]; current_task += 1 ){ current_task -> interval = current_task -> task(); } } return( ERR_SUCCESS ); } /***************************************************************************** ■逐一起動タスク■ ●task_immed を返す関数。 ●システムtick、何らかの割り込み(I2C通信完了など)で スリープから復帰したタイミングで実行されます。 ■返値 ERR_FINISED タスクを削除     それ以外 次のタイミングでまた実行 *****************************************************************************/ #define IMMED_RSV_TASKS_NUM 10 task_immed tasks_immed[ IMMED_RSV_TASKS_NUM ]; // タスクへのポインタの配列 u8 task_immed_index = 0; /************************************** **************************************/ void renge_task_immed_init(){ // tasks_immed[ 0 ] = (void *)0; task_immed_index = 0; } /************************************** **************************************/ err renge_task_immed_add( task_immed new_task ){ u8 temp; if( task_immed_index >= IMMED_RSV_TASKS_NUM ){ // タスクの登録領域が足りなかった while(1); }else{ #if 1 // 同じタスクの多重登録を避ける for( temp = 0; temp < task_immed_index; temp += 1 ){ if( tasks_immed[ temp ] == new_task ){ return( ERR_ERR ); } } #endif tasks_immed[ task_immed_index ] = new_task; tasks_immed[ task_immed_index+1 ] = 0; // 大丈夫? task_immed_index += 1; return( ERR_SUCCESS ); } } /************************************** **************************************/ err renge_task_immed_del( u8 task_id ){ u8 i; for( i = task_id; i < IMMED_RSV_TASKS_NUM; i += 1 ){ tasks_immed[ i ] = tasks_immed[ i+1 ]; } task_immed_index -= 1; return( ERR_SUCCESS ); } /************************************** **************************************/ err renge_task_immed_run(){ u8 task_id = 0; while( tasks_immed[ task_id ] != 0 ){ if( tasks_immed[ task_id ]( (u8*)0 ) == ERR_FINISED ){ renge_task_immed_del( task_id ); // ←が tasks_immed[ id ] を前詰めしてしまうので、 }else{ // 同じid (=元は、次のid) を起動しなくてはならない task_id += 1; } } return( ERR_SUCCESS ); } /****************************************************************************** 単位は ms NOPを回すだけ、指定時間CPUを占有します。 割り込みとか入るとその分遅れます。 少し誤差あります。 *****************************************************************************/ void wait_ms( u8 ms ){ u16 fine; WDT_Restart(); // まだ適当です! while( ms != 0 ){ ms--; fine = 430; while( fine != 0 ){ fine -= 1; } } }