Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial Internet of Things >> Eingebettet

Warum Sie standardbasierte Entwicklungspraktiken verwenden sollten (auch wenn Sie es nicht müssen)

Eine ganze Branche hat sich um Verifizierungs- und Validierungspraktiken herum entwickelt, die von funktionalen Sicherheits-, Sicherheits- und Codierungsstandards wie IEC 61508, ISO 26262, IEC 62304, MISRA C und CWE verfochten werden. Natürlich ist nicht jeder verpflichtet, die formalen Prozesse und Methoden zu befolgen, die diese Standards fördern, insbesondere wenn ihre Software nicht die Strenge dieser Standards erfüllen muss. Aber die Standards setzen sich für Best Practices ein, weil sie erfahrungsgemäß der effektivste Weg sind, qualitativ hochwertige, zuverlässige und robuste Software zu erzielen.

Best-Practice-Entwicklungstechniken, die diesen Standards entsprechen, tragen dazu bei, dass Fehler gar nicht erst in den Code eingeführt werden, wodurch die Notwendigkeit umfangreicher Debugging-Aktivitäten reduziert wird, die die Markteinführungszeit verlangsamen und die Kosten erhöhen können. Natürlich haben nicht alle Entwickler den Luxus der Zeit und des Budgets, die für Anwendungen in der Luft- und Raumfahrt, der Automobilindustrie oder der Medizingeräteindustrie zur Verfügung stehen. Die von ihnen eingesetzten Techniken stellen jedoch eine Toolbox mit enormen potenziellen Vorteilen für jedes Entwicklungsteam dar, unabhängig davon, ob ihre Verwendung durch Kritikalität erzwungen wird oder nicht.

Fehlerarten und Tools zu deren Behebung

Zwei Haupttypen von Fehlern können in Software gefunden und mithilfe von Tools behoben werden, um die Einführung von Fehlern zu verhindern:

Codierungsfehler und Codeüberprüfung

Die statische Analyse ist eine effektive Methode zur Erkennung von Codierungsfehlern, insbesondere wenn sie von Beginn eines Projekts an eingesetzt wird. Nachdem der Code analysiert wurde, können verschiedene Arten von Ergebnissen angezeigt werden. Bei der Codeüberprüfung wird der Code gegen einen Codierungsstandard wie MISRA C:2012 geprüft, worauf wir uns in diesem Artikel konzentrieren werden.

Idealerweise wird für alle eingebetteten Projekte eine sichere Sprache wie Ada verwendet. Ada enthält zahlreiche Eigenschaften, um einen Denkprozess zu erzwingen, der Fehler auf natürliche Weise reduziert (wie zum Beispiel striktes Tippen). Leider ist es schwierig, Programmierer mit Ada-Kenntnissen und -Erfahrung zu finden, daher verwenden die meisten Unternehmen stattdessen C und/oder C++. Diese Sprachen bergen jedoch selbst für erfahrene Entwickler Fallstricke. Glücklicherweise können die meisten dieser potenziellen Fallstricke durch eine Codeüberprüfung vermieden werden.

Der beste Weg, Fehler im Code zu vermeiden, besteht darin, sie nicht dort zu platzieren. Das klingt offensichtlich, aber genau das macht ein Codierungsstandard. In der C- und C++-Welt werden etwa 80 % der Softwarefehler durch die falsche Verwendung von etwa 20 % der Sprache verursacht. Wenn die Verwendung der Sprache eingeschränkt wird, um die bekanntermaßen problematischen Teile der Sprache zu vermeiden, werden Fehler vermieden und die Softwarequalität stark erhöht.

Die grundlegenden sprachbezogenen Fehlerursachen bei den Programmiersprachen C/C++ sind undefiniertes Verhalten, implementierungsdefiniertes Verhalten und nicht spezifiziertes Verhalten. Dieses Verhalten führt zu Softwarefehlern und Sicherheitsproblemen.

