Grafische Programmierung

Grafische Programmierung

Inhalt


1 Grafische Programmierung

Topic:.GraphProgr.

Last changed: 2018-12-07

Das Thema der Grafischen Programmierung ist als Alternative oder besser Ergänzung zur Programmierung in den allgemeinen statischen textuellen Sprachen C, C++, Java und C# dargestellt. Nach Meinung des Verfassers hat die textuelle Programmierung dann Nachteile, wenn es um die umfängliche Gesamtheit der Software geht. Für Details ist eine textuelle Programmierung in statischen Programmiersprache, also insbsondere C für Hardwarenähe und Betriebssystem, (zeitlos) passend. Übertragen gilt das auch für Algorithmen, die in Java oder C# sehr gut darstellbar sind.

In Abgrenzung zum hier dargestellten Thema: Die Programmierung in einer bestimmten Anwendungsumgebung, Geräte/Anlagen-Programmierung und dergleichen, wird oft grafisch ausgeführt. Dies sind jedoch aus Sicht dieses Artikels Speziallösungen, für die diese Überlegungen teils zutreffen aber bereits passend gelöst sind.

Als Tool der Grafischen Programmierung wurde Simulink (https://de.mathworks.com/products/simulink.html) ausgewählt, nach guten Praxiserfahrungen. Die in diesem Abschnitt dargestellten Aussagen sind aber auch auf ähnliche Programmiersysteme der Function-Block-Grafik übertragbar. Eine Abgrenzung zu UML-Grafiken ist im Artikel dargestellt.


1.1 Software soll durchschaubar sein für Kunde, Vertrieb, Management

Topic:.GraphProgr.nonObscure.

video: Einführung in Grafische Programierung


Bild: Kunde-Entwicklung Missverständnisse

Auf die Frage meines Vertriebs-Kollegen, was denn im neuen Update so alles geändert wurde, versuche ich zu erklären: Dies, das und jenes. Mein Gegenüber macht große Augen, weil, er versteht nicht wo von ich rede.

Software kommt dem Nicht-Softwerker oft undurchsichtig, obscure, vor. Was ist da drin in der Kiste? "Bitte schreibe konkrete Features auf, die ich dem Kunden weitergeben kann" .... Was habt ihr schon wieder geändert?

Bei einer Anordnung von mechanischen Teilen oder einer Hardware ist das einfacher. Da sieht man was das ist (auch wenn das Detail vielleicht nicht genau durchschaut wird). Geht das bei Software auch?


Bild: Kunde-Entwicklung

Meine Antwort "Ja" auf diese Frage besteht aus zwei Komponenten:

Mit dem zweiten Punkt ist man eigentlich bei der Objektorientierung, die den Blick auf die Daten als primär gegenüber dem Blick auf Abläufe (Programmstrukturen) betont. Eigentlich recht klar für den Informatiker. Interessant wird es aber, die Daten aus einer laufenden Software auf dem PC oder auf einem Gerät sofort darzustellen, visuell, bei laufender Software. Siehe dazu Chapter: 1.7 Inspector-DataViewing Zugriffsrechte.

Der erste Punkt deutet klar auf eine grafische Progarmmierung. Diese ist ein Muss, wenn Software durchschaubar sein soll. Im Folgeabschnitt ist dazu ein Beispiel gegeben. Dabei wird Simulink als Vertreter der Funktionsblock-Darstellungen klar der Vorzug gegeben gegenüber UML.


1.2 Alternativen UML oder Functionblockdarstellung (z.B. mit Simulink)

Topic:.GraphProgr.UMLvsFB.

video: UML oder FB-orientiert


Bild: UML oder FB-orientiert

UML (Unified Modelling Language) ist eine bekannte Herangehensweise der grafischen Programmierung mit etwa 14 Diagrammarten von Use cases über Object-Model-Diagramme (Klassen / Package oder Modulbeziehungen) bis hin zu Zustandsmaschinen in der Ausprägung Statechart. UML-Tools sind verbreitet, gut und wichtig auch für die Softwareentwicklung selbst, aber eventuell nicht hinreichend.

Die Funktionsblock / datenflussorientierte Darstellung gibt es ebenfalls schon eine längere Zeit, Simulink ist eines der Vertreter.

Das Video zeigt, wie mit Simulink-Mitteln doch sehr plastisch Module und ihr Zusammenspiel auf Kundennähe gebracht werden können.

Interessant ist, dass die Statechart-Technik in den 80-gern von David Harel entwickelt und über das Tool Statemate (i-Logix) in die UML-Welt hineingebracht, auch in Simulink präsent ist. An dieser Stelle treffen sich die Toolwelten. Zustandsmaschinen im allgemeinen und die Statecharts mit der guten Darstellung von geschachtelten Zuständen und Parallelitäten mit der Eventverarbeitung sind durchaus ein Bindeglied des Verständnisses der Software bis hin zum Kunden.


1.3 Beispiel mit FB-Darstellung

Topic:.GraphProgr.FB_bsp.

video: Blöcke im Gerät, Kundensicht


Bild: Beispiel Geräte Hauptbild

Wenn Sie ihrem technisch orientierten Vertriebler ein solches Bild präsentieren, dann können Sie die Funktion des Gerätes erklären. Die Sollwerte (RefValue) werden hier über eine Ethernet-Schnittstelle empfangen, das erledigt das gezeigte Modul. Wesentlich hierbei soll sein: Es handelt sich um eine Regelung mit Parameteroptimierung aufgrund Streckenparameter und Test-Stimulation. Es wird also auf den eigentlichen Ausgang etwas aufaddiert, das ist im Bild deutlich sichtbar. Die Parameteroptimierung benötigt die gemessenen Werte. Details lassen sich verbal erklären. Die Frage "Was habt ihr denn schon wieder geändert" ist dann lokalisierbar beantwortbar, beispielsweise "Bugfix bei der Messwertaufbereitung" mit Verweis auf genau dieses Modul.

Zum Umfang eines solchen Modells: In dieser Auflösug sind die Module noch erkennbar. Auf einem Full-HD-Monitor passt etwa 6..8 mal mehr, also ca. 20 Module. Das ist noch überschaubar - wichtig ist die Übersicht und auch Freiflächen. Mit einer Schachtelungstiefe (Submodule) von 4..5 kommt man dann auf eine doch beträchtliche Komplexität, die aber immer noch überschaubar sein sollte. Das ist das Ziel des guten Designs der Grafik.


1.4 Einbeziehung des Kunden in die Modellierung

Topic:.GraphProgr.FB_bsp.

video: Umgebungssimulation mit dem Kunden


Bild: Beispiel Hauptbild

Das Bild zeigt das Main-Diagramm des Beispiels. Typisch ist die Unterteilung in das zu realisierende Softwaremodul Device, die Umgebungssimulation Environment und diverse Mess-Ankopplungen auf dieser Ebene.

Man kann den Kunden direkt einbeziehen, denn er wird seine Umgebung am besten kennen und entweder selbständig zuarbeiten oder mit Ihnen im Detail diskutieren. Es gibt dabei zwei oder drei Arten von Kunden:


1.5 Modularisierung und Objektorientierung

Topic:.GraphProgr.ObjOmodule.

Das Video zeigt die Herangehensweise für den Entwurf der Modulverbindungen entsprechend der Beschreibung in den folgenden Unterabschnitten-

video: TODO Objektorientierte Verbindung der Module

Die Modularisierung der Software ist ein Schlüssel für durchschaubare pflegbare Software - divide et impera gilt wie bei der Römischen Länderverwaltung auch hier. Ein Modul lässt sich funktional vollständig durchschauen, einzeln testen. Der Zwang zur Modularisierung und Schnittstellendefinition führt letzlich zur guten Softwarearchitektur. Mit Blick auf die Gesamtfunktionaltität können die einzelnen Module als Black Box betrachtet werden, die Gesamtheit wird beherrscht.

Simulink unterstützt die modulare Softwarestruktur mit einzelnen FunctionBlocks, die intern wieder eine Substruktur als Teilmodell haben können, referenzierte Subsysteme und Teilmodelle als Modul in Libraries.

Die Modularisierung der Software wird oft mit der Objektorientierung in den Zusammenhang gebracht: Module haben ihre innere Funktionalität mit ihren Daten. Objektorientierung ist die Bindung der Funktionalität an die Daten. 'Zeige mir Deine Daten und ich sage Dir wer du bist' - Aus diesem Leitspruch werden die Daten zu einer Klasse in einem ObjectModelDiagram der UML im mittleren extra Abschnitt gezeigt. Dies ist nicht im Widerspruch zur private-Kapselung der Daten, die compiletechnischer Natur ist und nichts mit 'verbergen' oder 'geheimhalten' der Daten zu tun hat.

Die Objektorientierung lebt von der Referenzierung. Mit einer Referenz auf eine aggregierte oder assoziierte Instanz einer Klasse greift man auf die Instanz zu. Die Referenzierung ist in allen Programmiersprachen kein Thema. Geklärt, funktioniert.

Die Referenzierung steht nun (scheinbar) im Widerspruch zur Datenflussorientierung in Simulink-Modellen. Man kann dies nicht als Widerspruch auffassen sondern auf höherer Ebene verwirklicht sehen: Per Datenfluss wird der Zugang zu den Daten weitergegeben. Die Aggregation in UML-ObjectModelDiagram von der nutzenden zur genutzten Klasse gerichtet wird hier gedreht: Das benutzte Objekt/Modul gibt seine Referenz an das nutzende weiter. Mit diesem Zugangsschlüssel kann dann das nutzende Modul ohne viele Datenverbindungen auf das genutzte in mehreren Funktionalitäten mit ihren Daten zugreifen.

In Chapter: 2.3 Vergleich und Herangehensweise - Datenverbindung mit Bussen oder Referenzen ist diese Herangehensweise hergeleitet und erläutert.

Es verbleibt die Frage: Wie kommt man zu den Referenzen in Simulink. Dazu gibt es zwei Lösungsansätze, die beide mit Kern in C arbeiten:


1.6 Objektorientierung und Inspector-DataViewing

Topic:.GraphProgr.Inspc.

video: Objektorientierung und DataViewing mit Inspector


Bild: Objektorientierung und DataViewing mit Inspector]

