Beim EtherNet/IP Adapter ist es möglich, sich für einen Callback bei einer azyklischen Anfrage zu registrieren. Kommt eine azyklische Anfrage des Scanners beim EtherNet/IP Adapter Treiber an, wird die Anfrage automatisch zuerst auf registrierte Datenbereiche ausgeführt.
Danach werden alle registrieren Benutzer-FB-Instanzen aufgerufen, die mittels der Schnittstellen IF_EIPEventHandler_AsyncGetAttributeAll, IF_EIPEventHandler_AsyncGetAttributeSingle und IF_EIPEventHandler_AsyncSetAttributeSingle beim EtherNet-/IP-Adapter registriert wurden. Dabei wird auch der Status der automatischen Anfragebearbeitung übergeben, sodass auf eventuelle Probleme reagiert werden kann. Der aktuelle Zustand wird dann in den Parameter iq_udiError geschrieben.
HINWEIS: Die Methode RegisterAsyncClass() muss aufgerufen werden, damit die Callbacks einer bestimmten Klasse in der Callback-Methode erfasst werden.
Im Programmbeispiel SR_RegisterUserCallback sollen Anfragen auf die Klasse 102 verarbeitet werden. Deshalb muss beim Registriervorgang ifEtherNetIPAdapter.RegisterAsyncClass(102) ggf. manuell aufgerufen werden.
Das Programmbeispiel für die Registrierung für einen Callback (SR_RegisterUserCallback) finden Sie hier.
HINWEIS: Wenn nicht-zyklische Datenbereiche registriert sind, wird diese Methode intern automatisch ausgeführt. In diesem Fall muss die Methode RegisterAsyncClass() nicht nicht manuell aufgerufen werden. Im Beispielprogramm SR_RegisterInstances (siehe Beispiel: Registrierung azyklischer Datenbereiche ) werden azyklische Datenmodule auf die ClassId 105 registriert . Hier muss die Methode RegisterAsyncClass() nicht verwendet werden.
Eine Auflistung aller relevanten Methoden und der zugehörigen Schnittstellen finden Sie unter Relevante Methoden (Registrierung Callback).
Relevante Methoden (Callback-Registrierung)
Im Folgenden sind alle relevanten Methoden für die Registrierung der Datenbereiche der IF_EtherNetIPAdapter-Schnittstelle aufgelistet:
Methode |
Beschreibung |
---|---|
IsRegisteredAsyncGetAttributeAll |
Gibt an, ob der übertragene Funktionsbaustein bei Empfang einer GetAttributeAll-Anforderung bereits für das Callback registriert ist. |
IsRegisteredAsyncGetAttributeSingle |
Gibt an, ob der übertragene Funktionsbaustein bei Empfang einer GetAttributeSingle-Anforderung bereits für das Callback registriert ist. |
IsRegisteredAsyncSetAttributeSingle |
Gibt an, ob der übertragene Funktionsbaustein bei Empfang einer SetAttributeSingle-Anforderung bereits für das Callback registriert ist. |
RegisterAsyncGetAttributeAll |
Registriert den übertragenen Funktionsbaustein für das Callback im Fall von GetAttributeAll-Anforderungen. |
RegisterAsyncGetAttributeSingle |
Registriert den übertragenen Funktionsbaustein für das Callback im Fall von GetAttributeSingle-Anforderungen. |
RegisterAsyncSetAttributeSingle |
Registriert den übertragenen Funktionsbaustein für das Callback im Fall von SetAttributeSingle-Anforderungen. |
UnregisterAsyncGetAttributeAll |
Hebt die Registrierung des übertragenen Funktionsbausteins für das Callback im Fall von GetAttributeAll-Anforderungen auf. |
UnregisterAsyncGetAttributeSingle |
Hebt die Registrierung des übertragenen Funktionsbausteins für das Callback im Fall von GetAttributeSingle-Anforderungen auf. |
UnregisterAsyncSetAttributeSingle |
Hebt die Registrierung des übertragenen Funktionsbausteins für das Callback im Fall von SetAttributeSingle-Anforderungen auf. |
RegisterAsyncClass |
Aktiviert die Callbacks für die übertragene ClassId. Nur wenn die Callbacks für eine bestimmte ClassId aktiviert wurden, wird der für die Callbacks registrierte Code aufgerufen. Rückgabewert 0: Die ClassId wurde erfolgreich registriert. Rückgabewert 1: Die ClassId ist bereits registriert. Rückgabewert 2: Die ClassId ist ungültig. Rückgabewert 3: Die Anfrage AsyncClassRegister REQ kann nicht gesendet werden. Rückgabewert 4: Die Anfrage AsyncClassRegister REQ war fehlerhaft. |
Deklaration der Schnittstelle
Methode |
Deklaration der Schnittstelle |
---|---|
IsRegisteredAsyncGetAttributeAll |
METHOD IsRegisteredAsyncGetAttributeAll : BOOL |
IsRegisteredAsyncGetAttributeSingle |
METHOD IsRegisteredAsyncGetAttributeSingle : BOOL |
IsRegisteredAsyncSetAttributeSingle |
METHOD IsRegisteredAsyncSetAttributeSingle : BOOL |
RegisterAsyncGetAttributeAll |
METHOD RegisterAsyncGetAttributeAll : BOOL |
RegisterAsyncGetAttributeSingle |
METHOD RegisterAsyncGetAttributeSingle : BOOL |
RegisterAsyncSetAttributeSingle |
METHOD RegisterAsyncSetAttributeSingle : BOOL |
UnregisterAsyncGetAttributeAll |
METHOD UnregisterAsyncGetAttributeAll : BOOL |
UnregisterAsyncGetAttributeSingle |
METHOD UnregisterAsyncGetAttributeSingle : BOOL |
UnregisterAsyncSetAttributeSingle |
METHOD UnregisterAsyncSetAttributeSingle : BOOL |
RegisterAsyncClass |
METHOD RegisterAsyncClass : UDINT |
Beispiel: Registrierung eines Callbacks
PROGRAM SR_RegisterUserCallback
VAR
xAlreadyRegistered : BOOL := FALSE;
fbUserCallback : FB_UserCallback;
ifEtherNetIPAdapter : IF_EtherNetIP_Adapter := EtherNet_IP_Adapter;
byIndex : BYTE := 0;
udiResult : UDINT := 0;
axResults : ARRAY[0..2] OF BOOL := [3(FALSE)];
END_VAR
IF (xAlreadyRegistered=FALSE) THEN
// Set values of global array that is returned when class 102, instance 1 is requested
FOR (byIndex:=0) TO (c_byDataLength1-1) DO
G_abyDataTransfer1[byIndex] := byIndex+1;
END_FOR
// register async class 102 which should be used in user callback
udiResult := ifEtherNetIPAdapter.RegisterAsyncClass(102);
// Register for callback when Get_Attribute_All is requested
axResults[0] := ifEtherNetIPAdapter.RegisterAsyncGetAttributeAll(fbUserCallback);
// Register for callback when Get_Attribute_Single is requested
axResults[1] := ifEtherNetIPAdapter.RegisterAsyncGetAttributeSingle(fbUserCallback);
// Register for callback when Set_Attribute_Single is requested
axResults[2] := ifEtherNetIPAdapter.RegisterAsyncSetAttributeSingle(fbUserCallback);
xAlreadyRegistered := TRUE;
END_IF
Funktionsbaustein FB_UserCallback
FUNCTION_BLOCK FB_UserCallback IMPLEMENTS
IF_AsyncGetAttributeAll,
IF_AsyncGetAttributeSingle,
IF_AsyncSetAttributeSingle
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
udiAsyncGetAttributeAllCallbackCount : UDINT := 0;
udiAsyncGetAttributeSingleCallbackCount : UDINT := 0;
udiAsyncSetAttributeSingleCallbackCount : UDINT := 0;
END_VAR
Methode AsyncGetAttributeAll
METHOD AsyncGetAttributeAll : UDINT
VAR_INPUT
i_byClassId : BYTE;
i_byInstanceId : BYTE;
END_VAR
VAR_IN_OUT
iq_abyReadData : ARRAY [0..(Gc_EtherNetIPInstance_MaxSize - 1)] OF BYTE;
(* Length of read data*)
iq_byReadDataLen : BYTE;
iq_udiError : UDINT;
END_VAR
VAR
byIndex : BYTE := 0;
END_VAR
// You can write your own code here.
// The code is called by the callback when an Get_Attribute_All operation is requested.
THIS^.udiAsyncGetAttributeAllCallbackCount := THIS^.udiAsyncGetAttributeAllCallbackCount + 1;
// This method should give back the whole array
// G_abyDataTransfer[] when Get_Attribute_Allof class 102, instance 1 is requested.
IF (i_byClassId=102 AND i_byInstanceId=1) THEN
FOR (byIndex:=0) TO (c_byDataLength1) DO
// Return data
iq_abyReadData[byIndex] := G_abyDataTransfer1[byIndex];
END_FOR
// Return read data length
iq_byReadDataLen := c_byDataLength1;
// Before this method is called, the device searches for registered data modules.
// If no data module is registered for this class, instance, attribute combination
// the value of iq_udiError can be <> 0.
// Therefore it must be set to 0 => indicates that data was read
iq_udiError := 0;
END_IF
Methode AsyncGetAttributeSingle
METHOD AsyncGetAttributeSingle : UDINT
VAR_INPUT
i_byClassId : BYTE;
i_byInstanceId : BYTE;
i_byAttributeId : BYTE;
END_VAR
VAR_IN_OUT
iq_abyReadData : ARRAY [0..(Gc_EtherNetIPAttribute_MaxSize - 1)] OF BYTE;
(* Length of read data*)
iq_byReadDataLen : BYTE;
iq_udiError : UDINT;
END_VAR
// You can write your own code here.
// The code is called by the callback when an Get_Attribute_Single operation is requested.
THIS^.udiAsyncGetAttributeSingleCallbackCount := THIS^.udiAsyncGetAttributeSingleCallbackCount + 1;
// This method should give back the value of G_abyDataTransfer[i_byAttributeId]
// when class 102, instance 1, attribute < Gc_byAttributeNumber is requested. IF (i_byClassId=102 AND i_byInstanceId=1) THEN
IF (i_byAttributeId < c_byDataLength1) THEN
// Return data
iq_abyReadData[0] := G_abyDataTransfer1[i_byAttributeId];
// Return read data length
iq_byReadDataLen := 1;
// Before this method is called, the device searches for registered data modules.
// If no data module is registered for this class, instance,
// attribute combination the value of iq_udiError can be <> 0.
// Therefore it must be set to 0 => indicates that data was read
iq_udiError := 0; ELSE // Error: Invalid attribute requested
// iq_udiError <> 0 actuates a negative response.
iq_udiError := 1;
END_IF
END_IF
Methode AsyncSetAttributeSingle
Die azyklische Anforderung GetAttributeSingle des Masters wird im Slave durch AsyncGetAttributeSingle() verarbeitet. Die Behandlung erfolgt im Beispiel analog zu AsyncGetAttributeAll().