CODESYS · Legacy

CODESYS 2.3 auf CODESYS 3.5: Warum die Konvertierung allein nicht reicht.

Ein konvertiertes Projekt kann syntaktisch sauber sein und sich trotzdem anders verhalten als der Bestand. Eine belastbare Migration beginnt deshalb vor dem Import und endet nicht mit einem fehlerfreien Compile.

Konvertierung beantwortet nur eine Teilfrage

Der Wechsel von CODESYS 2.3 auf CODESYS 3.5 wird leicht als Dateiformat- oder Sprachversionsproblem verstanden: altes Projekt öffnen, Konverter ausführen, Meldungen bearbeiten, neu übersetzen. Dieser Ablauf kann ein notwendiger Arbeitsschritt sein. Er beantwortet aber nur, ob sich ein Quellstand in einer neuen Entwicklungsumgebung darstellen und übersetzen lässt.

Für eine Maschinensteuerung ist die wichtigere Frage eine andere: Erzeugt die neue Kombination aus Projekt, Zielgerät, Laufzeit, Bibliotheken und Konfiguration unter allen relevanten Betriebszuständen dasselbe beabsichtigte Verhalten? Diese Gleichwertigkeit steht nicht im Projektarchiv allein. Sie entsteht aus vielen gekoppelten Annahmen über Zyklus, I/O, Initialisierung, persistente Daten, Kommunikation und reale Mechanik.

Ein erfolgreicher Import beweist Lesbarkeit. Ein erfolgreicher Build beweist technische Erzeugbarkeit. Beides beweist noch keine funktionale Gleichwertigkeit an der Maschine.

Vor dem ersten Import: den tatsächlichen Bestand festhalten

Ohne belastbaren Ausgangspunkt lässt sich später nicht unterscheiden, ob eine Abweichung aus der Migration stammt oder schon im unklaren Altbestand vorhanden war. Deshalb beginnt die Arbeit mit einer Bestandsaufnahme, die Quellcode und Laufzeit zusammenführt.

Führenden Quellstand bestimmen

Ein Projektarchiv auf einem Service-Laptop ist nicht automatisch der Stand, der auf der Steuerung läuft. Zu klären sind unter anderem:

  • welches Projektarchiv oder Repository als führend gelten soll,
  • ob Upload-Informationen und vorhandene Laufzeitdaten zum Archiv passen,
  • welche Maschinen- und Optionsvarianten aus demselben Projekt erzeugt werden,
  • welche Änderungen nur auf einzelnen Rechnern oder in exportierten Bausteinen liegen,
  • und wie der freigegebene Ausgangsstand unveränderlich referenziert wird.

Wo ein binärer Vergleich oder eine eindeutige Zuordnung technisch nicht möglich ist, bleibt das eine dokumentierte Unsicherheit. Sie darf nicht durch eine scheinbar präzise Versionsnummer verdeckt werden.

Werkzeugkette und Zielsystem erfassen

Zum Ausgangsstand gehören die eingesetzte CODESYS-Version, Zielsystemdefinitionen, Laufzeitversion, Gerätedateien, installierte Herstellerpakete, Bibliotheksstände und relevante Build-Einstellungen. Ebenso wichtig sind Taskkonfiguration, Prioritäten, Zykluszeiten, Watchdog-Einstellungen und die Art, wie Bootprojekt und Download erzeugt werden.

Diese Informationen sind keine Nebendokumentation. Sie beeinflussen, ob sich der Altstand überhaupt reproduzierbar bauen lässt und welche Semantik bei der Übertragung in die neue Umgebung erhalten werden muss.

Abhängigkeiten außerhalb des SPS-Codes sichtbar machen

Gewachsene Projekte beziehen ihr Verhalten häufig aus mehr als IEC-Programmbausteinen. Dazu können I/O-Mapping, Feldbusparameter, Visualisierung, Rezept- und Persistenzdaten, herstellerspezifische Bibliotheken, Kommunikationspartner, Dateien auf dem Zielsystem oder Funktionen eines Maschinen-PCs gehören. Eine Migration, die nur Program Organization Units betrachtet, übersieht genau diese Systemgrenzen.

Wo semantische Abweichungen entstehen können

Nicht jede Abweichung führt zu einem Compilerfehler. Kritisch sind vor allem Unterschiede, die weiterhin syntaktisch zulässig sind, aber Initialisierung, Datenhaltung oder Zeitverhalten verändern.

Bibliotheken und Zielabhängigkeiten

Eine gleich klingende Bibliotheksfunktion kann in einer anderen Version zusätzliche Voraussetzungen, geänderte Datentypen oder anderes Fehlerverhalten haben. Manche CODESYS-2.3-Bibliotheken sind eng an das damalige Zielsystem gebunden und haben in 3.5 keinen direkten Ersatz. Eine Zuordnung allein nach Namen ist deshalb zu schwach.

Für jede relevante Bibliothek sollte feststehen, wer sie bereitstellt, welche Version im Ausgangsstand verwendet wurde, welche Bausteine tatsächlich aufgerufen werden und ob der Ersatz kompatibel, angepasst oder neu gekapselt werden muss. Wo Quellcode nicht vorliegt, ist die Abhängigkeit ausdrücklich als Blackbox zu behandeln.