Objektorientierung bedeutet im Kern die Bündelung der Daten an ihre Operationen. Eigenschaften wie Vererbung, Ableitung, virtuelle Funktionen, bekannt aus C++, Java &co sind add-ons, die sich aus der Logik ergeben und wünschenswert sind. Es gibt aber diesbezüglich Stimmen, die vor der ausufernde Nutzung von Vererbung warnen und gar mit der "Funktionalen Programmierung" eine neue Zeitära einleiten wollen. Das ist teils berechtigt. Bleiben wir also beim Kern - Bindung der Daten (Objekte) an ihre Operationen in einem Modul.

Damit ist der Zugriff auf die Daten des Moduls, um interne Funktionen zu debuggen, nicht im Schrittbetrieb, sondern anhand des Verlaufs der Daten, verbunden. Dazu sind die im Video gezeigten Datenbündler, der statt Bussen oder Mux im Simulink eingesetzt werden, geeignet. Der Zugriff erfolgt von außen über den Inspector und kann genauso im Zielgerät erfolgen, wenn der Inspector-Zugriffsdienst und die notwendigen Reflection dort ebenfalls implementiert werden.


1.7 Inspector-DataViewing Zugriffsrechte

Topic:.GraphProgr.InspcAcc.

video: DataViewing mit Inspector - Passwortschutz


Bild: DataViewing mit Inspector - Passwortschutz]

Für die Fehlersuche in der Entwicklung ist es wünschenswert, auf alle Daten zugreifen zu können und auch alle Daten modifizieren zu können, wenn sie nicht vom Rechenprozess selbst belegt werden. Man kann dies so ausbauen, dass spezielle Testfunktionen mit vorgesehenen Variablen freigeschaltet werden oder Parameter bis an Grenzen verstellt werden können. Das ist aber mit dem Background des Entwicklungstests oder einer diffizilen Fehlersuche am Zielgerät unter Kundenbedingungen, aber vom Spezialisten, gedacht. Der Datenzugriff über den Inspector ist andererseits tauglich auch für eine Kundenwartung oder als universelles Parametrierungstool. Folglich muss mit Zugriffschutz (Passwort) gearbeitet werden. Eine Endauslieferung ohne bestimmte Zugriffsmöglichkeiten bedeutet neben dem Zusatzaufwand, dass im Ernstfall der unvorhergesehenen Servicemaßnahme die Zugriffsmöglichkeiten nicht verfügbar sind.

Das Video und Bild zeigt, wie der Passwortschutz im Modell ausgedrückt werden kann: Der Eingang bekommt einfach ein Passwort-Level von 0 bis 7. Der Kunde kann dies nicht ändern, auch wenn er über das Simulink-Modell selbst verfügt, dazu müsste er noch die Zielsoftware erstellen und selbst implementieren. Nicht das Passwort selbst sondern das Level wird im Modell eingegeben. Die Passwortverwaltung mit Schlüssel in jedem Inspector-Telegramm ist nach den üblichen Algorithmen eingebaut und im Zielsystem in der Hand der Entwicklung.


1.8 Simulink und / oder C ?

Topic:.GraphProgr.Smlk_C.

video: Simulink und / oder C


Bild: Simulink und C]

Die grafische Programmierung - mit Simulink - wird deshalb hier favorisiert, weil es nur so gelingt, Komplexitäten zu beherrschen und eine Einheit von Dokumentation, Kunden-Gesprächen und tatsächlicher Software herzustellen. Die Implementierung ist und bleibt aber dennoch C. Vereint wird dies durch zwei Ansätze:

An Stellen, an denen keine Komplexität vorherrscht und auch nicht engmaschig Algorithmen mit dem Kunden abgestimmt werden, können Sie weiterhin direkt in C arbeiten. Die Verständlichkeit der Software leidet damit nicht, denn C ist einfach lesbar, oft sind es mathematische Gleichungen. Insbesondere auf Treiber-, Betriebssystem- und Hardwareebene ist C direkt besser. Nur wenn diese Schicht Ihnen jemand abnimmt, er für Sie die Hardwareanpassung realisiert, können Sie C vergessen. Das wäre allerdings dann der Fall, wenn etwa der Kunde Anpassungen im Gerät selbst vornimmt ('Projektierung des Gerätes'), direkt im Modell oder in einem übergeordneten Teilmodell.


1.9 Softwaremodularität und Refactoring

Topic:.GraphProgr.ObjOCon.

video: Grafisches Moduldesign und Refactoring der Software


Bild: Grafische Programmierung und Refactoring]

Der intene Aufbau der Software auf den äußeren Schalen ist mit der grafischen Programmierung geöffnet. Die Softwarestruktur muss mit der Grafik übereinstimmen, Codegenerierung aus dem Modell ist selbstverständlich.

Damit entsteht eine starke Verbindung der Software mit der Dokumentation. In der zeilenorientierten Programmierung gibt es diese Verbindung nicht wirklich. Die Struktur der Software muss von daher schon gut durchdacht sein. Softwarestrukturierungen entstehen nur in der Theorie Top-Down aus einem durchdachten Design hin zur Implementierung. In der Praxis - auch ohne das Paradigma der Agilität, wird in Details nachgebessert bis es in der modularen Struktur der Software kracht und knirscht. Der Entwickler ist nun schon wegen des eignenen Durchblicks zum Refactoring geneigt. Für das Management erscheint das oft nur als 'Kostenfaktor'.

Die grafische Programmierung hilft hier ungemein, da die Modulstruktur sichtbar ist und dessen Zweckmäßigkeit offen liegt.

Die Details der Programmierung, Treiberebene, Hardwareschnittstellen etc. sind die Teile in denen sich oft Know-how verbirgt und die nicht offengelegt werden sollen. An diesen Stellen ist man aber oft schon 'unten' in der Modularität, klar strukturiert, keine komplexen Abhängigkeiten. Hier gibt es zumeist nicht wirklich Probleme. Diese Teile sind also auch leicht aus der grafischen Darstellung herauslösbar. Probleme existieren im Mittelteil der Module. Diese geschickt zu schneiden wird mit der Grafik überschaubar.


1.10 Automatische Codegenerierung und Einbindung handprogrammierter C(++) codes

Topic:.GraphProgr..

Nutzt man die grafische Programmierung einschließlich Simulation dann ist es ein Zusatzaufwand, wenn die gefundenen Module und Relationen danach manuell in C programmiert werden müssen. Mehr noch, bei Diskussionen an der Grafik, deren Änderung mit Simulationstest muss danach die entsprechende Stelle im C-Code gefunden werden, um auch in der Zielsoftware nachzubessern. Dort hat aber der Programmier vielleicht schon einen Detailfehler korrigiert, der so nicht im Modell sichtbar war. Das Modul und der C-Code sind schon auseinandergelaufen. Diese Divergenz wird sich fortsetzen und zum Projektabschluss wird dann aus Zeitgründen nur noch im Code gefixt. So das Negativscenario.

Konsequent ist daher mit der Grafischen Programmierung immer auch die automatische Codegenerierung aus der Grafik verbunden. Dies wird von Simulink seit Jahren (Jahrzehnten) mit guter Erfahrung unterstützt, auch von anderen grafischen Entwicklungsumgebungen. Aus dieser Jahrzehnte-Erfahrung heraus müsste man meinen, niemand programmiert noch per Hand (außer Systemprogrammierer und Nerds). Das ist aber nicht so. Woran liegt das?


Bild: Knopfdruck-Anspruch

Damit gibt sich eine Diskrepanz. Eine große Personengruppe akzeptiert nur die eigenen manuell programmierten Zeilen. Eine andere Personengruppe möchte aus Grafik generieren, betreibt dies erfolgreich schon seit Jahren und versteht nicht die fehlende Akzeptanz.

Das Bild rechts zeigt Praxis und Anspruch der zweiten Gruppe: Es geht per Knopfdruck aus dem Grafiktool direkt ins Zielsystem. Dieser Anspruch funktioniert, wenn es sich um eine vorbereitete bekannte Umgebung handelt. Es hat sich jemand um die Details gekümmert.


Bild: Kein Knopfdruck-Anspruch

Dieses Bild ist eine Erweiterung des Knopfdruckanspruches und öffnet die Dinge die dahinterstehen:

Für den Endanwender, Projektierer, nur grafisch arbeitenden Funktionsdesigner gibt es auch hier den Knopfdruchanspruch. Der graue Bereich, die Aura des C/++-Developer, ist nicht notwendig wenn alles läuft. Die eigentlich zwei Schritte, Codegenerierung aus dem Modell und Compilierung für das Zielsystem, lassen sich zu einem Knopfdruck vereinen, besser noch zu einem Script das nachvollziehbar die Generierung aus gespeicherten Files in einer Softwarerevisionsverwaltung, ausführt.

Ist das Zielsystem ein eigenes, nicht ein Standardsystem, dann muss irgendjemand die Anpassung vornehmen und auf Änderung reagieren. Das ist der C/++-Entwickler. Er kennt die Compilertools und hat sich mit den Einstellungen der Codegenerierung vertraut gemacht. Er erkennt, wenn etwas im Modell ungünstig für die Implementierung designed ist. Er kann auf Lo-Level-C-Code oder maschinennahe auch mit dem generierten Code testen.

Genau genommen arbeitet der C/++-Entwickler wie bisher. Nur das ihm die Arbeit des Nachcodierens des Modells abgenommen wird, dafür muss er sich aber mit der Erscheinungsform des generierten Codes 'herumschlagen', muss diese kennen und aktzeptieren. Spätestens nach der zweiten Änderung im Modell wird er aber nicht mehr kritisch jede Zeile beäugen sondern wird grob darüberschauen ob eine ungünstige Rechenzeitkonstellation hinzugekommen ist oder dergleichen und dort keine Detailarbeit hineinstecken. Er wird am Modell mitarbeiten.

Nun ist die Basis bereitet für eine gute Zusammenarbeit:

Der Gesamt-Software-Test wird auf drei Ebenen ausgeführt:

