Is it possible to iterate through all tasks without any information of the tasks?

I am trying to create a function where I check if all tasks are running or not, but I cant find a way to iterate through all tasks.

I am thinking something like this


        FOR taskNo FROM 1 TO 20 DO
            IF NOT TaskIsExecuting(taskNo) RETURN FALSE;

        ENDFOR

but the TaskIsExecuting-function does not take a number as input.

I’d rather not use the ReadCfgData to analyze the systemparameters if not absolutely neccecary.

TaskIsExecuting(“T_Rob” + NumToStr(TaskNo,0))

It is suggested to try an array with the task names.

CONST string stTaskNames {5}:= [“T_ROB1”, … T_TaskX"];

FOR index FROM 1 to dim(stTaskNames,1) DO

IF NOT TaskIsExecuting(stTaskNames {index}) RETURN FALSE

Thank for your suggestions, but unfortunately I don’t know anything about the present tasks at “compile-time” so I cannot use the array-solution.
Also, I cannot take for granted that the tasks are named in a certain way so to build the tasknames is not an option.

It sounds then like you are going to have to go with ReadCfgData.

Hello,

I agree with lemester68 to use the ReaedCfgData, but it is not possible to search directly for the names of the tasks, because you could only search for the value of a string parameter in the configuration data.

The following code searches only for all normal tasks in the system:

LOCAL PROC GetTaskName()
    VAR num nListIndex;
    VAR string stTaskName;

    !read all normal task names from sys.cfg
    WHILE nListIndex<>END_OF_LIST DO
      ReadCfgData "/SYS/CAB_TASKS/Type/NORMAL","Name",stTaskName\ListNo:=nListIndex;
      TPWrite "Task name: "+stTaskName;
    ENDWHILE

  ENDPROC

If you want to search for all task types you have to add a search for the static and semi-static tasks.

Thanks for your suggestion. I have already considered this but I was looking for an “easier” way. Something like GetTaskName 1; would give me the name of task 1.

Hi Markus,

Did you ever happen across a convenient way of doing this?
I ended up writing a module (below) to discover the tasks and store some info about them,
but was also looking for a more simple way to get the data

%%%
	VERSION:1.0
	LANGUAGE:ENGLISH
%%%

MODULE Forge_Task(SYSMODULE)
!--------------------------------------------------------------------------------------------------!
!	Description:	Example Description															   !
!																								   !
!	| Revision | Date 		| Author | Description												   !
!	|----------|------------|--------|-------------------------------------------------------------!
!	| 1.0	   | 2022/03/07 | H.P.   | Document Creation										   !
!--------------------------------------------------------------------------------------------------!
    
	! Create an alias for the string datatype for task types, Normal, Static, SemiStatic
	ALIAS string tasktype;
	
	! Create a record for storing data about all tasks in the system
    RECORD fe_taskdata
		string Name; 		! Task name from the Controller System Config
		tasktype Type;		! The type of task in case this is relevant for certain operations
		tsp_status Status;	! Task active in controller status
		bool Executing;		! Task executing in controller status
	ENDRECORD
	
	! Constants representing each type of task
	CONST tasktype TKT_Normal 		:= "NORMAL";
	CONST tasktype TKT_Static 		:= "STATIC";
	CONST tasktype TKT_SemiStatic 	:= "SEMISTATIC";
	CONST tasktype TKT_None 		:= "";
	! Store an array of the task types for easy searching
	VAR tasktype tkt_Types{4} := [TKT_Normal, TKT_SemiStatic, TKT_Static, TKT_None]; 
	CONST num N_NumTaskTypes := 4; ! Number of different task types
	
	! An array storing all task data
	PERS fe_taskdata tsd_Tasks{20} := [["T_ROB1","NORMAL",14,TRUE],["T_ROB1_GUI","NORMAL",14,TRUE],["T_ROB1_Maintenance","NORMAL",14,FALSE],["T_ROB1_Background","SEMISTATIC",14,TRUE],["tAwSys_1","STATIC",13,TRUE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE],["","",-1,FALSE]];
	CONST num N_MaxTasks := 20; ! The maximum number of concurrent tasks
	
    !**********************************************************************************************!
    PROC LoadTasksFromConfig(INOUT fe_TaskData Tasks{*})										   !
    ! Description:																				   !
    ! 	Loads all task data into the given array												   !
    !																							   !
    ! Parameters:																				   !
    ! 	INOUT fe_taskData Tasks	-	An array, empty or otherwise of task data to be filled		   !
    !																							   !
    ! Author: Harry Parker		Date: 2022/03/07		Revision: 1.0							   !
    !**********************************************************************************************!
        
        VAR num n_CfgIndex := 0;		! Index of the configuration attribute in the instance list
		VAR string s_TaskName := ""; 	! Task name of searched task from the config file
		VAR num n_ListIndex := 1;		! The index of the input array to store the task data in
		VAR num n_TaskTypeIndex := 1; 	! The index of the current task type to search for
		
		! Loop through the array of stored tasks, while searching the config file for tasks
		WHILE n_ListIndex <= N_MaxTasks DO
			! If there are still task types to search for
			IF n_TaskTypeIndex <= N_NumTaskTypes - 1 THEN
				! Try and read the next name of a normal task from the config data
				ReadCfgData "/SYS/CAB_TASKS/Type/" + tkt_Types{n_TaskTypeIndex}, "Name", s_TaskName, \ListNo:=n_CfgIndex;
				! If the end of the list has been reached
				IF n_CfgIndex = N_EndOfList THEN
					! Have found all tasks of this type, search for the next type
					Incr n_TaskTypeIndex;
					! Reset the search index to search from 0 for the next type
					n_CfgIndex := 0;
				ENDIF
			ENDIF
			! Store the task name in the list
			Tasks{n_ListIndex}.Name := s_TaskName;
			! Store the task type in the list
			Tasks{n_ListIndex}.Type := tkt_Types{n_TaskTypeIndex};
			! Update the task executing boolean & status for this task
			UpdateTaskData Tasks{n_ListIndex};
			! Increment the list index
			Incr n_ListIndex;
		ENDWHILE
	
	!----------------------------------------------------------------------------------------------!
	ERROR ! Error handler
		! Check the error number for specific errors
		TEST ERRNO
		CASE ERR_CFG_NOTFND: ! Expected error for not finding configuration
			! If there is no config data set the index to -1 and the returned string to empty
			n_CfgIndex := -1;
			s_TaskName := "";
			! Move to the next instruction
			TRYNEXT;
		DEFAULT: ! For other unexpected errors
			RAISE; ! Raise the error to the calling procedure or function
		ENDTEST
	ENDPROC
    
	!**********************************************************************************************!
    PROC UpdateTaskData(INOUT fe_TaskData TaskData)												   !
    ! Description:																				   !
    ! 	Updates task data for the specific task													   !
    !																							   !
    ! Parameters:																				   !
    ! 	INOUT fe_taskData TaskData	-	Task data to have the status updated					   !
    !																							   !
    ! Author: Harry Parker		Date: 2022/03/07		Revision: 1.0							   !
    !**********************************************************************************************!
		
		! Update the execution status of the task
		TaskData.Executing := TaskIsExecuting(TaskData.Name);
		! Update the active status of the task
		TaskData.Status := GetTSPStatus(TaskData.Name);
		
	!----------------------------------------------------------------------------------------------!
	ERROR ! Error handler
		! Check the error number for specific errors
		TEST ERRNO
		CASE ERR_TASKNAME: ! Expected error for not finding the given task
			! Return empty data for the executing and status parameters if no task is found
			TaskData.Executing := FALSE;
			TaskData.Status := -1;
			RETURN;
		DEFAULT: ! For other unexpected errors
			RAISE; ! Raise the error to the calling procedure or function
		ENDTEST
	ENDPROC
ENDMODULE

Hi,

I did unfortunately not find a simpler way than reading the system parameters, and in the end I didn’t need the functionality. But I can see you created a really elegant solution.

Br