Betrachten Sie als Beispiel für implementierungsdefiniertes Verhalten die Ausbreitung des höherwertigen Bits, wenn eine ganze Zahl mit Vorzeichen nach rechts verschoben wird. Ist das Ergebnis 0x40000000 oder 0xC0000000?


Abbildung 1:Das Verhalten einiger C- und C++-Konstrukte hängt vom verwendeten Compiler ab. (Quelle:LDRA)

Die Antwort hängt davon ab, welchen Compiler Sie verwenden (Abbildung 1). Es könnte entweder sein. Die Reihenfolge, in der die Argumente einer Funktion ausgewertet werden, ist in der Sprache C nicht festgelegt. In dem in Abbildung 2 gezeigten Code – wo die rollDice() Die Funktion liest einfach den nächsten Wert aus einem Ringpuffer, der die Werte „1, 2, 3 und 4“ enthält – der erwartete Rückgabewert wäre 1234. Es gibt jedoch keine Garantie dafür und mindestens ein Compiler generiert Code, der zurückgibt der Wert 3412.


Abbildung 2:Das Verhalten einiger C- und C++-Konstrukte ist von den Sprachen nicht spezifiziert. (Quelle:LDRA)

Die C/C++-Sprachen bieten viele solcher Fallstricke, aber mit der Verwendung eines Codierungsstandards können diese undefinierten, nicht spezifizierten und implementierungsdefinierten Verhaltensweisen vermieden werden. Ebenso die Verwendung von Konstrukten wie goto oder malloc kann zu Fehlern führen, daher kann ein Kodierungsstandard verwendet werden, um die Verwendung dieser Konstrukte zu verhindern. Beim Mischen von vorzeichenbehafteten und vorzeichenlosen Werten treten viele Probleme auf, was meistens kein Problem darstellt, aber manchmal kann es vorkommen, dass der vorzeichenbehaftete Wert überläuft und negativ wird.

Codierungsstandards können auch überprüfen, ob Code in einem bestimmten Stil geschrieben ist; B. überprüfen, ob das Tabulatorzeichen nicht verwendet wird, die Einrückung eine bestimmte Größe hat oder dass Klammern an einer bestimmten Position positioniert sind. Dies ist wichtig, da einige manuelle Codeüberprüfungen erforderlich sind und wenn der Code in einem anderen Editor angezeigt wird, in dem das Tabulatorzeichen eine andere Größe hat, lenkt das seltsame Layout den Überprüfer davon ab, sich auf die Überprüfung des Codes zu konzentrieren.

Manche Entwickler machen sich schuldig, „cleveren“ Code zu schreiben, der hocheffizient und kompakt, aber auch kryptisch und komplex sein kann, was es für andere schwer macht, ihn zu verstehen. Es ist viel besser, es einfach zu halten und den Compiler die Erstellung einer effizienten Binärdatei zu überlassen. Auch hier kann die Verwendung eines Codierungsstandards dazu beitragen, Entwickler daran zu hindern, undokumentierten und überkomplexen Code zu erstellen.

Die bekanntesten Programmierstandards sind vielleicht die MISRA-Standards, die erstmals 1998 für die Automobilindustrie veröffentlicht wurden. Die Popularität dieser Standards spiegelt sich in der Anzahl eingebetteter Compiler wider, die ein gewisses Maß an MISRA-Prüfung bieten. Die neueste Version von MISRA ist MISRA C:2012, die fast doppelt so viele Seiten wie ihr Vorgänger hat. Der größte Teil dieser zusätzlichen Dokumentation besteht aus nützlichen Erklärungen zu den einzelnen Regeln sowie Einzelheiten zu den verschiedenen Ausnahmen von dieser Regel. MISRA hat mehrere Richtlinien und diese enthalten ggf. Verweise auf Standards oder auf das undefinierte, nicht spezifizierte und umsetzungsdefinierte Verhalten. Ein Beispiel dafür ist in Abbildung 3 zu sehen.


