タスクはプログラムの並行実行の単位です。
to be filled in
アプリケーション開発者は tTask セルタイプのセルを生成することにより、タスクを生成することができます。次の例では MyTask
という名前のタスクセルを生成し、 MyCell
の eTaskBody
をメインルーチンとして結合しています。
celltype tMyCellType {
entry sTaskBody eTaskBody;
};
cell tMyCellType MyCell {};
cell tTask MyTask {
attribute = C_EXP("TA_ACT");
stackSize = 1024;
priority = 42;
cTaskBody = MyCell.eTaskBody;
};
void eTaskBody_main(CELLIDX idx)
{
CELLCB *p_cellcb = GET_CELLCB(idx);
// ...
}
tTask が提供する :tecs~tTask::eTask
という名前の受け口を利用することにより、タスクの制御及び状態の取得を行うことができます。
cell tTask MyTask {};
celltype tMyAnotherCellType {
call sTask cTask;
};
cell tMyAnotherCellType MyAnotherCell {
cTask = MyTask.eTask;
};
// タスクの起動
cTask_activate();
// タスクの現在状態の参照
T_RTSK taskStatus;
cTask_refer(&taskStatus);
なお、非タスクコンテキスト内では、:tecs~tTask::eTask
の代わりに :tecs~tTask::eiTask
を使用する必要があります。
tTask によるタスクの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。
factory {
write("tecsgen.cfg",
"CRE_TSK(%s, { %s, $cbp$, tTask_start, %s, %s, NULL });",
id, attribute, priority, stackSize);
};
最初の MyTask
を用いた例の場合、以下のような静的API記述が生成されます。
CRE_TSK(TSKID_tTask_MyTask, { TA_ACT, &tTask_CB_tab[0], tTask_start, 42, 1024, NULL });
tTask が持つ属性は、 :tecs~tTask::id
を除き実行時にはすべて未使用である為、[omit]
指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。
上で示した静的 API 記述では、メインルーチンとして tTask_start
という名前の関数が指定されています。この関数では以下に示すコードにより TECS への橋渡しを行います。
void
tTask_start(intptr_t exinf)
{
CELLCB *p_cellcb = (CELLCB *) exinf;
cTaskBody_main();
}
:tecs~tTask::eTask
及び :tecs~tTask::eiTask
に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。
Inline ER
eTask_activate(CELLIDX idx)
{
CELLCB *p_cellcb = GET_CELLCB(idx);
return(act_tsk(ATTR_id));
}