Auf dieser dritten Ebene, Zielcode-Test am PC, kann dann auch sehr gut die Codeoptimalität begutachtet werden. Möglicherweise muss man Optionen der Codegenerierung anders einstellen, möglicherweise muss man bestimmte Styleguides der Modellierung beachten und entwickeln.


1.11 Objektorientierung und Wiedererkennung in Modell und Zielcode

Topic:.GraphProgr.ObjOCodeGen.

Der Zielcode ist vielfältig wenn das Modell umfangreich ist. Von Simulink ausgehend, die Mathwork-Tools bieten Hilfen um vom Modell zum Code und umgekehrt zu navigieren (Hyperlinks in zusätzlich generierten Html-Dokufiles, Comments im Code). Es ist aber nicht trivial und einfach.

Benutzt man im Modell die Datastruct_Inspc-Daten-FBlocks wie sie insgesamt in Chapter: 2 Objektorientierung und Handleverbindungen im Modell - Details dargestellt sind, dann werden Datenstrukturen in eigenen Headerfiles so angelegt, wie sie in diesen FBlocks in den Parametrierungen festgelegt sind. Diese struct-Definitionen sind in der jeweiligen Form sichtbar

Hier spielt also der Objektorientierte Gedanke eine wichtige Rolle. Zu den Modulen gehören Daten. Über die Daten werden dann die Verarbeitungsfunktionen sowohl im Modell als auch im Code gefunden.

Der zweite Wiedererkennungswert zwischen Modell und Code sind die SFunctionBlocks, die direkt in C/++ geschriebene Module einbinden. Zum FBlock im Modell gibt es den Aufruf der entsprechenden C/++-Operations im Zielcode, über inline optimiert.

Die Objektorientierung im Modell hat also neben den Wert der Rechenzeitersparnis (wegen geparter Datenweiterreichungs-Codes) den hohen Wert der Wiedererkennung.

Die Eigenständigkeit des generierten Zielcodes neben dem Modell hat zwei Bewandnisse:


1.12 Generierung der S-Funktionen aus Informationen in Headerfiles

Topic:.Smlk_de.C_ObjO.genSfH.

Mathworks-Simulink bietet für die Erstellung von S-Funktionen, also Aufrufe von C-Anteilen im Simulink, 3 Wege an:

Der letzte Punkt bietet alle Möglichkeiten. Das sind sehr viele, beispielsweise die Nutzung dynamischer (vom Modell bestimmter) Port-Eigenschaften, mehrere Abtastzeiten in einem Block, beliebige Parameter. Das manuelle Erstellen ist aber aufwändig. Insbesondere bei vielen kleinen S-Funktionen ist das erheblich.


Bild: Generierung Sfunction-Wrapper

Daher hat der Verfasser einen Generator erstellt, der S-Funktion-Wrapper und tlc-File aus Zusatzinformationen im Headerfile erstellt. Das dazu nötige Script kann mehrere Headerfiles verarbeiten und damit eine Vielzahl meist kleiner S-Funktionen erstellen ('Kerne in C') und muss nicht angepasst werden, wenn sich Operationen im Header ändern. Der Generator arbeitet wie folgt:

Die Tools zum Generieren sind Open-Source, nicht aber die genannten Script-Files. Diese enthalten wesentliches Knowhow der S-Funktion-Technik des Mathworks-Simulink und schon von daher notwendigerweise geschützt. Mit vorhandener Simulink-Lizenz und entsprechender Anfangsbetreuung können diese Scripts dann vom Kunden genutzt und auch angepasst werden.

mailto: simulink@vishia.org

Folgendes pdf-Handbuch erläutert die Anwendung dieser Technik:

www.vishia.org/smlk/SmlkOOguide-de.pdf Handbuch für die Einbindung von C über Sfunction in Simulink mit vishia-Sfunction-Generator, Objektorientierung in Simulink.


2 Objektorientierung und Handleverbindungen im Modell - Details

Topic:.HdlPtrObjO.

Last changed: 2018-12-07

Das hier beschriebene Thema wird mit Simulink dargestellt. Es ist aber verallgemeinerbar auch auf andere Grafische Function-Block Programmierumgebungen, die mit C/++ oder Java/C# zusammenarbeiten.


2.1 Objektorientierung bei der Modellierung

Topic:.HdlPtrObjO.ObjOCon.

Bei der Modellierung mit Simulink spielt die Objektorientierung oft keine Rolle. Die Modelle sind datenflussorientiert. Damit, so könnte man meinen, sind sie sogar moderner: Es gibt eine Tendenz der Abkehr von der Objektorientierung hin zur Funktionalen Programmierung, die ebenfalls die Sicht hin zur Eingabe/Verarbeitung/Ausgabe der Daten lenkt. Die Wahrheit liegt aber wie oft eher in der Mitte. In der Softwaretechnologie hat die Objektorientierung als Herangehensweise ihren festen Platz. Kritik an der Objektorientierung und Hinweis auf die Vorteile der Funktionalen Programmierung ist teils angebracht bei der Anwendungspraxis. Soweit zur Einordnung der drei Paradigmen Objektorientierung, Funktionale Programmierung und Datenflussdarstellung.

Module enthalten mit grafischen Mitteln gezeichnet eine Reihe von Signalen, die in einem anderen Modul als Eingang möglicherweise verwendet werden sollen. Wenn man diese alle als Einzelsignale herüberführt, dann entsteht das Chaos der Verbindungslinien. Man kann im Tool Simulink Signale entweder als Bus oder als Kabelbünder (Multiplexer) zusammenführen. Dann kann aber schnell der Überblick verlorengehen, welche Sigbnale dies sind.

Die Objektorientierte Herangehensweise bündelt in den objektorientierten Sprachen Daten mit ihren Operationen (in der Theorie 'Methoden' genannt). Auf die grafische Programmierung angewendet ist ein Modul eine (komplexe) Operation, und die Daten des Moduls sollen gebündelt werden. Dazu sind die Busse in Simulink bedingt geeignet.

Der Verfasser hat mit Blick auf Datenstrukturen auch in der Realisierungsebene und dem Zugriff auf die Daten auch im Zielsystem ein Set von Sfunctions als Simulink-Function-Block (FB) entwickelt, die sowohl Daten zusammenfassen, als auch diese Zusammenfassung im Zielsystem beibehalten und mit einem sogenannten 'Inspector' sowohl im Simulink als auch auf dem Zielsystem zugriffsfähig halten.


2.2 Handle und Pointer/Referenzen in Simulink

Topic:.HdlPtrObjO..

video: Handle und Pointer in Simulink (Länge 24 min)


Bild: Handle und Pointer in Simulink]

