PROFINET IO Controller V3 - IOCS / IOPS [DE]

Hintergrund

Mit dem Update des Profinet Stack von Version 2 zu Version 3 gab es eine signifikante Änderung im Handling mit dem sogenannten IO-Consumer-States (IOCS) sowie IO-Provider-States (IOPS). Wurden die Status-Flags bisher innerhalb des Protokoll-Stacks überprüft und behandelt, so hat man sich im Zuge des neuen Standards dazu entschieden, diese Aufgabe aus Performance-Gründen aus dem Protokoll-Stack auszulagern. Dieser Schritt war mit der Anforderung eines minimalen Buszyklus von 250 Mikrosekunden erforderlich. Die Verantwortung über die Status-Flags wurde damit an die Applikation abgetreten. Zu diesem Zweck werden nun die Status-Flags in das Prozessimage eingebettet, um so der Applikation den Zugriff auf die Status-Werte zu ermöglichen.

Umsetzung

Begriffseinordnung - Consumer / Provider

Im Kontext dieser Application-Note wird vom sogenannten Provider oder Consumer gesprochen. Als Provider wird hierbei grundsätzlich der Teilnehmer, unabhängig von seiner Rolle (Controller oder Device) bezeichnet, der die Nutz-Daten sendet. Ein Consumer ist folglich derjenige, der Nutz-Daten empfängt.

Provider & Consumer Status-Flags

Jedem konfigurierten Modul/Sub Modul wird jeweils ein Provider- und ein Consumer-Flag zugeordnet. Es wird über das Prozessdatenabbild zusammen mit den Prozessdaten zwischen den Teilnehmern ausgetauscht. Ein Provider-Status wird grundsätzlich in dieselbe Sende-Richtung wie die Prozessdaten gesendet, befindet sich also im Output-Image des DPM und wird hinter die Prozessdaten des Moduls gehängt. Der Consumer-Status wird folglich in die entgegengesetzte Richtung zu den Nutzdaten versendet, sind daher im Input-Image des DPM zu finden und wird über die Prozessdaten des nächsten Prozessdaten-Blocks gestellt.

Folgende Abbildung zeigt das Prozessdatenabbild jeweils für die Eingangs- und Ausgangs-Daten einer Beispielkonfiguration. Mithilfe der Modulnamen bzw. der darin enthaltenen Slot-Indizes <Slot_1 … Slot_n> lässt sich die Zugehörigkeit der jeweiligen Status-Flags bestimmen. Die in der Liste enthaltene Adresse zeigt, unter welchem Offset der jeweilige Wert auf dem Prozessdatenabbild erreichbar ist.

Die ersten vier Status-Bytes zählen zum sogenannten Device Access Point (DAP) und wird für jeden Bus-Teilnehmer ins Prozessabbild integriert. Sie haben die Datenlänge von „1“.  Das Setzen der Flags auf „GOOD“ ist einen erfolgreichen Kommunikationsaufbau obligatorisch.


Interpretation

Der Inhalt der Daten entspricht einer bestimmten Codierung. Sie ist im Folgenden beschrieben. Beachten Sie, dass im Rahmen einer Zertifizierung, die korrekte Behandlung der Status-Werte erforderlich sein kann.


Bit 0:

Value (hex)Bedeutung
0x0Kein weiteres IOxS Oktett folgt.
0x1Es folgt ein weiteres IOxS Oktett.


Bit 1 bis 4:

Reserviert


Bit 5 bis 6:

Value (hex)Bedeutung
0x0Detektiert im Subslot
0x1Detektiert im Slot
0x2Detektiert im IO-Device
0x3Detektiert im IO-Controller


Bit 7:

Value (hex)Bedeutung
0x0

Bad:

Das Datenfeld enthält nicht valide Daten.

0x1

Good:

Das Datenfeld enthält valide Daten

Applikative Umgebung

Selektives Handling

Die jeweiligen Module, bestehend aus dem Prozessdaten-Block und den Status-Flags, können als Einheit betrachtet werden. Dabei kann jede Einheit selektiv gehandelt werden. Das Setzen der Status-Flags wirkt sich also spezifisch auf das jeweilige Modul aus. Die Freigabe der Prozessdaten eines Moduls erfordert damit auch das Setzen bestimmter Status-Flags. Dies ist auch beim initialen Start der Bus-Kommunikation zu beachten:

  • Die Header-Flags auf den ersten vier Byte des Prozessdatenabbilds sind obligatorisch und müssen zur globalen Freigabe des Prozessdatenabbilds gesetzt werden.

  • Der Provider-Status zum entsprechenden Daten-Modul, identifizierbar durch die Slot-Nummer, gibt die jeweiligen Prozessdaten frei.

Beispiel für C/C++


Quellcode
// Array in size of process-image
uint8_t		abRecvData[27] = {0};
uint8_t 	abSendData[22] = {0};
	...
	...
	...
// Set flags of header-states
abSendData[0] = 0x80;
abSendData[1] = 0x80;
abSendData[2] = 0x80;
abSendData[3] = 0x80;

// Do I/O data exchange until a key is hit
while(!kbhit())
{	
	if(CIFX_NO_ERROR != xChannelIORead(hChannel, 0, 0, sizeof(abRecvData), abRecvData, IO_WAIT_TIMEOUT)){
		// ERROR reading IO Data area!
		...
	}
	
	// Consumer-states for incomming data-slots - set to GOOD-Flag when all data could be received completely in
	// in the consumer states in the outgoing image
	abSendData[4] = 0x80;
	abSendData[8] = 0x80;
	
	// check if provider flags from node are GOOD-Flag...
	if(abRecvData[8] != 0x80 || abRecvData[26] != 0x80){
		// Provider status are BAD ... data from node are not persistent
		...
	}

	// check if consumer reports a successful recaiption of the process data
	if(abRecvData[9] != 0x80 || abRecvData[27] != 0x80){
		// Cosumer status are BAD ... data could not receive correct from node
		...
	}
	
	// Handle I/O data-arrays
	... = abRecvData[/* {x: 4 .. 7 } */];
	... = abRecvData[/* {x: 10 .. 25 } */];
	abSendData[/* {x: 5, 6 } */] = ...
	abSendData[/* {x: 9 .. 20 } */] = ...

	// Provider-states for all outging data-slots - set to GOOD-Flag
	abSendData[7] = 0x80;
	abSendData[21] = 0x80;
	
	if(CIFX_NO_ERROR != xChannelIOWrite(hChannel, 0, 0, sizeof(abSendData), abSendData, IO_WAIT_TIMEOUT)){
		// ERROR writing IO data area!
		...
	}
	...
}


IO Monitor

Folgende Abbildung zeigt den gesamten Aufbau des Prozessdatenabbilds im IO-Monitor. Alle Module sind durch das gesetzte „GOOD“-Flag (0x80) freigegeben und werden übertragen. Zum Lesen der Prozessdaten aus dem Prozessdatenabbild ist die Kenntnis über die Position der Nutzdaten erforderlich.