Abbildung 3:MISRA C-Referenzen auf undefiniertes, nicht spezifiziertes und implementierungsdefiniertes Verhalten. (Quelle:LDRA)

Die meisten MISRA-Richtlinien sind „entscheidbar“, was bedeutet, dass ein Tool in der Lage sein sollte, zu erkennen, ob ein Verstoß vorliegt oder nicht. Einige Richtlinien sind jedoch „unentscheidbar“, d. h. ein Tool kann nicht immer auf einen Verstoß schließen. Ein Beispiel hierfür ist, wenn eine nicht initialisierte Variable als Ausgabeparameter an eine Systemfunktion übergeben wird, die sie initialisieren soll. Wenn die statische Analyse jedoch keinen Zugriff auf den Quellcode der Systemfunktion hat, kann sie nicht wissen, ob diese Funktion die Variable verwendet, bevor sie sie initialisiert. Wenn ein einfacher MISRA-Checker verwendet wird, wird dieser Verstoß möglicherweise nicht gemeldet, was möglicherweise zu einem falsch-negativen Ergebnis führt. Alternativ kann ein MISRA-Checker, wenn er sich nicht sicher ist, den Verstoß melden, was möglicherweise zu einem falsch positiven Ergebnis führt. Was ist das beste? Sie wissen nicht, dass es ein Problem geben könnte? Oder wissen Sie genau, wo Sie Zeit verbringen müssen, um sicherzustellen, dass es definitiv kein Problem gibt? Sicherlich ist es besser, falsch-positive als falsch-negative zu haben.

Im April 2016 hat das MISRA-Komitee eine Änderung zu MISRA C:2012 herausgegeben, die zusätzliche 14 Richtlinien hinzufügte, um sicherzustellen, dass MISRA nicht nur für sicherheitskritische, sondern auch für sicherheitskritische Software anwendbar ist. Eine dieser Leitlinien war die Richtlinie 4.14, die, wie in Abbildung 4 zu sehen ist, dazu beiträgt, Fallstricke durch undefiniertes Verhalten zu vermeiden.


Abbildung 4:MISRA und Sicherheitsüberlegungen. (Quelle:LDRA)

Anwendungsfehler und Anforderungstests

Anwendungsfehler können nur gefunden werden, indem getestet wird, ob das Produkt tut, was es soll, und das bedeutet, dass es Anforderungen stellt. Um Anwendungsfehler zu vermeiden, müssen sowohl das richtige Produkt als auch das richtige Produkt entwickelt werden.

Das richtige Produkt zu konzipieren bedeutet, im Vorfeld Anforderungen festzulegen und die bidirektionale Nachvollziehbarkeit zwischen den Anforderungen und dem Quellcode sicherzustellen, damit jede Anforderung umgesetzt wurde und jede Softwarefunktion auf eine Anforderung zurückgeführt wird. Jede fehlende oder unnötige Funktionalität (die eine Anforderung nicht erfüllt) ist ebenfalls ein Anwendungsfehler. Das Entwerfen des Produktrechts ist der Prozess der Bestätigung, dass der entwickelte Systemcode die Projektanforderungen erfüllt, was durch anforderungsbasierte Tests erreicht werden kann.

Abbildung 5 zeigt ein Beispiel für die bidirektionale Rückverfolgbarkeit. In diesem einfachen Beispiel wurde eine einzelne Funktion ausgewählt und die vorgelagerte Rückverfolgbarkeit von der Funktion zu einer Anforderung auf niedriger Ebene, dann zu einer Anforderung auf hoher Ebene und schließlich zu einer Anforderung auf Systemebene hervorgehoben.


Abbildung 5:Bidirektionale Rückverfolgbarkeit mit ausgewählter Funktion. (Quelle:LDRA)