Die Objektorientierung in Simulink, eingeführt mit den S-Function Blocks DataStruct_Inspc und Out_DataStruct_Inspc und mit der Verwendung von C über Sfunctions verwendet Handle oder Pointer zum Datenaustausch, so wie es in der Implementierungsebene, in Objektorientierten Sprachen wie C++ oder Java und in C üblich ist. Dem entgegen steht die traditionelle Orientierung auf kopierende Weitergabe der Daten, die sicherer scheint aber jedenfalls an einigen Stellen auch Zeitaufwände im Ablauf im Zielsystem mit sich bringt und an sich nicht notwendig ist. Die Verwendung von Referenzen ist von sich aus sicher. Ein Problem mit Pointern gibt es nur bei Programmierfehlern, die in C und C++ nicht sicher abgefangen werden. Hier im Simulink werden sie abgefangen. Ein sicherer Typtest erfolgt zur Startup-time beim Modelltest. Ähnlich wie in Java sind dafür alle Datenobjekte von einer gemeinsamen Basisklasse abgeleitet die den Typtest unterstützt: ObjectJc (adäquat java.lang.Object). Das obige Video nennt diese Dinge ohne Blick auf den C-Code.

Das folgende Video zeigt, wie dies im Wrapper der Sfunction in C programmiert ist:

video: Handle und Pointer in Simulink (Länge 27 min)

Dieses Video zeigt im Detail, wie Visual Studio ab 2015 mit 'Attache to process' mit Mathworks/Simulink zusammenarbeitet und im einzelnen debuggt werden kann.


2.3 Vergleich und Herangehensweise - Datenverbindung mit Bussen oder Referenzen

Topic:.HdlPtrObjO..

Traditionell ist Simulink datenflussorientiert, Daten werden transportiert, nicht referenziert. Man kann zusammengehörige Daten in Bussen zusammenfassen.


Bild: Zwei Module]

Das Bild zeigt zwei Module. Die Modularität ist außerhalb der Diskussion über Objektorientierung und Datenfluss ein unangefochtenes Paradigma. Aber die Aufteilung der Funktionalitäten zu den Modulen wird von diffizilen Entscheidungen geprägt:


Bild: M_A Innenmodell als Submodul]

Im Inneren des Moduls M_A befindet sich eine Teilschaltung, die mit einem Signal des M_B arbeitet. Verantwortlich für die Teilschaltung ist Module M_A, dies soll so bleiben. Es soll aber aus diesem Teilmodell ein Submodul gebildet werden dass dann im M_B eingesetzt wird. Grund für diese Intension: Das Inputsignal von M_B zu dieser Teilschaltung soll nicht als Modulschnittstelle aufgenommen werden. Die Bildung dieses Signals soll eigenständig im M_B bearbeitet werden, ohne die Modulschnittstelle zu beeinflussen.

Es ist aber auch entschieden, dass die Speicher für die Daten, die Unit-Delay-FB im M_A verbleiben sollen, aus Gründen des Zusammenhalts von Daten. Solche Entscheidungen können auch getroffen werden, ohne an die Objektorientierung zu denken. Beispielsweise soll offengehalten werden ob in der Weiterbearbeitung im M_A die Signale beispielsweise mit einer Reset-Logik versehen werden oder ähnliches.


2.3.1 Busverbindung aus einem Modul M_A zu einer Operation zugehörig zu M_A in einem anderen Modul

Topic:.HdlPtrObjO...


Bild: Submodul im M_B]

Das Bild zeigt nun das Ausführungsergebnis: Das ehemalige Innenmodell ist in einem anderen Submodul M_B_2 untergebracht. Es ist nun eine Verbindung für den Daten-Rückfluss notwendig.


Bild: Submodul im M_B_2 enthält M_A_operation über Busverbindung

Sieht man dies durch die Objektorientierte Brille, dann ist M_A_data nun das datenhaltende Modul aus M_A. Das fremde Modul M_B enthält in seinem Inneren eine Operation, die zu M_A gehört. Ohne Objektorientierte Sicht ist dies das Ergebnis der Überlegung, dass eine Datenverarbeitung von Daten aus M_A innerhalb eines anderen M_B_2 stattfinden soll. Objektorientierung kommt damit ins Spiel, dass die Daten trotz Verarbeitung in M_B dennoch in M_A in den UnitDelays gehalten (gespeichert) werden sollen. Das ist der Kerngedanke der Objektorientierung: Bündelung von Daten, relativ unabhängige Operationen ('Methoden') mit den Daten. Die Operationen oder 'Methoden' gehören zu den Daten. Ohne Objektorientierung ist der Treiber die Verantwortung für die Datenverarbeitung, die zum Modul M_A bzw. zu dessen Library gehört, dass eventuell ein Wiederverwendungskandidat ist. Die Objektorientierung formuliert dies nur systematischer.


Bild: M_A_operation mit Busverbindung

Das rechtsstehende Bild zeigt die eigentliche M_A_Operation, die zum Modul bzw. zur Library M_A gehört aber in M_B verwendet wird.

Die Lösung ist aber insgesamt wegen der Rückverbindung nicht sehr elegant. Diese ist als Bus ausgeführt schon noch übersichtlich. Jedoch muss bedacht werden, dass dies ein einfaches Beispiel ist. Gibt es mehreren M_A_operationXY in verschiedenen Modulumgebungen, dann braucht es jeweils angepasst Teil-Busse mit Rückschreibe-Daten nach A. Die Datenlieferung (MA_data) kann jedoch als ein Bus ausgeführt werden, aus denen sich das jeweils nutzende Modul die passenden Daten herauszieht.


2.3.2 Alternative: Referenzierung

Topic:.HdlPtrObjO...

In der Objektorientierung und in der gesamten ablauforientierten Datenverarbeitung spielen referenzierte Daten eine sehr große Rolle. Daten werden im Maschinencode eigentlich immer referenziert, auch lokale Variable stehen, wenn die Prozessorregister nicht ausreichen, referenziert über das SP-Register im Stack.

In C gibt es die 'Pointer' mit einem schlechten Ruf. Pointer sind Referenzen: Die Verwendung von Referenzen ist von sich aus sicher. Ein Problem gibt es nur bei Programmierfehlern, die in C und C++ nicht sicher abgefangen werden. Hier im Simulink werden sie abgefangen. Ein sicherer Typtest erfolgt zur Startup-time beim Modelltest. Ähnlich wie in Java sind dafür alle Datenobjekte von einer gemeinsamen Basisklasse abgeleitet die den Typtest unterstützt: ObjectJc (adäquat java.lang.Object).

Referenzen können in Simulink über S-Functions gebildet werden. Sie passen in eine uint32-Variable, wenn sie in einem 64-bit-System als Handle gehandelt werden und über passende Mechanismen intern in die notwendige 64-bit-Speicheradresse umgesetzt werden. Für ein 32-bit-Zielsystem reicht dann das unit32-Format als Adresse direkt. Dies ist kein numerischer Wert, sondern ein Wert, der nur weitergereicht wird. Im Simulink erfolgt eine Eingangskontrolle der Speicheradresse. Ähnlich wie in Java wird zur Startup-Zeit oder auch zur Laufzeit bei wechselnden Adressen die Richtigkeit des Typs getestet. Das ist in TODO näher ausgeführt.


