目次

RTOSコンフィグレータ(Python)

 マイコンでReal Time Operating System(RTOS)が必要な
 ときは、自作のUSO(Unvoiced Shadow Operating system)
 を利用します。

 C、Tcl/Tkを使ったRTOSのコンフィグレータは
 ありますが、少し複雑なのでPythonで書直し
 使いやすくしました。

 コンフィグレータを利用すると、パラメータを設定
 するだけで、RTOSを組込んだ、雛形ファイルを生成
 できます。

 Pythonで書直しし、使いやすくしてみます。

 Tcl/Tkでは、GUIを利用して使い勝手をよく
 してあります。



 テキストファイルcfg.txにパラメータを入力
 しておき、CUIでコンフィグレータを動かします。

 指定するパラメータは、生成するCソースコード名
 とタスク数です。



 DOS窓で利用すると、次のようにします。



 スクリプトの内容は、以下。

# open
fin = open('cfg.txt','r')
# get parameters
line = fin.read()
dout = line.split('\n')
# close
fin.close()

# HTML file name and acount
xline = dout[0].split(' ')

# generate filename 
fname = xline[0] + ".c"
acnt  = xline[1]
iacnt = int(acnt)
print fname

# open
fout = open( fname , 'w' )

# header
fout.write("/*\n")
fout.write(" "+fname+"\n")
fout.write("\n")
fout.write("    task number "+acnt+"\n")
fout.write("\n")
fout.write("*/\n")
# macro
fout.write("#define OFF 0\n")
fout.write("#define ON  OFF+1\n")
fout.write("\n")
fout.write("#define NO  0\n")
fout.write("#define YES NO+1\n")
fout.write("\n")
fout.write("/* redefine data types */\n")
fout.write("typedef unsigned char  UBYTE ;\n")
fout.write("typedef   signed char  SBYTE ;\n")
fout.write("typedef unsigned short UWORD ;\n")
fout.write("typedef   signed short SWORD ;\n")
fout.write("typedef unsigned long  ULONG ;\n")
fout.write("\n")
fout.write("/* define TCB */\n")
fout.write("typedef struct {\n")
fout.write("  void  (*tsk)(void);\n")
fout.write("  UWORD wcount ;\n")
fout.write("} TCBP ;\n")
fout.write("\n")
fout.write("TCBP tcb[TSK_ID_MAX];\n")
fout.write("\n")
fout.write("/* define TASK state */\n")
fout.write("#define TTS_SUSPEND 0\n")
fout.write("#define TTS_WAIT    TTS_SUSPEND+1\n")
fout.write("#define TTS_READY   TTS_SUSPEND+2\n")
fout.write("\n")
fout.write("volatile UWORD ready  ;\n")
fout.write("volatile UWORD suspend;\n")
fout.write("volatile UWORD waitq ;\n")
fout.write("volatile UWORD run_tsk;\n")
fout.write("volatile UBYTE tflag;\n")
fout.write("\n")
# genarate task number
for e in range(0,iacnt) :
  fout.write("#define TSK_ID"+str(e)+" "+str(e)+"\n")
fout.write("\n")
fout.write("/*-----------------------*/\n")
fout.write("/* system call prototype */\n")
fout.write("/*-----------------------*/\n")
fout.write("void  init_os(void);\n")
fout.write("void  cre_tsk(UBYTE tid,void (*tsk)(void));\n")
fout.write("void  sta_tsk(UBYTE tid,UBYTE sta);\n")
fout.write("void  rsm_tsk(UBYTE tid);\n")
fout.write("void  sus_tsk(UBYTE tid);\n")
fout.write("void  slp_tsk(void);\n")
fout.write("void  wai_tsk(UWORD x);\n")
fout.write("UBYTE is_tsk_ready(UBYTE tid);\n")
fout.write("void  timer_handler(void);\n")
fout.write("\n")
fout.write("/*--------------------------------*/\n")
fout.write("/* Insert user functions protoype */\n")
fout.write("/*--------------------------------*/\n")
fout.write("void  user_initialize(void);\n")
fout.write("\n")
fout.write("/*------*/\n")
fout.write("/* main */\n")
fout.write("/*------*/\n")
fout.write("int main(void)\n")
fout.write("{\n")
fout.write("  TCBP  pcur_tsk ;\n")
fout.write("\n")
fout.write("  user_initialize();\n")
fout.write("\n")
fout.write("  cli() ;\n")
fout.write("  /* initialize monitor */\n")
fout.write("  init_os();\n")
fout.write("\n")
for e in range(0,iacnt) :
  fout.write("  cre_tsk(TSK_ID"+str(e)+",tsk"+str(e)+"_proc);\n")
fout.write("\n")
for e in range(0,iacnt) :
  fout.write("  sta_tsk(TSK_ID"+str(e)+",TTS_SUSPEND);\n")