In Abbildung 6 wurde eine High-Level-Anforderung ausgewählt, und die Hervorhebung zeigt sowohl die Upstream-Rückverfolgbarkeit auf eine Systemlevel-Anforderung als auch die Downstream-Verfolgbarkeit auf Low-Level-Anforderungen und auf Quellcodefunktionen.

Klicken für größeres Bild

Abbildung 6:Bidirektionale Rückverfolgbarkeit mit ausgewählter Anforderung. (Quelle:LDRA)

Diese Möglichkeit, die Rückverfolgbarkeit zu visualisieren, kann dazu führen, dass Rückverfolgbarkeitsprobleme (Anwendungsfehler) früh im Lebenszyklus erkannt werden.

Das Testen der Code-Funktionalität erfordert ein Bewusstsein dafür, was sie tun soll, und das bedeutet, dass Sie niedrige Anforderungen haben müssen, um anzugeben, was jede Funktion tut. Abbildung 7 zeigt ein Beispiel für eine Low-Level-Anforderung, die in diesem Fall eine einzelne Funktion vollständig beschreibt.


Abbildung 7:Beispiel einer Low-Level-Anforderung. (Quelle:LDRA)

Testfälle werden von Low-Level-Anforderungen abgeleitet, wie in Tabelle 1 dargestellt.

Tabelle 1:Testfälle abgeleitet von Low-Level-Anforderungen. (Quelle:LDRA)

Mit einem Unit-Test-Tool können diese Testfälle dann auf dem Host oder dem Target ausgeführt werden, um sicherzustellen, dass sich der Code den Anforderungen entsprechend verhält. Abbildung 8 zeigt, dass alle Testfälle regressiert und bestanden wurden.


Abbildung 8:Durchführen von Unit-Tests. (Quelle:LDRA)

Wenn die Testfälle ausgeführt wurden, sollte die strukturelle Abdeckung gemessen werden, um sicherzustellen, dass der gesamte Code ausgeführt wurde. Wenn die Abdeckung nicht 100 Prozent beträgt, ist es möglich, dass entweder mehr Testfälle erforderlich sind oder überflüssiger Code entfernt werden sollte.

Schlussfolgerung

Mit zunehmender Softwarekomplexität nehmen auch potenzielle Softwarefehler zu. Best-Practice-Entwicklungstechniken helfen, das Auftreten dieser Fehler zu vermeiden. Die Best-Practice-Entwicklung besteht darin, einen hochmodernen Codierungsstandard wie MISRA C:2012 zu verwenden, Metriken des Codes zu messen, Anforderungen zu verfolgen und anforderungsbasierte Tests durchzuführen. Inwieweit diese Techniken angewendet werden, wenn keine Verpflichtungen zur Einhaltung von Standards bestehen, liegt eindeutig im Ermessen des Entwicklungsteams. Die Standards setzen sich jedoch für diese Praktiken ein, da sie erfahrungsgemäß der effektivste Weg sind, um qualitativ hochwertige, zuverlässige und robuste Software zu erzielen. Und ob ein Produkt sicherheitskritisch ist oder nicht, das ist sicherlich ein Ergebnis, das nur seinem Entwicklungsteam zugute kommen kann.


Eingebettet

  1. Warum Sie zu Connext DDS Secure wechseln sollten
  2. Warum Sie aufhören sollten, Ihre Roboter zu programmieren
  3. Warum müssen Sie landwirtschaftliche Farbstoffe verwenden?
  4. Was ist das NuttX-RTOS und warum sollte es Sie interessieren?
  5. Warum Sie sich für generalüberholte Industrieanlagen entscheiden sollten
  6. Warum Sie eine Netzdrossel verwenden sollten
  7. Warum Sie eine Karriere im Maschinen- und Anlagenbau in Betracht ziehen sollten
  8. Wann sollten Sie einen Hammerhai verwenden? Ein Leitfaden
  9. Warum sollten Sie eine Remote Expert-Lösung verwenden?
  10. Warum sollten Sie den Konsignationsverkauf für Ihre Gebrauchtgeräte nutzen?