Files
infineon_plc/PLC/LibraryCandidates/Scheduler/POUs/FB_Scheduler.TcPOU

170 lines
4.8 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_Scheduler" Id="{af4eba28-c46c-4c30-8885-00e91057da4d}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Scheduler
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR_IN_OUT
fbFlowRecHandler : FB_FlowRecHandler;
fbJobQueue : FB_JobQueue;
END_VAR
VAR
// Array needs to start at 1 so that 0 can be an invalid station
// Maybe later change this to int ant -1
_aiStations : ARRAY[1..(GVL_Scheduler.MAX_STATIONS)] OF I_Station;
_uiStationCount : UINT := 0;
_fbTransport : I_Transport;
_uiCnt : UINT;
_uiNextAvailStation : UINT;
_iFlowRecIdx : INT;
_dwNextProcReq : DWORD;
_stTmpJob : ST_TransJob;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[// Call job queue
fbJobQueue(xEnableAging := FALSE);
// Avoid invalid interface refs
IF (_uiStationCount = 0) OR (_fbTransport = 0) THEN
RETURN;
END_IF
IF (NOT _fbTransport.P_Available) THEN
// No need to check the stations if we don't have a transport ready
RETURN;
END_IF
FOR _uiCnt := 1 TO _uiStationCount DO
IF _aiStations[_uiCnt].P_ProdAvail THEN
// Get flow recipe index
_iFlowRecIdx := _aiStations[_uiCnt].P_CurrFlowRecIdx;
// Get next process requirements
IF (NOT fbFlowRecHandler.M_GetNextProcReq(iIdx := _iFlowRecIdx, dwProcReq => _dwNextProcReq)) THEN
CONTINUE;
END_IF
// Find next available station according to recipe and available station
_uiNextAvailStation := M_FindNextAvailStation(_dwNextProcReq);
// Check if there is a station available
IF _uiNextAvailStation <> 0 THEN
// Reserve source station
_stTmpJob.uiFromStationHandle := _aiStations[_uiCnt].M_Reserve();
// Reserve target station
_stTmpJob.uiToStationHandle := _aiStations[_uiNextAvailStation].M_Reserve();
// Check if we could reserve the stations
IF (_stTmpJob.uiToStationHandle <> 0) AND (_stTmpJob.uiFromStationHandle <> 0) THEN
// Create transport job
_stTmpJob.uiFromStation := _uiCnt;
_stTmpJob.uiToStation := _uiNextAvailStation;
_stTmpJob.uiPrio := fbFlowRecHandler.M_GetNextPrio(iIdx := _iFlowRecIdx);
// Add job to job queue
fbJobQueue.M_AddJob(stJob := _stTmpJob);
ELSE
// Remove registrations from stations
_aiStations[_uiCnt].M_Release(_stTmpJob.uiFromStationHandle);
_aiStations[_uiNextAvailStation].M_Release(_stTmpJob.uiToStationHandle);
END_IF
END_IF
END_IF
END_FOR]]></ST>
</Implementation>
<Method Name="M_ClearStations" Id="{7c667e8a-38f2-48a9-afff-834e87e4d3f6}">
<Declaration><![CDATA[METHOD M_ClearStations
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Remove all registered stations from array
MEMSET(destAddr := ADR(_aiStations), fillByte := 0, n := SIZEOF(_aiStations));
// Reset number of registered stations
_uiStationCount := 0;]]></ST>
</Implementation>
</Method>
<Method Name="M_FindNextAvailStation" Id="{75382296-32be-4724-b020-39273aa8358c}">
<Declaration><![CDATA[METHOD PRIVATE M_FindNextAvailStation : UINT
VAR_INPUT
dwProcReq : DWORD;
END_VAR
VAR
_uiCnt : UINT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[FOR _uiCnt := 1 TO _uiStationCount DO
IF _aiStations[_uiCnt].M_HasCapabilty(dwProcReq) AND _aiStations[_uiCnt].P_Available THEN
M_FindNextAvailStation := _uiCnt;
RETURN;
END_IF
END_FOR
M_FindNextAvailStation := 0;]]></ST>
</Implementation>
</Method>
<Method Name="M_GetStation" Id="{e8451683-3cd1-4d6f-99dd-76f33ecd008d}">
<Declaration><![CDATA[METHOD M_GetStation : I_Station
VAR_INPUT
iStationIdx : INT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF iStationIdx < 1 OR iStationIdx > (GVL_Scheduler.MAX_STATIONS - 1) THEN
M_GetStation := 0;
RETURN;
END_IF
M_GetStation := _aiStations[iStationIdx];]]></ST>
</Implementation>
</Method>
<Method Name="M_Register" Id="{6a14034a-d5c0-46c1-a13b-418885a02563}">
<Declaration><![CDATA[METHOD M_Register
VAR_INPUT
fbStation : I_Station;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Check if station is valid interface
IF fbStation = 0 THEN
RETURN;
END_IF
// Check if we have free slots
IF _uiStationCount < GVL_Scheduler.MAX_STATIONS THEN
_uiStationCount := _uiStationCount + 1;
_aiStations[_uiStationCount] := fbStation;
_aiStations[_uiStationCount].P_StationID := _uiStationCount;
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_RegisterTransport" Id="{a85ebd03-27a5-40c5-bd8f-ade9f2eac962}">
<Declaration><![CDATA[METHOD M_RegisterTransport
VAR_INPUT
fbTransport : I_Transport;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Check if transport is valid interface
IF fbTransport = 0 THEN
RETURN;
END_IF
// Set transport interface
_fbTransport := fbTransport;
]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>