fout.write("\n")
fout.write("  sei();\n")
fout.write("  /* loop */\n")
fout.write("  run_tsk = TSK_ID0 ;\n")
fout.write("  while ( ON ) {\n")
fout.write("    /* dispatcher */\n")
fout.write("    pcur_tsk = tcb[run_tsk] ;\n")
fout.write("    if ( is_tsk_ready( run_tsk ) == YES ) { (*(pcur_tsk.tsk))(); }\n")
fout.write("    run_tsk++;\n")
fout.write("    if ( run_tsk == TSK_ID_MAX ) { run_tsk = TSK_ID0 ; }\n")
fout.write("    /* timer */\n")
fout.write("    if ( tflag == ON ) {\n")
fout.write("      tflag = OFF ;\n")
fout.write("      timer_handler();\n")
fout.write("    }\n")
fout.write("  }\n")
fout.write("  /* dummy */\n")
fout.write("  return 0 ;\n")
fout.write("}\n")
#
fout.write("\n")
fout.write("/*-----------------------*/\n")
fout.write("/* Insert user functions */\n")
fout.write("/*-----------------------*/\n")
fout.write("void user_initialize(void)\n")
fout.write("{\n")
fout.write("\n")
fout.write("}\n")
fout.write("\n")
fout.write("/*----------------*/\n")
fout.write("/* task functions */\n")
fout.write("/*----------------*/\n")
for e in range(0,iacnt) :
  fout.write("void tsk"+str(e)+"_proc(void)\n")
  fout.write("{\n")
  fout.write("\n")
  fout.write("}\n")
  fout.write("\n")
#
fout.write("/*------------------*/\n")
fout.write("/* system call body */\n")
fout.write("/*------------------*/\n")
fout.write("void init_os(void)\n")
fout.write("{\n")
fout.write("  ready   = 0 ;\n")
fout.write("  suspend = 0 ;\n")
fout.write("  waitq   = 0 ;\n")
fout.write("  tflag   = OFF ;\n")
fout.write("}\n")
fout.write("\n")
fout.write("void cre_tsk(UBYTE tid,void (*tsk)(void))\n")
fout.write("{\n")
fout.write("  tcb\[tid\].tsk    = tsk;\n")
fout.write("  tcb\[tid\].wcount = 0;\n")
fout.write("}\n")
fout.write("\n")
fout.write("void sta_tsk(UBYTE tid,UBYTE sta)\n")
fout.write("{\n")
fout.write("  UWORD tmp ;\n")
fout.write("  tmp = (1 << tid);\n")
fout.write("  if ( sta == TTS_READY   ) { ready   |= tmp; }\n")
fout.write("  if ( sta == TTS_SUSPEND ) { suspend |= tmp; }\n")
fout.write("  if ( sta == TTS_WAIT    ) { waitq   |= tmp; }\n")
fout.write("}")
fout.write("\n")
fout.write("void rsm_tsk(UBYTE tid)\n")
fout.write("{\n")
fout.write("  UWORD tmp ;\n")
fout.write("  tmp = (1 << tid);\n")
fout.write("  ready   |=  tmp;\n")
fout.write("  suspend &= ~tmp;\n")
fout.write("  waitq   &= ~tmp;\n")
fout.write("}\n")
fout.write("\n")
fout.write("void sus_tsk(UBYTE tid)\n")
fout.write("{\n")
fout.write("  UWORD tmp ;\n")
fout.write("  tmp = (1 << tid);\n")
fout.write("  ready   &= ~tmp;\n")
fout.write("  suspend |=  tmp;\n")
fout.write("  waitq   &= ~tmp;\n")
fout.write("}\n")
fout.write("\n")
fout.write("void slp_tsk(void)\n")
fout.write("{\n")
fout.write("  sus_tsk(run_tsk);\n")
fout.write("}\n")
fout.write("\n")
fout.write("void wai_tsk(UWORD x)\n")
fout.write("{\n")
fout.write("  UWORD tmp ;\n")
fout.write("  tmp = (1 << run_tsk);\n")
fout.write("  ready   &= ~tmp;\n")
fout.write("  suspend &= ~tmp;\n")
fout.write("  waitq   |=  tmp;\n")
fout.write("  tcb\[run_tsk\].wcount = x ;\n")
fout.write("}\n")
fout.write("\n")
fout.write("UBYTE is_tsk_ready(UBYTE tid)\n")
fout.write("{\n")
fout.write("  return( (ready >> tid) & 1 ) ;\n")
fout.write("}\n")
fout.write("\n")
fout.write("void timer_handler(void)\n")
fout.write("{\n")
fout.write("  volatile UWORD xtmp;\n")
fout.write("  volatile UBYTE loop;\n")
fout.write("  /* call timer handling */\n")
fout.write("  xtmp = waitq ;\n")
fout.write("  for ( loop = 0 ; loop < TSK_ID_MAX ; loop++ ) {\n")
fout.write("    if ( xtmp & 1 ) {\n")
fout.write("      tcb\[loop\].wcount-- ;\n")
fout.write("      if ( tcb\[loop\].wcount == 0 ) { rsm_tsk(loop); }\n")
fout.write("    }\n")
fout.write("    xtmp >>= 1 ;\n")
fout.write("  }\n")
fout.write("}\n")
# close
fout.close()

 ファイルが作成されているかを確認します。



 生成されたCのソースコードは、以下。

