mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-10-31 13:51:10 -04:00
313 lines
8.6 KiB
C
313 lines
8.6 KiB
C
#ifndef _WIN32
|
||
|
||
#pragma section @@CODE ROM_CODE
|
||
#pragma nop
|
||
#pragma ei
|
||
#pragma di
|
||
#pragma sfr
|
||
|
||
#endif
|
||
|
||
|
||
#ifdef _WIN32
|
||
typedef unsigned char bit;
|
||
typedef unsigned char u8;
|
||
#endif
|
||
|
||
/******************************************************************************
|
||
タスクシステム?
|
||
なるほど、iTRONにはコンフィギュレータがあるはずだ。
|
||
→作りました
|
||
ctr_mcu_config.rb 参照。 task_config.hが作成されます。
|
||
*****************************************************************************/
|
||
#include "renge.h"
|
||
#include "renge_task_intval.h"
|
||
#include "renge_task_immediate.h"
|
||
#include "..\WDT.h"
|
||
#include "..\config.h"
|
||
#include "..\user_define.h"
|
||
|
||
#ifdef _WIN32
|
||
#include "../sim/simOnWin.h"
|
||
#endif
|
||
//#define _renge_test_
|
||
|
||
#define true 1
|
||
#define false 0
|
||
|
||
//******************************************************************************
|
||
u8 renge_flg_interval;
|
||
bit renge_task_interval_run_force;
|
||
bit renge_task_immediate_not_empty;
|
||
|
||
|
||
#include "..\bsr_system.h"
|
||
extern system_status_ system_status;
|
||
|
||
|
||
//******************************************************************************
|
||
static void renge_task_immed_init();
|
||
static void renge_task_immed_del();
|
||
|
||
|
||
|
||
//******************************************************************************
|
||
task_status_immed ( *tasks_immed[ TASK_IMMED_RUN_LIST_MAX ] )();
|
||
extern void DI_wt_chk();
|
||
|
||
|
||
|
||
/******************************************************************************
|
||
初期化
|
||
・タスクシステムの動的部分の初期化
|
||
・インターバルタイマ
|
||
*****************************************************************************/
|
||
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();
|
||
}
|
||
*/
|
||
|
||
|
||
|
||
/******************************************************************************
|
||
コンパイル時に決まっている、インターバル起動のタスク
|
||
そのうち、逐次起動と混ぜるかもしれない。
|
||
*****************************************************************************/
|
||
__callt err renge_task_interval_run(){
|
||
u8 i;
|
||
|
||
// インターバル起動
|
||
DI_wt_chk();
|
||
if(( renge_flg_interval != 0 ) ||
|
||
( renge_task_interval_run_force )) /// 統合したかったな…
|
||
{
|
||
renge_task_interval_run_force = false; // 今から起動するタスク、割り込むタスクでフラグが立つかもなので
|
||
if( renge_flg_interval != 0 )
|
||
{
|
||
renge_flg_interval --;
|
||
WDT_Restart( );
|
||
}
|
||
EI();
|
||
for( i = 0; i != TSK_LAST; i ++ )
|
||
{
|
||
tasks[ i ]();
|
||
// 逐次起動タスクがあったら間に挟む
|
||
renge_task_immed_run();
|
||
}
|
||
}
|
||
EI();
|
||
return( ERR_SUCCESS );
|
||
}
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
■逐一起動タスク■
|
||
|
||
●task_immed を返す関数。
|
||
●システムtick、何らかの割り込み(I2C通信完了など)で
|
||
スリープから復帰したタイミングで実行されます。
|
||
|
||
■返値 ERR_FINISED タスクを削除
|
||
それ以外 次のタイミングでまた実行
|
||
|
||
*****************************************************************************/
|
||
|
||
|
||
/**************************************
|
||
**************************************/
|
||
void renge_task_immed_init(){
|
||
u8 i;
|
||
|
||
for( i = 0; i < TASK_IMMED_RUN_LIST_MAX; i++ ){
|
||
tasks_immed[ i ] = TSK_IMM_EMPTY_;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**************************************
|
||
逐次実行タスクの登録
|
||
割り込み禁止 36us →
|
||
**************************************/
|
||
__callt err renge_task_immed_add( task_status_immed (*new_task)() ){
|
||
u8 i;
|
||
|
||
// リストの空きの先頭に登録
|
||
// 削除したばかりのタスクは、削除マーク(TSK_IMM_DELETED_)となり、空きとは明示的に区別される
|
||
// 重複登録を避ける
|
||
for( i = 0; i < TASK_IMMED_RUN_LIST_MAX; i ++ )
|
||
{
|
||
DI_wt_chk();
|
||
if( tasks_immed[ i ] == TSK_IMM_EMPTY_ )
|
||
{
|
||
// 空きを見つけた
|
||
tasks_immed[ i ] = new_task;
|
||
EI();
|
||
return( ERR_SUCCESS );
|
||
}
|
||
else
|
||
{
|
||
// 重複登録チェック
|
||
/// 歯抜けになってない、前詰めされてる前提
|
||
if( tasks_immed[ i ] == new_task )
|
||
{
|
||
// 重複登録はしない
|
||
EI();
|
||
return( ERR_ERR );
|
||
}
|
||
}
|
||
EI();
|
||
}
|
||
// タスク登録しすぎ(無いはず
|
||
return( ERR_ERR );
|
||
}
|
||
|
||
|
||
|
||
/**************************************
|
||
逐次実行タスクの実行
|
||
**************************************/
|
||
__callt err renge_task_immed_run(){
|
||
u8 list_id;
|
||
|
||
// while( tasks_immed[ 0 ] != TSK_IMM_EMPTY_ )
|
||
if( tasks_immed[ 0 ] != TSK_IMM_EMPTY_ )
|
||
{
|
||
DI_wt_chk();
|
||
for( list_id = 0; list_id < TASK_IMMED_RUN_LIST_MAX; list_id ++ ){
|
||
if( tasks_immed[ list_id ] == TSK_IMM_EMPTY_ ){
|
||
// リスト完了
|
||
EI();
|
||
break;
|
||
}
|
||
#ifdef _renge_test_
|
||
else if( tasks_immed[ list_id ] == TSK_IMM_DELETED_ )
|
||
{
|
||
EI();
|
||
NOP();
|
||
// タスク管理の不備
|
||
// 存在しないタスクを実行しようとした
|
||
// タスクの削除後の処理がまずい
|
||
// 予期しないタイミングで immed_run が呼ばれた
|
||
}
|
||
#endif
|
||
else
|
||
{
|
||
u8 rv;
|
||
|
||
EI();
|
||
rv = tasks_immed[ list_id ](); // タスク実行
|
||
if( rv == ERR_SUCCESS )
|
||
{
|
||
tasks_immed[ list_id ] = TSK_IMM_DELETED_;
|
||
}
|
||
// きわどいタイミングで同じタスクの登録があると困るのでDI状態でかえって来る事がある
|
||
}
|
||
DI_wt_chk();
|
||
}
|
||
// リスト上のタスクを一通り実行した
|
||
|
||
// タスク削除 //
|
||
{
|
||
u8 i = 0; // リストの並べ替え先
|
||
u8 j = 1;
|
||
|
||
// 必ず i < j、j < TASK_IMMED_RUN_LIST_MAX (でないとタスクあふれ)
|
||
while( 1 )
|
||
{
|
||
if( tasks_immed[ i ] == TSK_IMM_EMPTY_ )
|
||
{
|
||
// 前詰め完了 && リスト空っぽ
|
||
// break;
|
||
goto imm_list_sort_fin;
|
||
}
|
||
else if( tasks_immed[ i ] == TSK_IMM_DELETED_ )
|
||
{
|
||
for( ; j < TASK_IMMED_RUN_LIST_MAX; j++ )
|
||
{
|
||
if( tasks_immed[ j ] == TSK_IMM_DELETED_ )
|
||
{
|
||
// 隣(?)も削除対象だった
|
||
// next j
|
||
}
|
||
else
|
||
{
|
||
DI_wt_chk();
|
||
if( tasks_immed[ j ] == TSK_IMM_EMPTY_ )
|
||
{
|
||
do{
|
||
j --;
|
||
tasks_immed[ j ] = TSK_IMM_EMPTY_;
|
||
// リスト前詰め完了
|
||
}while( i < j );
|
||
EI();
|
||
goto imm_list_sort_fin;
|
||
}
|
||
else
|
||
{
|
||
// 前詰めすべきタスクを見つけた
|
||
tasks_immed[ i ] = tasks_immed[ j ];
|
||
tasks_immed[ j ] = TSK_IMM_DELETED_;
|
||
i ++;
|
||
EI();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// このタスク、滞留
|
||
}
|
||
i ++;
|
||
}
|
||
}
|
||
}
|
||
|
||
imm_list_sort_fin:
|
||
// ここまでで完全に前詰めされている
|
||
#ifdef _renge_test_
|
||
/// ほんと?
|
||
{
|
||
u8 a,b;
|
||
|
||
a = 0;
|
||
for( b = 0 ; b < TASK_IMMED_RUN_LIST_MAX; b++ )
|
||
{
|
||
if( tasks_immed[ b ] == TSK_IMM_EMPTY_ )
|
||
{
|
||
a = 1;
|
||
}
|
||
else
|
||
{
|
||
if( a != 0 )
|
||
{
|
||
NOP(); // EMPTYより後ろにタスクやdeletedが有る
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#else
|
||
NOP(); // なんか無いとリンカが怒る
|
||
#endif
|
||
// }
|
||
return( ERR_SUCCESS );
|
||
}
|