Vereinfachte Kommunikation mit programmierbarer Echtzeiteinheit

Die Industriekommunikation unterscheidet sich vielfach von der Technologie in Konsumergeräten. Sie muss deterministisch, schnell und sicher sein, um mit den effizienteren Produktionszyklen, einer einfacheren Wartung und den Maschinenrichtlinien übereinzustimmen. Eine der oben genannten Vereinfachungen in der industriellen Anwendung besteht in der kontrollierten Umgebung, die die Planung der Automatisierungsanlage weit vor dem Betrieb ermöglicht. Es ist jedoch immer noch erforderlich, die Kommunikationsphasen für Nicht-Echtzeit-Daten wie Standard-TCP/IP-Traffic für Konfiguration und Verwaltung zu mischen. Durchlaufverfahren oder Cut-Through-Verfahren Bei Echtzeit-Traffic sehen wir seriell basierte Feldbussysteme wie Profibus, der in einer Master/Slave-Konfiguration mit einer Datenrate von bis zu 12Mbaud betrieben wird. Die Profibus-Technologie unterliegt einer festen Echtzeitanforderung und muss 11Bit Zeiteinheiten (960ns) nach dem Erhalt eines Pakets einen Meldeblock senden. Dazu ist eine Echtzeitverarbeitung auf Paketebene erforderlich, was normalerweise auf festverdrahteten Bausteinen ausgeführt wird. Bei Industrial Ethernet wurde die Anforderung der Verarbeitung eines eingehenden Pakets auf eine Geschwindigkeit von 100MBit/S erhöht, was die Anwendung noch anspruchsvoller macht. Daher gibt es weitere Asics und FPGAs für unterschiedliche Standards. In der Master/Slave-Konfiguration muss der Zeitraum, in dem ein Paket in einem Slave verbleibt, minimiert werden. Dadurch können alle Slaves innerhalb kurzer Kommunikationszykluszeiten aktualisiert werden. Bei Ethernet-basierten Systemen mit zwei physikalischen Ports werden eingehende Pakete entweder im Durchlauf verarbeitet oder in im \’Cut-Through\‘-Verfahren. Industrial Ethernet im \’Durchlaufbetrieb\‘ ist beispielsweise Ethercat. Jedes am ersten Port empfangene Paket wird am zweiten Port gesendet. Die Ein-/Ausgangsdaten werden während sich das Paket im Slave-Controller befindet geändert. Die Verzögerung im Slave-Controller bemisst sich nach der Verarbeitungsbreite des Pakets. Bei einer 16Bit-Verarbeitung von Ethernet-Paketen mit 100Mbit/S tritt eine Verzögerung von 160ns auf. Weitere Verzögerungen von Ethernet Phy und eine Synchronisierung von verschiedenen Zeitbereichen führen zu einer Draht-zu-Draht-Verzögerung von 600 bis 700ns. Bei \’Cut-Through\‘ Switches wie Profinet IRT wird auf der Basis des Paket-Headers entschieden. Hier muss der Slave-Controller auf die Header-Information und eine Filterübereinstimmung warten, bevor das Paket an den zweiten Port weitergeleitet werden kann. Die Verzögerung liegt hier in einem Bereich von 1 bis 3µs. Latenz- und Jitter-Anforderungen für Industrial Ethernet machen es für \’pipelined\‘ CPUs unmöglich, einen programmierbaren Ansatz mit einem Slave-Controller für mehrere Protokolle anzuwenden. Die PRU als programmierbarer Ansatz für die Industriekommunikation mit mehreren Protokollen verarbeitet die Latenz- und Jitter-Anforderungen von Ethernet-Verkehr mit bis zu 100MBit/S. Programmierbare Echtzeiteinheit (Programmable Real-time Unit – PRU) Der 32Bit Risc-Prozessor ist speziell für die Verarbeitung von gepackten Datenstrukturen in Echtzeit ausgelegt. Ein PRU-Subsystem wird paarweise mit zwei Prozessoren geliefert, wobei jede CPU normalerweise bei 200MHz läuft. Die Architektur mit einem einfachen Satz an Instruktionen umfasst ca. 40 Instruktionen für Logik-, Arithmetik- und Ablaufsteuerungsfunktionen. Jede Instruktion die auf einem Register arbeitet benötigt einen Taktzyklus. Die Daten können über Lade- und Speicherbefehle vom Systemspeicher aus gelesen und geschrieben werden. Diese Datentransfers können schubweise auftreten und die Ausführungszeit hängt von der Verbindungs- und Speicherzugriffzeit ab. PRU-Core Ein PRU-Core ist in Abbildung 2 zu sehen. Die Architektur ist nicht linear ausgelegt, was bedeutet, dass der Abruf der Instruktionen, die Entschlüsselung und Ausführung mit einem einzigen PRU-Takt durchgeführt wird. Dies bildet die Basis für die Echtzeitverarbeitung von Daten im Register. Register sind 32Bit groß und können in Bit, Byte, 16Bit und 32Bit angesprochen werden. Register 30 ist mit externen Signalen verknüpft und kann als Ausgang genutzt werden. Register 31 ist ebenfalls extern verknüpft und spiegelt den Status der Eingänge wieder. Die PRU-basierte GPIO-Programmierung erzeugt einen Jitter von normalerweise 5ns oder einen PRU-Taktzyklus. Die letzten beiden Bit von R31 sind mit dem Interrupt-Controller verknüpft. Die PRU analysiert R31 Bit 30 und Bit 31 für Interrupts. Die PRU kann auch Interrupts zum System erzeugen, indem sie in die ersten fünf Bit von Register R31 schreibt. Der Interrupt-Controller verarbeitet bis zu 64 Events, die in zehn Kanäle gruppiert werden können. Innere Angelegenheiten Eine typische PRU-Instruktion arbeitet mit drei Operanden. Beispielsweise stellt ADD R3,R2,R1 die Summe von Register R1 + R2 in Register R3. Da kein Registerfeld angegeben wurde, nimmt der Vorgang 32Bit-Werte. Bei Instruktion \’ADD R3.b3, R2.b0, R1,b0\‘ liegt die Betriebsbreite nun bei 8Bit und das Ergebnis wird im höchsten Byte von Register R3 gespeichert. Der bitweise Betrieb wird durch Rx.ty angegeben. Die Instruktion CLR R0.t17 löscht Bit 17 in Register 0. Die Instruktion QBBS label,R0.t17 verzweigt zur Sprungaddresse, wenn Bit 17 in Register R0 gesetzt ist. Die Ausführungszeit des QBBS (Quick Branch Bit Set) ist ein einziger Takt, unabhängig davon ob eine Verzweigung durchgeführt wird. Die deterministische Einzyklusausführung einschließlich bedingter Verzweigungen und Einzelbitbedingungen macht aus der PRU-Programmierung eher einen Echtzeitentwurf für Schnittstellen als eine objektorientierte Verarbeitung einer höheren Programmiersprache. Die meisten Instruktionen werden in einzelnen Registern betrieben. Die PRU unterstützt eine parallele Schnittstelle, die Operationen verknüpfen kann, die sich auf komplette Register erstrecken. Es gibt mit parallelen Schnittstelle verknüpfte Instruktionen, die grundsätzlich neue Register mit einem Hauptregister verknüpfen. Dies dient zum Hinzufügen weiterer Register und zur Durchführung von Coprozessor-Schnittstellen, deren Ergebnisse in weiteren Registern verknüpft sind. Um Daten in Register zu stellen und daraus abzurufen wird ein Burstverfahren mit Byte-Granularität verwendet. Beispielsweise schreibt SBCO R15.b3, C31, 4, 17 17Bytes angefangen vom hoechsten Byte in Register R15 in die Systemspeicheradresse, die in C31 referenziert ist, plus ein Offset von 4Byte. Eine ähnliche Instruktion ist für das Lesen von Daten vorhanden. LBBO R1, R0, 0, 16 lädt 16Byte vom Systemspeicher in Register R1 bis R4. In diesem Beispiel wird die Systemadresse in Register R0 und kein Offset angewendet. PRU-Programmierung PRU-Instruktionen zum Register sind nicht leicht zu verstehen, wenn eine komplexere Firmware entwickelt wird. Das Assembler-Tool für die PRU bietet Funktionen, die den Code strukturierter und lesbarer machen. Pre-Prozessorbefehle wie #define, #include und #ifdef sind aus der C-Programmiersprache bekannt und können genauso bei der PRU-Programmierung verwendet werden. Assembler-Punktbefehle helfen beim Aufbau von Strukturen, Makros und der Zuweisung zu einem Register. Anstatt auf den Paketinhalt über das Register und den Byte-Offset zu verweisen kann der Benutzer eine Struktur mit dem Register verknüpfen und auf PktBuf.length referenzieren. Die Fehlersuche in der PRU-Software kann auf zwei Arten erfolgen. Zum einen ein Debug-Server an der Host-CPU, der annimmt, dass ein Ethernet-Port eine Verbindung zur integrierten Entwicklungsumgebung am PC herstellt. Ein derartiger Debug-Server ist für Linux-basierte ARM CPUs vorhanden. Eine zweite Möglichkeit ist JTAG und Code Composer Studio, das die parallele Fehlersuche von mehreren Kernen im System ermöglicht. Wichtige Funktionen des Debuggers sind Programmstopps, Einzelschritte, Registeransicht und Zykluszähler. Die PRU-Treibersoftware auf der Host-CPU wird verwendet, um PRU-Funktionen in der Anwendung zu verarbeiten. Sie enthält Funktionen zum Laden, Starten, Stoppen von Firmware und zum Verarbeiten von Interrupts. Für die Zeitsynchronisierung in Industrial-Ethernet-Netzwerken wird die Differenz zwischen einer Referenzuhr und der lokalen Uhr periodisch gemessen und gefiltert. Durch die Verwendung eines einfachen Mittelungsalgorithmus wird der Zyklus-zu-Zyklus-Jitter reduziert. Die Filterberechnung per Zeitvergleich dauert vier Zyklen unter der Annahme, dass sich die Daten im Register befinden. Standard ARM CPU mit integ-riertem Industrial Ethernet Industrial-Ethernet-Standards unterscheiden sich auf vielfältige Weise, weshalb eine separate Hardware-Implementierung erforderlich ist. Mit PRU und zusätzlicher Hardwareunterstützung wird ein einzelner Hardwarefunktionsblock zur Implementierung verschiedener Standards wie Ethercat und Profinet verwendet. Abbildung 3 zeigt den Industriekommunikationsprozessor AM335x mit integriertem PRU-Subsystem. Durch eine schnelle 32Bit-Verbindung zwischen der ARM Cortrex A8 CPU und den PRUs hat der Anwendungsprozessor Echtzeitzugriff auf Industrial Ethernet. Ein zusätzlicher 64KB L3-Speicher dient als Kommunikationspuffer und wird als Switchpuffer für Profinet IRT verwendet. Der AM335x kann im MCU-Modus betrieben werden, wobei der kritische Code im L2 Cache-Speicher eingefroren ist. Bei größeren Systemen wird ein externer DDR-Speicher verwendet. Mit einem umfangreichen Satz an On-Chip-Peripherie wird die AM335x-Reihe in Steuerungs-, Antriebs- und Sensoranwendungen mit integriertem Industrial Ethernet verwendet. Die Leistungsaufnahme für eine Ethercat-Slave-Anwendung liegt unter 500MW. Das Gerät wird mit einem industriellen und erweiterten Temperaturbereich angeboten, um industrielle Anforderungen zu erfüllen.