CODESYS Example Projectを調べてみた#6(Task Manager)
Task Manager
今回は、Task Managerについて調べました。このExampleでは、CmplecTask
というライブラリを使用してタスク情報を読み取る方法を示しています。
セットアップ
コードをダウンロードし、デバイスのアップデートを行うだけで、問題なく動作させることができました。
プログラムの内容
サンプルプログラムでは、MainTaskとSecondTaskの2つのタスクが「Fixed Pinned」とプライオリティ(1, 10)の設定で実行されています。MainTaskの役割は、タスク名やプライオリティ値などの情報を取得することです。
MainTaskの実装は、以下のようになっています。Task_Info2型
やIecTaskGetCurrent()
がライブラリで提供されている機能です。
PROGRAM PLC_PRG
VAR
tTask : Task_Info2; (* Information about the task *)
aIecTasks : ARRAY[1..20] OF Task_Info2; (* Information about all tasks *)
hCurrentTask : RTS_IEC_HANDLE := SysTypes.RTS_INVALID_HANDLE; (* Current task *)
Result : RTS_IEC_RESULT; (* Result Code *)
END_VAR
// Retrieve information about the current task.
IF hCurrentTask = SysTypes.RTS_INVALID_HANDLE THEN
hCurrentTask := IecTaskGetCurrent(pResult:=ADR(Result));
tTask := CurrentTaskInfo(hCurrentTask := hCurrentTask);
END_IF
// Retrieve all task information.
aIecTasks := AllTaskInfo();
SecondTaskは、カウントアップ処理のみ実装されており、MainTask側から他のTask情報が取得できるか確認するために実行されています。
PROGRAM Second_PRG
VAR
udiCount : UDINT;
END_VAR
udiCount := udiCount + 1;
自身のTask情報を取得するために、CurrentTaskInfo()関数が定義されています。この関数内で、IecTaskGetInfo3()関数
を使ってTask情報を取得しています。タスクの指定には、IecTaskGetCurrent()
関数で取得した RTS_IEC_HANDLE 型のハンドルを、CurrentTaskInfo()関数の引数として渡しています。
FUNCTION CurrentTaskInfo : Task_Info2
VAR_INPUT
hCurrentTask : RTS_IEC_HANDLE;
END_VAR
VAR
Result : RTS_IEC_RESULT;
hIecTask: RTS_IEC_HANDLE;
END_VAR
hIecTask := hCurrentTask;
IF hIecTask <> RTS_INVALID_HANDLE AND Result = 0 THEN
CurrentTaskInfo := IecTaskGetInfo3(hIecTask:=hIecTask, pResult:=ADR(Result))^;
END_IF
取得したTask情報は以下のようなものがあります。iJitterなども取得できそうですが、今回の実行環境では値は0のままでした。(DeviceのMonitor機能では、有限の値になっている。)pJitterDistribution.wCountJitterPos変数は、逐次値が更新されていました。
Comment列に記載されている[c]と[s]の記号は、ライブラリのドキュメントによると
IecTaskCreateで使用されるタスク設定メンバには[c]、ステータスメンバには[s]が付きます。
Main Taskで呼ばれるAllTaskInfo()関数は、他のTask情報も取得しTask_Info2の配列に保存しています。最初にIecTaskGetFirst()
でハンドルを取得し、IecTaskGetInfo3()
でTask情報の取得します。そして、IecTaskGetNext()
https://content.helpme-codesys.com/en/libs/CmpIecTask/Current/IecTaskGetNext.htmlで次のタスクハンドルを取得することで、すべてのタスクを順番にしらべられうようになっています。
FUNCTION AllTaskInfo : ARRAY[1..20] OF Task_Info2
VAR_INPUT
END_VAR
VAR
hTask : RTS_IEC_HANDLE; (* task handle *)
iTasks : INT; (* task counter *)
pTask : POINTER TO Task_Info2; (* pointer to task information *)
sAppName: STRING := 'Application'; (* name of the application *)
Result : RTS_IEC_RESULT; (* error code *)
END_VAR
iTasks := 0;
hTask := IecTaskGetFirst(pszAppName:=ADR(sAppName), pResult:=ADR(Result));
WHILE hTask <> RTS_INVALID_HANDLE AND Result = 0 DO
iTasks := iTasks + 1;
pTask := IecTaskGetInfo3(hIecTask:=hTask, pResult:=ADR(Result));
IF pTask <> 0 AND Result = 0 THEN
AllTaskInfo[iTasks] := pTask^;
END_IF
(* Get the next task *)
hTask := IecTaskGetNext(pszAppName:=ADR(sAppName), hPrevIecTask:=hTask, pResult:=ADR(Result));
END_WHILE
学びと気づき
- Jitterなどが表示・グラフ表示できればデバッグに使えそう。
- Taskに関する異常値をMonitorしたい場合に使えそう。
- 動的なタスクの負荷分散が必要な場合に使えそう。
まとめ
- CmplecTaskでTaskの内容を取得できる。
- Task情報取得の流れ
-
IecTaskGetCurrent()
,IecTaskGetFirst()
などでハンドラ取得 -
IecTaskGetInfo3()
でTask情報取得 -
Task_Info2
型の変数にデータ格納
-
Discussion