Taskmodell, Zyklus und Nebenläufigkeit

Steuerungslogik lebt nicht nur von der Reihenfolge im Text, sondern auch davon, wann und in welcher Task sie ausgeführt wird. Änderungen an Taskzuordnung, Zykluszeit, Priorität oder Kommunikationsaktualisierung können Flanken, Timer, Handshakes und Zustandsübergänge beeinflussen. Besonders empfindlich sind gemeinsam genutzte Daten zwischen Tasks und Logik, die implizit eine bestimmte Aufrufreihenfolge voraussetzt.

Die Migration braucht daher ein explizites Laufzeitmodell: Welche Task liest welche Eingänge? Wo werden Befehle gebildet? Wann werden Ausgänge geschrieben? Welche Daten dürfen während eines Zyklus wechseln? Erst mit diesem Modell lassen sich Unterschiede gezielt testen.

Initialisierung, RETAIN und persistente Daten

Startwerte, remanente Variablen und Rezeptdaten tragen oft Maschinenzustand über Neustarts oder Downloads hinweg. Bei einer Migration können sich Layout, Typen oder Initialisierungswege ändern. Ein Projekt kann trotzdem erfolgreich starten, während Zähler, Kalibrierwerte, Betriebsparameter oder Zustandsmerker nicht so übernommen wurden wie beabsichtigt.

Deshalb braucht jede relevante Datenklasse eine bewusste Entscheidung: neu initialisieren, konvertieren, aus gesicherter Quelle übernehmen oder verwerfen. Die Entscheidung gehört in einen wiederholbaren Inbetriebnahmeablauf – nicht in eine spontane Handlung während des ersten Downloads.

I/O, Kommunikation und Bedienung

Gerätebaum und I/O-Mapping bilden die reale Peripherie ab. Adressen, Skalierungen, Ersatzwerte, Byte-Reihenfolge und Diagnosezustände müssen für den neuen Zielaufbau geprüft werden. Dasselbe gilt für Feldbusse, serielle Verbindungen, OPC UA, herstellerspezifische Protokolle und gekoppelte Bedienoberflächen.

Eine robuste Struktur trennt logische Maschinensignale von konkreten Hardwarezugriffen. Wo der Altbestand diese Trennung nicht hat, kann eine Adapterebene die Migration und spätere Tests erleichtern. Sie sollte jedoch nicht gleichzeitig mit einer vollständigen Neustrukturierung der Maschinenlogik eingeführt werden, wenn dadurch die Vergleichbarkeit verloren geht.

Vier Nachweisstufen statt eines großen Abnahmetests

Eine kontrollierte Migration zerlegt die Beweisführung. Jede Stufe hat einen eigenen Zweck und eine klare Grenze.

1. Quellcodeanalyse: Struktur und Risiken verstehen

Die Analyse erfasst Aufrufgraphen, Zustandsautomaten, direkte I/O-Zugriffe, globale Daten, Taskgrenzen, Bibliotheksnutzung und externe Kommunikationspfade. Sie sucht außerdem nach impliziten Voraussetzungen: nicht dokumentierte Wertebereiche, mehrfach beschriebene Variablen, unerwartete Seiteneffekte oder Logik, die nur durch eine bestimmte Zyklusfolge funktioniert.

Das Ergebnis ist ein technisches Modell und eine Liste offener Risiken. Eine Codeanalyse kann Widersprüche und fehlende Trennungen zeigen. Sie kann nicht beweisen, dass die reale Maschine in allen Betriebsarten korrekt reagiert.

2. Reproduzierbarer Build: den Quellstand technisch erzeugbar machen

Zuerst sollte der freigegebene Ausgangsstand, soweit der Bestand es zulässt, aus einer dokumentierten Umgebung erneut erzeugt werden. Danach gilt dasselbe für den migrierten Stand. Festgehalten werden Werkzeugversion, Zieldefinition, Bibliotheksauflösung, Buildmeldungen, Eingangsrevision und erzeugtes Artefakt.

Ein Build ist reproduzierbar, wenn eine definierte Umgebung ohne lokale Zufallsabhängigkeiten zum erwarteten Ergebnis führt. Das kann durch Skripte, dokumentierte Importschritte oder eine kontrollierte Build-Station erreicht werden. Entscheidend ist nicht maximale Automatisierung, sondern Wiederholbarkeit. Der erfolgreich wiederholte Build belegt, dass die erfassten Eingänge in dieser Umgebung zum erwarteten Artefakt führen. Er belegt weder die Vollständigkeit nicht erfasster Laufzeit- oder Variantenbestandteile noch eine korrekte Ablaufreaktion.

3. Logiktests und DryRun: Verhalten unter kontrollierten Eingängen prüfen

Isolierbare Bausteine lassen sich mit definierten Eingangsfolgen, Grenzwerten und erwarteten Zuständen testen. Für zusammenhängende Maschinenabläufe kann ein DryRun sinnvoll sein: reale Hardwarezugriffe werden über eine klar erkennbare Schnittstelle ersetzt, Eingänge werden simuliert und Ausgänge als Befehle beobachtet, ohne Aktoren anzusteuern.