/*
 hoge.c

    task number 3

*/
#define OFF 0
#define ON  OFF+1

#define NO  0
#define YES NO+1

/* redefine data types */
typedef unsigned char  UBYTE ;
typedef   signed char  SBYTE ;
typedef unsigned short UWORD ;
typedef   signed short SWORD ;
typedef unsigned long  ULONG ;

/* define TCB */
typedef struct {
  void  (*tsk)(void);
  UWORD wcount ;
} TCBP ;

TCBP tcb[TSK_ID_MAX];

/* define TASK state */
#define TTS_SUSPEND 0
#define TTS_WAIT    TTS_SUSPEND+1
#define TTS_READY   TTS_SUSPEND+2

volatile UWORD ready  ;
volatile UWORD suspend;
volatile UWORD waitq ;
volatile UWORD run_tsk;
volatile UBYTE tflag;

#define TSK_ID0 0
#define TSK_ID1 1
#define TSK_ID2 2

/*-----------------------*/
/* system call prototype */
/*-----------------------*/
void  init_os(void);
void  cre_tsk(UBYTE tid,void (*tsk)(void));
void  sta_tsk(UBYTE tid,UBYTE sta);
void  rsm_tsk(UBYTE tid);
void  sus_tsk(UBYTE tid);
void  slp_tsk(void);
void  wai_tsk(UWORD x);
UBYTE is_tsk_ready(UBYTE tid);
void  timer_handler(void);

/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void  user_initialize(void);

/*------*/
/* main */
/*------*/
int main(void)
{
  TCBP  pcur_tsk ;

  user_initialize();

  cli() ;
  /* initialize monitor */
  init_os();

  cre_tsk(TSK_ID0,tsk0_proc);
  cre_tsk(TSK_ID1,tsk1_proc);
  cre_tsk(TSK_ID2,tsk2_proc);

  sta_tsk(TSK_ID0,TTS_SUSPEND);
  sta_tsk(TSK_ID1,TTS_SUSPEND);
  sta_tsk(TSK_ID2,TTS_SUSPEND);

  sei();
  /* loop */
  run_tsk = TSK_ID0 ;
  while ( ON ) {
    /* dispatcher */
    pcur_tsk = tcb[run_tsk] ;
    if ( is_tsk_ready( run_tsk ) == YES ) { (*(pcur_tsk.tsk))(); }
    run_tsk++;
    if ( run_tsk == TSK_ID_MAX ) { run_tsk = TSK_ID0 ; }
    /* timer */
    if ( tflag == ON ) {
      tflag = OFF ;
      timer_handler();
    }
  }
  /* dummy */
  return 0 ;
}

/*-----------------------*/
/* Insert user functions */
/*-----------------------*/
void user_initialize(void)
{

}

/*----------------*/
/* task functions */
/*----------------*/
void tsk0_proc(void)
{

}

void tsk1_proc(void)
{

}

void tsk2_proc(void)
{

}

/*------------------*/
/* system call body */
/*------------------*/
void init_os(void)
{
  ready   = 0 ;
  suspend = 0 ;
  waitq   = 0 ;
  tflag   = OFF ;
}

void cre_tsk(UBYTE tid,void (*tsk)(void))
{
  tcb\[tid\].tsk    = tsk;
  tcb\[tid\].wcount = 0;
}

void sta_tsk(UBYTE tid,UBYTE sta)
{
  UWORD tmp ;
  tmp = (1 << tid);
  if ( sta == TTS_READY   ) { ready   |= tmp; }
  if ( sta == TTS_SUSPEND ) { suspend |= tmp; }
  if ( sta == TTS_WAIT    ) { waitq   |= tmp; }
}
void rsm_tsk(UBYTE tid)
{
  UWORD tmp ;
  tmp = (1 << tid);
  ready   |=  tmp;
  suspend &= ~tmp;
  waitq   &= ~tmp;
}

void sus_tsk(UBYTE tid)
{
  UWORD tmp ;
  tmp = (1 << tid);
  ready   &= ~tmp;
  suspend |=  tmp;
  waitq   &= ~tmp;
}

void slp_tsk(void)
{
  sus_tsk(run_tsk);
}

void wai_tsk(UWORD x)
{
  UWORD tmp ;
  tmp = (1 << run_tsk);
  ready   &= ~tmp;
  suspend &= ~tmp;
  waitq   |=  tmp;
  tcb\[run_tsk\].wcount = x ;
}

UBYTE is_tsk_ready(UBYTE tid)
{
  return( (ready >> tid) & 1 ) ;
}

void timer_handler(void)
{
  volatile UWORD xtmp;
  volatile UBYTE loop;
  /* call timer handling */
  xtmp = waitq ;
  for ( loop = 0 ; loop < TSK_ID_MAX ; loop++ ) {
    if ( xtmp & 1 ) {
      tcb\[loop\].wcount-- ;
      if ( tcb\[loop\].wcount == 0 ) { rsm_tsk(loop); }
    }
    xtmp >>= 1 ;
  }
}

 タスクの内容とタイマー割込みに関係する内容を
 追加して、ターゲットマイコンにあわせたソース
 コードにします。


目次

inserted by FC2 system