目次
前
次
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 ;
}
}
タスクの内容とタイマー割込みに関係する内容を
追加して、ターゲットマイコンにあわせたソース
コードにします。
目次
前
次