Bild: Referenz- (Handle-) Verbindung der Module

Das Bild zeigt die gleiche Funktionalität wie Bild 'Submodul im M_B'. Der Rück-Bus ist entfallen, die Modulverbindung ist nicht mehr mit einem Bus ausgeführt sondern mit einer Handleverbindung.

Nach dem Datenfluss-Paradigma, dass den FBlock-Darstellungen im Simulink eigen ist, ist folgende Interpretation zulässig: Modul M_A liefert als Datenfluss die Referenz der Daten aus M_A dem nutzenden Modul M_B. Innerhalb des M_B kann dann mit den Daten gearbeitet werden.


Bild: Submodul im M_B_2 enthält M_A_operation über Handle-Referenz

Das Bild ist das adäquate Bild wie im Vorabschnitt, nur das hier das Handle die Verbindung darstellt und der Rückdatenfluss-Bus entfällt. Es ist nun die Eingenschaft des M_A_operation als Operation auf die Daten MA_data gut zu erkennen. Die MA-Data werden als 'this'-Referenz geliefert, weitere Ein- und mögliche Ausgänge stellen die weiteren Schnittstellen der Operation dar. Die Operation enthält keine eigene Datenhaltung, also keine Unit-Delay oder dergleichen. Damit ist auch die Charakteristik für den Ablauf im Zielsystem (des Zielsystem-Machinen- oder C-Codes) abschätzbar.


Bild: M_A_operation mit Handleverbindung

Das entspricht dem Folgebild im Vorabschnitt, das Innenmodell des M_A_operation. Statt dem BusSelektor und dem BusCreator sind zwei Sfunctions für den Datenabgriff und das Datensetzen verwendet. Das sind allgemeine Module aus der lib_Inspc die mit den Variablen parametriert wurden, keine direkt in C zu schreibenden und selbst zu erstellenden Sfunction. Damit sind dies sogenannten getter und setter als direkten Zugriff auf die Daten. Es werden aus den Gesamtdaten des Modul M_A aber nur diese Teildaten gesetzt, ohne dass ein extra Aufwand (der Rückdatenfluss-Bus) notwendig ist.

Man kann an diesen Stellen auch manuell geschriebenen C-Code einbinden, beispielsweise um betriebsspezifische Datenkonsistenzoperationen einzubinden. Ein allgemeiner Datenkonsistenzansatz, die Verwendung eines Wechselpuffermechanismus wie er an solchen Stellen oft üblich ist, dann von entsprechend spezialisierten allgemeinen Modulen aus lib_Inspc erwartet werden.


3 SFBlocks for objectoriented connection of modules

Topic:.Smlk_Inspc.FB_ObjOConn.

Last changed: 2018-11-14

ObjectOrientation as such means, bundling of data to their operations. For Simulink FBs (Function Blocks) it means, any FBlock, or Module, has its specific data. The assembled data of a FBlock or Module can be presented and forwarded with the simulink standard equipment via a mux (Multiplexer) or via a bus. But how it is with set-operations. Show the right image:


Bild: Two modules bus-connected In this image two modules are connected. One of them should hold the data, the other is a operation which works with that data. That should be the approach of the software structure, that is Object Oriented.

But to rewrite to the data inside the operation a second connection is needed, from the operation, which changes the data, back to the Module which holds the data. That is data flow, the original paradigm of Simulink.


Bild: data module for bus connection

It may be additional confuse-able: The Module which holds the data holds it in unit delays. One per data word. That is data-flow oriented. They are several data. Of course for vectorized data one unit delay is only necessary.

Yet the designer of the model could come to the idea to assemble the unit delay in the 'operation' module, because the new data are calculated there, it is more simple. It is data-flow-oriented. But now the architecture of the software is disturbed, no more separation between data and the operation, no more assemble all data in one module. The data-separation approach may be done for any other reason, not for the details here. It is not possible to enforce it because the data-flow-orientation is petty from this view.


Bild: two modules handle (reference)-connected

Now the two modules are connected via a handle which is a reference to the data. Now it is ObjectOriented.


Bild: data module for reference connection

The module which holds the data has a centralized Function Block of type lib_Inspc/DataStructMng_Inspc which is contained in the lib_Inspc. It can hold up to 6 data elements which any number of array size, and it can cacaded with some more such FBlock to one data struct.


Bild: operation module for reference connection

The operation should rewrite the data. How to do it without a back-connection (data-flow thinking). Of course, it is possible with a set-Operation. That are the two right FBs which accesses the data. The access FBs of type get/set_DataStruct_Inspc know the data via the handle input.

Code generation support:

For code generation (Simulink embedded coder) both FBs produces a typename.h Headerfile in its runtime which presents the connected and parametrized values in a struct with access operations (getter, setter). The tlc-File to control the target language compiler for the Simulink coder takes special run-time-parameter, which are produces too on runtime of the FBs. So the generated code is optimized for access to the bundled data depending of the model-specific properties of the instances in the model.

Access to the data via inspector:

Last not least there is a FBlock Service_Inspc and one or more tools to access the data. The Service can also run in the target system, the data are bundled ObjectOriented there too. It is data viewing, which is an important medium to explore and evaluate the software in runtime.


3.1 Application notes of the DataStruct_Inspc FBlock family

Topic:.Smlk_Inspc.FB_ObjOConn.appl.

Last changed: 2018-11-14

The FBlocks to build and access Data are arranged in the Library lib_Inspc.skx because a substantial feature is the assignability to data with the Inspector Service.


3.1.1 example with two cascaded ''DataStruct_Inspc'' FBlocks and one ''get_DataStruct_Inspc'' FBlock

Topic:.Smlk_Inspc.FB_ObjOConn.appl.exmpl.


Bild: Application example

The FBlock with 'M' named thiz is the DataStructMng_Inspc from the lib_Inspc.slx. The first 4 Inputs are connected from several signals inside this module. The types of the signals can be different. In this image the types are visible (Display - Signals and Ports - Port Data Types) is switched on to demonstrate it.

The output of this FBlock is a handle as uint32-type. It is named thiz because it presents this data for the module, adquate to usage of this in C++. It is named thiz to prevent name clashes for C++ target code generation. The handle is converted to a pointer to the data in the using Sfunctions, for target code the handle presents the 32-bit-memory address of the data immediately and optimized.

The second FBlock with 'i' is a cascade with a Init_DataStruct_Inspc SFB from the lib_Inspc. It is especially used for the initial wiring of Blocks and modules: In ObjectOrientation associations and aggregations are need. That are references to other Objects. Aggregations are connected in the startup phase, and after them they are fix. Associations can be switched on runtime. That is the wording of UML. The Tinit step (or sample-) time is the one where initial wiring for aggregations are done. It is support by this FBlock: The special feature is: The types of the input references are checked. It is a typecheck on startup time in this module, independent of this feature the types are checked in the using Blocks again. The typecheck here helps to detect model errors local in the module.

