Generierung von Produktions-Codes früher und heute #####

Die automatische Code-Generierung aus Modellen ist ein wichtiges Verfahren für die Entwicklung von Produktions-Software. Mit der immer stärkeren Abstraktion und Automatisierung geht aber auch die Notwendigkeit einher, neue Prozesse, Methoden und Werkzeuge in die Software-Entwicklung einzuführen und vorhandene auslaufen zu lassen. Im Vergleich zu früheren Verfahren lassen sich durchaus Vorteile erkennen.

Die automatische Code-Generierung aus Modellen ist ein wichtiges Verfahren für die Entwicklung von Produktions-Software. Mit der immer stärkeren Abstraktion und Automatisierung geht aber auch die Notwendigkeit einher, neue Prozesse, Methoden und Werkzeuge in die Software-Entwicklung einzuführen und vorhandene auslaufen zu lassen. Im Vergleich zu früheren Verfahren lassen sich durchaus Vorteile erkennen.

Wasserfallprozesse sind heute zugunsten von Spiralmodellen und iterativen Verfahren in den Hintergrund getreten. Ausführbare Spezifikationen, die auf Modellen basieren, verdrängen die statischen, auf gedruckten Dokumenten basierenden Entwürfe. Außerdem sind neue Ideen und Tools wie etwa die integrierte Entwicklungsumgebung (Integrated Development Environment, IDE), die Hardware Description Language (HDL) oder Werkzeuge für automatisierte Tests entstanden. Aber nicht jede Idee für neue Entwicklungsprozesse und Tools hat sich durchgesetzt. Neuentwicklungen scheitern oft, weil sie nicht für die typische Massenproduktion geeignet sind. Ein Beispiel hierfür sind die CASE-Tools der 1980er. Sie waren zwar hilfreich für die Entwicklung und Dokumentierung, aber auch schwer zu pflegen, weil sie keinen automatisierten Weg zur Generierung von ECU-Code anboten. Die formalen Methoden sind ein weiteres Beispiel: Es gibt sie zwar seit etlichen Jahren und sie können die Software-Qualität verbessern, aber die fehlende Unterstützung durch automatisierte Werkzeuge hat ihre flächendeckende Akzeptanz verhindert.

Die modellorientierte Entwicklung hingegen hat sich im Rahmen dieses Evolutionsprozesses bisher als erfolgreich erwiesen. Sie ist praxistauglich und wird durch viele Tools unterstützt. Ein Anwendungs-Modell lässt sich auf vielfältige Weisen nutzen, die über das reine Festhalten des Systementwurfs hinausgehen, so auch für das On-Target Rapid Prototyping. Die Generierung von Produktions-Code ist jedoch nicht möglich. Das Umgebungsmodell kann als Testumgebung für die Validierung der Anwendung durch Processor-in-the-Loop-Tests (PiL) in einer IDE dienen. Mit dem Modell können Berichte erzeugt und für Design-Reviews genutzt werden. In letzter Zeit hat The MathWorks außerdem Werkzeuge wie den Simulink Design Verifier und die PolySpace-Code-Verifikationsprodukte vorgestellt; sie automatisieren die formale Analyse. Der durch die modellorientierte Entwicklung erzielte Nutzen nimmt ganz offensichtlich mit jeder Anwendungsmöglichkeit des Modells weiter zu. Eine Fortsetzung des bisherigen Wachstums der modellorientierten Entwicklung erfordert jedoch eine enge Integration aller beteiligten Prozesse, Methoden und Werkzeuge, weil sonst ihre Wartung deutlich erschwert wird. Fehlt außerdem nur eines der genannten Teile, kann das die erfolgreiche Umstellung von Produktionsprozessen in einem Unternehmen empfindlich behindern.

Im Folgenden werden Methoden und Arbeitsabläufe zur Generierung von Produktions-Code im Rahmen einer System- und Software-Entwicklung vorgestellt; darunter auch solche, die derzeit für Systeme mit hoher Integritätsdichte eingesetzt werden. Die Eigenschaften der vorgestellten Tools beziehen sich auf die Versionen von Matlab, Simulink, Stateflow und Real-Time Workshop Embedded-Coder aus dem MathWorks Release 2008a (R2008a).


R2007b:
void s_step(void) {
    bus_2 rtb_BusCreator;
    int32_T rtb_size;
    int32_T rtb_signal1;
    int8_T rtb_p_data[8];
    rtb_size = s_U.in.size;
    (void) memcpy(&(rtb_p_data[0]),&s_U.in.p_data, 8*sizeof(unit8_T));
    s_Y.Out1 = s_U.in.start – s_U.in.end;
    rtb_signal1 = rtb_size << 1U;
    rtb_BusCreator.size = rtb_singal1;
    (void) memcpy(&(rtb_BusCreator.p_data),rtb_p_data, 8*sizeof...
    (void) memcpy(&(rtb_.p_data[0]),rtb_BusCreator.p_data...
    s_Y.Out4 = rtb_p_data[2];
}
R2008a:
void s_step(void) {
    s_Y.Out1 = s_U.in.start – s_U.in.end;
    s_Y.Out2 = s_U.in.p_data[2];
}
Code-Optimierung für Busse in R2007b und R2008b: Die überflüssigen temporären Variablen (rtb_) wurden in R2008a entfernt. Das macht den Code effizienter und leichter integrierbar.