Dabei werden Normalabläufe, Abbrüche, Wiederanlauf, Kommunikationsfehler und unzulässige Reihenfolgen geprüft. Ein DryRun ist nur belastbar, wenn sein Modell und seine Grenzen dokumentiert sind. Er ersetzt weder reale Buslaufzeiten noch elektrische Eigenschaften, mechanische Trägheit, Sensorstreuung oder das Verhalten eines konkreten Antriebs.

4. Reale Maschinenvalidierung: Integration und Physik prüfen

Die Prüfung an der Maschine bleibt eine eigene, geplante Phase. Sie umfasst reale I/O, Kommunikationspartner, Zyklus- und Reaktionszeiten, Betriebsarten, Bedienhandlungen, Störfälle sowie die Wechselwirkung mit Mechanik und Prozess. Umfang und Verantwortung müssen sich am konkreten System und dessen Risikobeurteilung orientieren.

Vor dem Download sollten Sicherung, Rückweg, verantwortliche Personen, sichere Ausgangsstellung, erlaubte Testfälle und Abbruchkriterien feststehen. Ein bestandener DryRun reduziert Suchraum und Überraschungen. Er ist keine Freigabe für den Produktionsbetrieb.

Wichtige TrennungQuellcodeanalyse, reproduzierbarer Build, Logiktest/DryRun und reale Maschinenvalidierung liefern unterschiedliche Evidenz. Keine Stufe sollte mit einer Formulierung dokumentiert werden, die den Aussageumfang der nächsten Stufe vorwegnimmt.

Vergleichbarkeit vor gleichzeitiger Modernisierung schützen

Eine Migration lädt dazu ein, alte Strukturen umfassend zu bereinigen. Technisch kann das sinnvoll sein, erschwert aber den Nachweis: Wenn Laufzeit, Bibliotheken, Hardwarezugriff, Zustandslogik und Datenmodell gleichzeitig wechseln, hat jede Abweichung viele mögliche Ursachen.

Besser ist eine Folge kleinerer, referenzierbarer Schritte. Zuerst wird ein beobachtbarer Ausgangsstand gesichert. Dann werden notwendige Kompatibilitätsänderungen von fachlichen Änderungen getrennt. Strukturverbesserungen folgen dort, wo Tests das Verhalten absichern. Jeder Schritt erhält eine eigene Revision, Build-Evidenz und definierte Prüfergebnisse.

Das bedeutet nicht, schlechten Code unverändert zu konservieren. Es bedeutet, Änderungen so zu schneiden, dass Ursache und Wirkung noch zugeordnet werden können.

Was am Ende einer belastbaren Migrationsphase vorliegen sollte

  • ein referenzierter und gesicherter Ausgangsstand mit dokumentierten Unsicherheiten,
  • eine Bestandsübersicht aus Zielsystem, Laufzeit, Tasks, Geräten und Kommunikation,
  • eine aufgelöste Liste der Bibliotheken und externen Abhängigkeiten,
  • ein dokumentierter Buildweg für Ausgangs- und Zielprojekt,
  • eine Zuordnung notwendiger Konvertierungs- und bewusster Fachänderungen,
  • ausgeführte Logiktests beziehungsweise DryRun-Szenarien mit Ergebnissen und Grenzen,
  • ein abgestimmter Plan für Integration und reale Maschinenvalidierung,
  • sowie ein Rückweg für den Fall, dass die Inbetriebnahme abgebrochen werden muss.

Ob alle Punkte in einem konkreten Projekt erreichbar sind, hängt vom Bestand ab. Gerade bei alten Zielgeräten, fehlenden Bibliotheken oder unklaren Quellständen kann das erste belastbare Ergebnis eine begrenzte Machbarkeitsaussage sein. Diese Grenze ist wertvoller als ein vorschnelles Komplettversprechen.

Wann die Migration bewusst unterbrochen werden sollte

Ein Stopp ist sinnvoll, wenn kein vertrauenswürdiger Ausgangsstand bestimmt werden kann, zentrale Bibliotheken fehlen, die Zielhardware nicht ausreichend abgebildet ist oder sicherheitsrelevante Funktionen ohne abgestimmtes Prüfkonzept verändert würden. Dann ist die nächste Aufgabe nicht „weiter konvertieren“, sondern die offene technische Voraussetzung zu klären.

Genau darin liegt der Unterschied zwischen einer Dateikonvertierung und einer Maschinenmigration: Die Migration behandelt nicht nur Code, sondern ein gekoppeltes System – und macht sichtbar, welche Aussage bereits belegt ist und welche erst an der realen Maschine beantwortet werden kann.

Technischen Fall kurz abgleichen

Wenn der Fall mehrere Disziplinen berührt, spreche ich mit Ihnen direkt über das System.

Der kurze Abgleich dient der Einordnung. Analyse, Log-, Konfigurations-, Daten- oder Quellcodeprüfung beginnen anschließend mit einem klar vereinbarten Auftrag.