逐次実行タスクの登録/削除を改良

登録順を守る


git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@67 013db118-44a6-b54f-8bf7-843cb86687b1
This commit is contained in:
fujita_ryohei 2009-12-24 05:59:49 +00:00
parent e155ddaf0c
commit bbac8f6f0f
5 changed files with 136 additions and 171 deletions

View File

@ -25,7 +25,7 @@ bit renge_task_interval_run_force;
u8 system_time; u8 system_time;
extern const task_info tasks[];
#include "..\bsr_system.h" #include "..\bsr_system.h"
extern system_status_ system_status; extern system_status_ system_status;
@ -38,8 +38,13 @@ static void renge_task_immed_del();
//******************************************************************************
task_status_immed ( *tasks_immed[ TASK_IMMED_RUN_LIST_MAX ] )();
/****************************************************************************** /******************************************************************************
*****************************************************************************/ *****************************************************************************/
@ -72,16 +77,14 @@ void renge_interval(){
*****************************************************************************/ *****************************************************************************/
err renge_task_interval_run(){ err renge_task_interval_run(){
task_info *current_task; u8 i;
// インターバル起動 // インターバル起動
if( renge_flg_interval == 1 ){ if( renge_flg_interval == 1 ){
renge_flg_interval = 0; renge_flg_interval = 0;
for( current_task = &tasks[0]; for( i = 0; i != TSK_LAST; i += 1 )
current_task != &tasks[TSK_LAST];
current_task += 1 )
{ {
current_task -> task(); tasks[ i ]();
} }
} }
return( ERR_SUCCESS ); return( ERR_SUCCESS );
@ -100,174 +103,146 @@ err renge_task_interval_run(){
         
*****************************************************************************/ *****************************************************************************/
#define IMMED_RSV_TASKS_NUM 10
task_immed tasks_immed[ IMMED_RSV_TASKS_NUM ]; // タスクへのポインタの配列
u8 task_immed_index = 0;
/************************************** /**************************************
**************************************/ **************************************/
void renge_task_immed_init(){ void renge_task_immed_init(){
/*
u8 i;
for( i = 0; i < IMMED_RSV_TASKS_NUM; i++ ){
tasks_immed[ i ] = (void *)0;
}
task_immed_index = 0;
*/
}
/**************************************
immedの否定...
36us
**************************************/
err renge_task_immed_add( task_immed new_task ){
u8 i; u8 i;
u8 place;
// 末尾の連続した空き領域の先頭でかつ、 for( i = 0; i < TASK_IMMED_RUN_LIST_MAX; i++ ){
// 重複登録を避ける tasks_immed[ i ] = TSK_IMM_EMPTY_;
for( i = place = 0; i < IMMED_RSV_TASKS_NUM; i += 1 ) }
{ }
if( tasks_immed[ i ] != ( void * )0 )
{
place = i+1; // 最近見つけた、タスクリストの最後尾
}
if( tasks_immed[ i ] == new_task ) // 重複登録
{
// while(1){
NOP(); // アサートで止めたい
// }
return( ERR_ERR );
}
}
if( place > IMMED_RSV_TASKS_NUM )
{ // タスク登録しすぎ(無いはず
// while(1){ /**************************************
NOP(); // アサートで止めたい
// 36us
return( ERR_ERR ); **************************************/
} err renge_task_immed_add( task_status* new_task ){
else u8 i;
{
DI(); // リストの空きの先頭に登録
DBG_LED_WIFI_2_on; // 削除したばかりのタスクは、削除マークとなり、空きとは明示的に区別される
// もたもたしているうちに割り込み等から割り込まれるのを考慮 // 重複登録を避ける
// 滅多にないはずだが for( i = 0; i < TASK_IMMED_RUN_LIST_MAX; i += 1 )
for( ; place < IMMED_RSV_TASKS_NUM; place += 1 ) {
{ if( tasks_immed[ i ] != TSK_IMM_EMPTY_ )
if( tasks_immed[ place ] == ( void * )0 ) {
{ // 空きではなかった
tasks_immed[ place ] = new_task; if( tasks_immed[ i ] == new_task )
DBG_LED_WIFI_2_off; {
EI(); // 重複登録はしない
return( ERR_SUCCESS ); NOP();
} return( ERR_ERR );
} }
// 割り込まれてタスク登録できなくなった }
DBG_LED_WIFI_2_off; else
EI(); {
return( ERR_ERR ); // 空きを見つけた
} DI();
DBG_LED_WIFI_2_on;
// もたもたしているうちに割り込み等から割り込まれるのを考慮
// 滅多にないはずだが
for( ; i < TASK_IMMED_RUN_LIST_MAX; i += 1 )
{
if( tasks_immed[ i ] == TSK_IMM_EMPTY_ )
{
tasks_immed[ i ] = new_task;
DBG_LED_WIFI_2_off;
EI();
return( ERR_SUCCESS );
}
}
// 割り込まれてタスク登録できなくなった
DBG_LED_WIFI_2_off;
EI();
return( ERR_ERR );
}
}
// タスク登録しすぎ(無いはず
NOP(); // デバッガで捕まえるため
return( ERR_ERR );
} }
/************************************** /**************************************
**************************************/ **************************************/
err renge_task_immed_run(){ err renge_task_immed_run(){
u8 task_id; u8 list_id;
u8 last_task; u8 last_task_id;
do{ do{
last_task = 0xFF; last_task_id = 0xFF;
for( task_id = 0; task_id < IMMED_RSV_TASKS_NUM; task_id += 1 ){ for( list_id = 0; list_id < TASK_IMMED_RUN_LIST_MAX; list_id += 1 ){
if( tasks_immed[ task_id ] != 0 ){ if( tasks_immed[ list_id ] != TSK_IMM_EMPTY_ ){
if( tasks_immed[ task_id ]() == ERR_FINISED ){ if( tasks_immed[ list_id ] == TSK_IMM_DELETED_ )
tasks_immed[ task_id ] = (void*)0; {
last_task = task_id; NOP();
// タスク管理の不備
// 存在しないタスクを実行しようとした
// タスクの削除後の処理がまずい
// 予期しないタイミングで immed_run が呼ばれた
}
else
{
if( tasks_immed[ list_id ]() == ERR_SUCCESS )
{
tasks_immed[ list_id ] = TSK_IMM_DELETED_;
}
last_task_id = list_id;
} }
} }
} }
// タスク削除 // タスク削除
{ {
if( last_task != 0xFF ) if( last_task_id != 0xFF )
{ {
u8 i,j; u8 i,j;
// リスト前詰め // リスト前詰め
i = 0; i = 0; // 前詰め後リストの最後尾
j = 1; j = 0; // リストの後ろの方のタスクを探す
for( ; j < IMMED_RSV_TASKS_NUM; j++)
for( ; j < TASK_IMMED_RUN_LIST_MAX; j++)
// for( ; j <= last_task_id; j++) // 間で割り込まれたときに困る
{ {
DI(); DI();
DBG_LED_WIFI_2_on; DBG_LED_WIFI_2_on;
if( tasks_immed[ i ] == (void *)0 ) if( tasks_immed[ i ] == TSK_IMM_DELETED_ )
{ {
if( tasks_immed[ j ] != (void *)0 ) tasks_immed[ i ] = TSK_IMM_EMPTY_;
}
if( tasks_immed[ i ] == TSK_IMM_EMPTY_ )
{
// 前詰めできるスペースを見つけた
if(( tasks_immed[ j ] != TSK_IMM_EMPTY_ )
&& ( tasks_immed[ j ] != TSK_IMM_DELETED_ ))
{ {
// 探索隊が前詰めすべきタスクを見つけた
tasks_immed[ i ] = tasks_immed[ j ]; tasks_immed[ i ] = tasks_immed[ j ];
tasks_immed[ j ] = (void *)0; tasks_immed[ j ] = TSK_IMM_EMPTY_;
i += 1; i += 1;
} }
} }
else else
{ {
// 実行すべきタスクが滞留することになった
i += 1; i += 1;
} }
DBG_LED_WIFI_2_off; DBG_LED_WIFI_2_off;
EI(); EI();
if( last_task < i )
{
break;
}
} }
} }
} }
} }
while( last_task != 0xFF ); // タスクが残っていたら再実行 while( last_task_id != 0xFF ); // タスクが残っていたら再実行
#if 0
for( task_id = 0; task_id < IMMED_RSV_TASKS_NUM; task_id += 1 ){
if( tasks_immed[ task_id ] == 0 ){
break;
}
if( tasks_immed[ task_id ]() == ERR_FINISED ){
DI();
renge_task_immed_del( task_id );
EI();
}
}
// 整合性チェック
{
u8 j;
u8 k = 0;
for( j = 0; j < ( IMMED_RSV_TASKS_NUM -1); j += 1 ){
if( tasks_immed[ j ] != 0 ){
k += 1;
}
}
if( k != task_immed_index ){
while(1){
NOP();
}
}
}
#endif
return( ERR_SUCCESS ); return( ERR_SUCCESS );
} }

View File

@ -20,8 +20,6 @@ err renge_task_immed_add( task_immed );
void wait_ms( u8 ); void wait_ms( u8 );
u8 renge_set_jump( u8 tsk_id );
//****************************************************************************** //******************************************************************************

View File

@ -24,38 +24,12 @@ typedef unsigned char err;
//*/ //*/
// ***************************************************************************** // ************************************
#define SYS_INTERVAL_TICK 1.953 #define SYS_INTERVAL_TICK 1.953
//******************************************************************************
typedef u8 task_rv;
typedef task_rv renge_task; // 気分の問題
typedef u8 task_interval;
typedef task_interval ( *p_task )(); // p_taskという、task_interval型の関数へのポインタ
typedef enum{
INTERVAL,
I2CM_END,
I2C_M_FREE
}dispatch_type;
typedef struct{
p_task task;
}task_info;
/**************************************
*************************************/
typedef u8 task_status_immed;
typedef task_status_immed (*task_immed)();
// ************************************
typedef enum{ typedef enum{
ERR_SUCCESS = 0, ERR_SUCCESS = 0,
ERR_ERR ERR_ERR
@ -67,4 +41,19 @@ typedef enum{
ERR_CONTINUE ERR_CONTINUE
}IMMED_TASK_ERR; }IMMED_TASK_ERR;
/**************************************
*************************************/
typedef void task_status;
/**************************************
*************************************/
typedef IMMED_TASK_ERR task_status_immed;
#endif #endif

View File

@ -1,20 +1,24 @@
#ifndef __tasks__ #ifndef __tasks__
#define __tasks__ #define __tasks__
#include "renge_defs.h" #include "renge_defs.h"
// *************************************
#define TASK_IMMED_RUN_LIST_MAX 8
/***************************************************************************** extern task_status_immed do_command( );
*****************************************************************************/
extern task_status_immed ntr_pmic_comm(); extern task_status_immed ntr_pmic_comm();
extern task_status_immed tsk_cbk_accero();
extern task_status_immed do_command();
extern task_status_immed acc_read(); extern task_status_immed acc_read();
extern task_status_immed acc_write(); extern task_status_immed acc_write();
//extern task_status_immed acc_hosu_set();
// *************************************
#define TSK_IMM_EMPTY_ ( void * )( 0x0000 )
#define TSK_IMM_DELETED_ ( void * )( 0x0001 )
#endif #endif

View File

@ -6,7 +6,7 @@
#include "renge_defs.h" #include "renge_defs.h"
enum { enum {
TSK_SW, TSK_ADC, TSK_BATT, TSK_LED_POW, TSK_LED_WIFI, TSK_LED_CAM, TSK_MISC_STAT, TSK_DEBUG, TSK_DEBUG2, TSK_SYS, TSK_LAST TSK_SW, TSK_ADC, TSK_BATT, TSK_LED_POW, TSK_LED_WIFI, TSK_LED_CAM, TSK_MISC_STAT, TSK_DEBUG, TSK_DEBUG2, TSK_SYS, TSK_LAST
}; };
extern void tsk_sw(); extern void tsk_sw();
@ -20,7 +20,7 @@ extern void tsk_debug();
extern void tsk_debug2(); extern void tsk_debug2();
extern void tsk_sys(); extern void tsk_sys();
static const task_info tasks[ TSK_LAST ] = { static const task_status ( *tasks[ TSK_LAST ] )() = {
tsk_sw, tsk_sw,
tsk_adc, tsk_adc,
tsk_batt, tsk_batt,
@ -31,7 +31,6 @@ static const task_info tasks[ TSK_LAST ] = {
tsk_debug, tsk_debug,
tsk_debug2, tsk_debug2,
tsk_sys, tsk_sys,
}; };