Registrierung für Callback

Allgemeines

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_AsyncGetAt­tributeSingle 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 ifEtherNetIP­Adapter.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
VAR_INPUT
   i_ifAsyncGetAttributeAll : IF_AsyncG­etAttributeAll;
END_VAR

IsRegisteredAsyncGetAttributeSingle

METHOD IsRegisteredAsyncGetAttributeS­ingle : BOOL
VAR_INPUT
   i_ifAsyncGetAttributeSingle : IF­_AsyncGetAttributeSingle;
END_VAR

IsRegisteredAsyncSetAttributeSingle

METHOD IsRegisteredAsyncSetAttributeS­ingle : BOOL
VAR_INPUT
   i_ifAsyncSetAttributeSingle : IF­_AsyncSetAttributeSingle;
END_VAR

RegisterAsyncGetAttributeAll

METHOD RegisterAsyncGetAttributeAll : BOOL
VAR_INPUT
   i_ifAsyncGetAttributeAll : IF_AsyncG­etAttributeAll;
END_VAR

RegisterAsyncGetAttributeSingle

METHOD RegisterAsyncGetAttributeSingle : BOOL
VAR_INPUT
   i_ifAsyncRead : IF_AsyncRead;
END_VAR

RegisterAsyncSetAttributeSingle

METHOD RegisterAsyncSetAttributeSingle : BOOL
VAR_INPUT
   i_ifAsyncGetAttributeSingle : IF­_AsyncGetAttributeSingle;
END_VAR

UnregisterAsyncGetAttributeAll

METHOD UnregisterAsyncGetAttributeAll : BOOL
VAR_INPUT
   i_ifAsyncGetAttributeAll : IF_AsyncG­etAttributeAll;
END_VAR

UnregisterAsyncGetAttributeSingle

METHOD UnregisterAsyncGetAttributeSing­le : BOOL
VAR_INPUT
   i_ifAsyncGetAttributeSingle : IF­_AsyncGetAttributeSingle;
END_VAR

UnregisterAsyncSetAttributeSingle

METHOD UnregisterAsyncSetAttributeSing­le : BOOL
VAR_INPUT
   i_ifAsyncSetAttributeSingle : IF­_AsyncSetAttributeSingle;
END_VAR

RegisterAsyncClass

METHOD RegisterAsyncClass : UDINT
VAR_INPUT
   i_byClassId : BYTE;
END_VAR

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().