The FBlock f_Y12 is an instance of get_DataStruct_Inspc. It uses the thiz output via Goto-From-data connection. This FBlock is used to access a value from the DataStructMng_Inspc thiz. Its output is named f_Y12_z because it is the value from the last step time. It acts as unit delay. The DataStructMng_Inspc writes the data in the mdlUpdate routine as last action of the step time, so the access is done to the value from the previous step time. With them a numeric loop is prevented, and the delayed f_Y12_z can be used to calculate the new value of this signal with the shown += operation. That is an integrator function.

The get_DataStruct_Inspc accesses the data from the last step time in any case. The combination of this with the DataStructMng_Inspc and a DataStruct_Inspc for cascade acts as unit delay. That is important to exactly implement the integration of differential equations and to prevent data consistent conflicts.


3.1.2 Parameter of FBlock ''get_DataStruct_Inspc''

Topic:.Smlk_Inspc.FB_ObjOConn.appl.get_DataStructPar.


Bild: Parameter of FBs

The get_DataStruct_Inspc can get and output the stored data in any step/sample time.


3.1.3 Parameter of FBlock ''DataStructMng_Inspc''

Topic:.Smlk_Inspc.FB_ObjOConn.appl.DataStructMngPar.


Bild: Parameter of FBs

The DataStructMng_Inspc has the following parameter:


3.1.4 Parameter of FBlock ''DataStruct_Inspc'' and ''InitDataStruct_Inspc

Topic:.Smlk_Inspc.FB_ObjOConn.appl.DataStructPar.


Bild: Parameter of FBs

Both FBlocks have a similar Parameter Dialog. The InitDataStruct_Inspc has additional features, therefore it is shown here.

The FBlock InitDataStruct_Inspc transfers numeric initial values or references in the Tinit step time. The DataStruct_Inspc does the same as dataStructMng_Inspc with the data. Both build a a cascade with the DataStructMng_Inspc as common last member. The last one holds the data, writes the header etc.


3.2 The ''set_DataStruct_Inspc'' FBlock and its Parameter

Topic:.Smlk_Inspc.FB_ObjOConn.set_DataStructPar.

Last changed: 2018-11-14

Like shown in Chapter: 3.1.3 Parameter of FBlock ''DataStructMng_Inspc'' the DataStructMng_Inspc and DataStruct_Inspc can define a variable but set only with an initial value. The name parameter should be written in {...}. The value can be set with a set_dataStruct_Mng. This possibility should be discussed under the Object Oriented aspect:


Bild: Application of set_DataStruct_Inspc

The image right shows a set_DataStruct_Inspc FBlock for the signals tunefY12. This signal is build in the controller and set set into the data of the module parOptimizer. From view of the parOptimizer it is an input for a optimizing process. The parOptimizer determines the meaning of this input. The controller should deliver the proper signal.


Bild: two variantes of get...

This image shows an experience model detail from the parOptimizer. The first variant is: Existing output values of the controller are used and combined. If the controller has the proper public data values, it is ok. In this case the parOptimizer should know which values are proper from the controler to work, it should have knowledge about the functionality of the controller. The controller does not need any knowledge about the parOptimizer.

The alternative is: The own value tune_fY12 is used which is set in the controller. In this case the controller should determine the algorithm to tune the factor f_Y12. The module parOptimizer is only the execution instance. The controller should know which values are proper for the input to the parOptimizer. The controler should know something about the parOptimizer, but only on its given interface. The parOptimizer should nothing know about the controller. It gets the input and works with them, no more.

Which knowledge relation is better for the design, that is a decision of the cooperation between the modules, a design or architecture decision, not a model decision. For the modelling, both decisions are equate.

The design or architecture desicision is shaped by considerations about changing of some details of the moduls, about responsibilities or such considerations.


Bild: Parameter of FBlock set_DataStruct_Inspc

The parameter are similar the get_DataStruct_Inspc.


3.3 Tree of DataStructMng_Inspc for nested modules

Topic:.Smlk_Inspc.FB_ObjOConn.tree.

Last changed: 2018-11-02

If you have submodules in modules, any submodule may/should have its DataStructMng_Inspc FBlock which presents the module data.

In the superior module the handle of the submodules are connected to the DataStructMng_Inspc of this module. The next image show that:


Bild: treed module references

You see a snippet of a modulare structure. Some modules have its thiz output. They are connected to a 'goto' FBlock, a corresponding 'from' FBlock is the source for an input of DataStructMng_Inspc. Usage goto/from is a proper design style to prevent too much lines for regular connections.

