170 lines
4.8 KiB
XML
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> |