The inputs which comes from the submodules, repspectively all inputs which are handles (from in C written Sfunctions too are marked with * before the name. It is semantically known from the pointer access in C-language. Here it means, the input is not a simple uint32, it should be recognized as handle.

You can access from outside to a deeper level in a module/submodule with the Out_DataStruct_Inspc FBlock with writing a path separated by a dot:


Bild: Access path to a submodule

From view of the model it is similar a 'from' from a global 'goto': It is a stand alone FBlock with a textual given source. But global goto/from can be seen as nuisance for modularization. The source of this block is systematically.

From view of ObjectOriented access it is an access to an inner class (concatenated associations) whereby the inner class is gotten via its direct reference, not with a get-method. It is quite usual in ObjectOrientation. It saves access routines respecitively ports and lines in the model.


3.4 Connection and Access via Inspector Service

Topic:.Smlk_Inspc.FB_ObjOConn.inspc.

Last changed: 2018-11-02

The Inspector Service cann access all data which are based on ObjectJc, and all data which's reflection are known beside its struct definition. The DataStructMng_Inspc is based on ObjectJc. The reflection of DataStructMng_Inspc are created dynamically depending of the model and connected signals.

You only need connect the most superior DataStructMng_Inspc to the Inspector Service. All submodules are successfully connected if you build a tree of DataStructMng_Inspc proper to the tree of module structure.

The image shows the connection:


Bild: Connection to Inspc Service

A add_DataNode_Inspc FBlock is used. That FBlock contains an argument for the name of the DataStructMng_Inspc data struct for the access. For the inspector service concept see Chapter: 3.4 Connection and Access via Inspector Service.


Bild: Fiels of fist level In this constellation you can open the Inspector-Tool and view fields of the first level. You see:

More aggregations (modules) are existing if more as one are registered via add_DataNode_Inspc, for example parts or the whole simulation environment.


Bild: Fiels of second level

If you click into myDevice you see the modules and signals of the device of the first level according to the DataStructMng_Inspc FBlock and the deeper levels:


Bild: Fiels of second level

If you have the access password:


Bild: password diaglog

The passwords are hard coded in the standard implementation of the Inspector GUI and the emc access sources:

If you use the Inspector and a target system for a customer, you should implement the necessary special password protection.


Bild: developer access You see more fields, especially 'super' via super.thiz1 you can access internas of the FBlock to view its implementation, as developer access:


Bild: developer access

This shows data, which are gathered from the simulink model on startup of the simulation: TstepMin = minimum of step times of all inputs, here 0.0001 s, index of the ports etc.


3.5 Code generation contribution for Simulink Embedded Coder

Topic:.Smlk_Inspc.FB_ObjOConn..

Some manually adapted tlc files are contained in .../lib/+mkSfn/tlc_src/*.tlc and copied from there with the mex compilation to the adequate mex/tlc_c directory. The automatic generated tlc files are stored as .../lib/+genSfn/Inspc/*.tlc

There are two contributions:

1) Headerfile and C-file from DataStructMng_Inspc-instances:

The type and parametrized name constellation of an instance in the model is generated to an headerfile. The directory path to store that file is given with the filedir - gensrc parameter. The file looks like (part):

typdef struct ParameterOptimizer_ProgrSimple_t {

 ObjectJc* par_PID;

 float f_Y12;

 float Ystim[2];

 char16 checkEn;
} ParameterOptimizer_ProgrSimple_s;

inline float get_f_Y12_ParameterOptimizer_ProgrSimple(ParameterOptimizer_ProgrSimple_s* thiz)
   { return thiz->f_Y12; }

2) tlc-file adaption to organize the call if the getter/setter:

The tlc file is hand-written. The get_Access_DataStruct_Inspc_SfH.tlc contains the following code (shorten):

%function OutputsForTID(block, system, tid) Output
  .....
%if tid == tidStep
  %assign srcBlock = LibBlockSrcSignalBlock(0, 0)
  %assign sys1 = srcBlock[0]
  %assign blk1 = srcBlock[1]
  %assign block1 = CompiledModel.System[sys1].Block[blk1]
  %with block1
    %assign typeData = SFcnParamSettings.typeData_param
  %endwith
  {
    //The input is the reference to the created struct from DataStructMng_Inspc. The connected ...
    //The dwork is not used: %<LibBlockDWork(thiz_h, "", "", "0")>
   %<typeData>_s* pData = PTR_Handle2Ptr(%<LibBlockInputSignal(0, "", "", 0)>, %<typeData>_s);
   *(%<LibBlockOutputSignalAddr(0, "", "", 0)>) = get_%<SFcnParamSettings.name_param>_%<typeData>(pData);
  }
%endif
%endfunction

The generated codes come from the parameter settings, not from the C-functions of the Sfunction:

Adequate it is for the set_DatatStructMng_Inspc_SfH:

%function InitializeConditions (block, system) Output
 //Initialize the handle2Ptr-Mechanism on 64-bit-Systems if not done already:
 INIT_Handle2Ptr();
 { //jzTc: malloc for %<Type> %<ParamSettings.FunctionName>: %<Name>
   %assign hthizAddr = LibBlockDWorkAddr(thiz_h, "", "", "0")
   //create data for SFBlock= %<LibGetFormattedBlockPath(block)>, Type= step_DataStructMng_Inspc_SfH
   %<SFcnParamSettings.typeData_param>_s* thiz = (%<SFcnParamSettings.typeData_param>_s*) malloc(sizeof(%<SFcnParamSettings.typeData_param>_s));
   memset(thiz, 0, sizeof(Data_TestDataStruct_genc_s));
   init_ObjectJc((ObjectJc*)thiz, sizeof(Data_TestDataStruct_genc_s), ident_newAllocated_ObjectJc);  //set the length in ObjectJc for test.
   //NOTE: for 64 bit accelerator mode: register the pointer. Set hthiz. For 32-bit target it is a simple macro.
   registerPtr_Handle2Ptr(thiz, "%<SFcnParamSettings.typeData_param>", %<LibBlockDWorkAddr(thiz_h, "", "", "0")>);
 }
%endfunction

The DWork pointer is used in the originally Sfunction Wrapper to store the thiz-pointer to the struct DataStructMng_Inspc_t* which is more complex. For the generated code only the generated struct ...Type... with the Type from the paramter settings are present. The Type is stored as typeData_param. The data are created dynamically in the target system too, the handle is stored in the DWork.

%function UpdateForTID(block, system, tid) Output
 %assign tidInit = LibGetGlobalTIDFromLocalSFcnTID("OutputPortIdx0")    %%The TID for step_, the first step input port.
 %assign tidStep = LibGetGlobalTIDFromLocalSFcnTID("InputPortIdx0")    %%The TID for step_, the first step input port.
 %if tid == tidInit
 %%nothing Update in init
 %elseif tid == tidStep
 { //jzTc: update for %<Type> %<ParamSettings.FunctionName>: %<Name> (%<LibGetFormattedBlockPath(block)>), TID = %<tidInit>
   %assign hthiz = LibBlockDWork(thiz_h, "", "", "0")
   %<SFcnParamSettings.typeData_param>_s* thiz = PTR_Handle2Ptr(%<hthiz>, %<SFcnParamSettings.typeData_param>_s);
   %%
   %%It checks the name parameter and the connection on an input. Not connected inputs: the possible element remain unchanged, it is 0.
   %%
   %if (SFcnParamSettings.n1_param !="" && LibBlockInputSignalConnected(0))  %%only on given name:
     thiz->%<SFcnParamSettings.n1_param> = %<LibBlockInputSignal(0, "", "", 0)>;
   %endif
   %if (SFcnParamSettings.n2_param !="" && LibBlockInputSignalConnected(1))  %%only on given name:
     thiz->%<SFcnParamSettings.n2_param> = %<LibBlockInputSignal(1, "", "", 0)>;
   %endif
   %if (SFcnParamSettings.n3_param !="" && LibBlockInputSignalConnected(2))  %%only on given name:
     thiz->%<SFcnParamSettings.n3_param> = %<LibBlockInputSignal(2, "", "", 0)>;
   %endif
   %if (SFcnParamSettings.n4_param !="" && LibBlockInputSignalConnected(3))  %%only on given name:
     thiz->%<SFcnParamSettings.n4_param> = %<LibBlockInputSignal(3, "", "", 0)>;
   %endif
   %if (SFcnParamSettings.n5_param !="" && LibBlockInputSignalConnected(4))  %%only on given name:
     thiz->%<SFcnParamSettings.n5_param> = %<LibBlockInputSignal(4, "", "", 0)>;
   %endif
   %if (SFcnParamSettings.n6_param !="" && LibBlockInputSignalConnected(5))  %%only on given name:
     thiz->%<SFcnParamSettings.n6_param> = %<LibBlockInputSignal(5, "", "", 0)>;
   %endif
 }
 %endif
%endfunction %% Update