it-swarm-eu.dev

Können Abstraktionen und gute Code-Praktiken in eingebettetem C ++ den Debugger überflüssig machen?

Ich bin ein C-Entwickler für ein eingebettetes System. YouTube hat kürzlich begonnen, Gespräche über "C++ für eingebettete Systeme" zu empfehlen. Nachdem sie einige von ihnen gesehen haben, wecken sie mein Interesse, aber keiner von ihnen beantwortet die Frage, mit der sie mich verlassen.

Diese Vorträge (insbesondere Modern C++ in Embedded Systems von Michael Caisse) befürworten einen Entwicklungsprozess, bei dem anstelle von:

  1. code schreiben und bearbeiten
  2. debuggen, um zu bestätigen, dass es funktioniert (oder wahrscheinlicher Debuggen, um zu sehen, was falsch ist und wohin es von hier aus gehen soll)
  3. wiederholen, bis es funktioniert

... sollte man den Debugger vollständig vermeiden und darauf vertrauen, dass die Wahl der Sprache und der bewährten Verfahren Fehler weniger wahrscheinlich macht, wodurch der Debugger nicht mehr benötigt wird.

Aber als jemand, der Firmware für einen Mikrocontroller schreibt, der analoge Schaltkreise steuert, treten viele meiner Probleme auf, wenn Hardware unerwartetes Verhalten zeigt und ich finde, dass ich dieses Verhalten (insbesondere das Timing von Ereignissen) nur untersuchen kann, indem ich Haltepunkte über meinen gesamten Code wirf und warte um zu sehen, dass Ereignisse nicht oder nicht in Ordnung sind.

Dies zeigt dann entweder ein falsch konfiguriertes Register oder ein unerwartetes Verhalten eines der Peripheriegeräte des Mikrocontrollers an, das aus dem Gerätehandbuch nicht ersichtlich war und eine Neugestaltung des Codes erforderlich macht. Diese Gespräche haben meine Aufmerksamkeit erregt, aber ich kann nicht sehen, wie diese Techniken, die Leuten wie mir helfen sollen, mir tatsächlich bei Hardwareproblemen helfen.

Können Abstraktionen und gute Code-Praktiken (für die ich alle bin) den Debugger überflüssig machen (etwas, das ich für notwendig halte, um Hardware-Fehler zu beheben)?

25
Smyther

Ich denke, Sie stellen die Botschaft des Videos "Modern C++ in Embedded Systems" falsch dar. Der Punkt ist, dass es Menschen in der eingebetteten Welt gibt, die Code schreiben und ihn dann testen, indem sie den Code im Debugger ausführen, um zu überprüfen, ob er das tut, was er glaubt. Er argumentiert, dass eine bessere Alternative darin besteht, Abstraktionen zu verwenden, damit der Compiler überprüfen kann, ob bestimmte Annahmen über den Code gelten.

Diese Methode ermöglicht es weiterhin, den Debugger zu verwenden, um Fehler zu finden, insbesondere Hardwareprobleme. Sie sollten den Debugger einfach nicht verwenden, um Code zu verstehen. Er sollte verständlich und korrekt sein, wenn Sie ihn so schreiben.

Der Vorteil der Verwendung höherer Abstraktionen zur Validierung von Annahmen besteht darin, dass es bestimmte Arten von Fehlern gibt, z. mit einer Funktion f(int mode, int value), die als f(value, mode) bezeichnet wird, die vollständig vermieden werden kann. Michael Caisse argumentiert, dass die Verwendung der richtigen Werkzeuge, z. Starke Typen in C++ mildern dies und sollten daher verwendet werden.

34
henje

Nein überhaupt nicht !

Abstraktionen und bewährte Verfahren können natürlich das Fehlerrisiko verringern. Zum Beispiel:

  • sprachabstraktionen lassen den Compiler Code generieren, den Sie sonst selbst schreiben müssten. Das C++ - Objektmodell stellt beispielsweise sicher, dass das erstellte Objekt so zerstört wird, wie es sein soll, ohne dass Sie besonders auf Ihre Schultern achten müssen.

  • mit diesen Abstraktionen können Sie sicherere Konstrukte erstellen, die Sie in Ihrem Code verwenden können, z. B. RAII oder intelligente Zeiger , die das erheblich verringern Aufgaben im Zusammenhang mit der Speicherverwaltung;

  • eine umfangreiche Container-Bibliothek und eine leistungsstarke Algorithmus-Bibliothek vermeiden außerdem, dass Sie selbst viel fehleranfälligen Code schreiben müssen, indem Sie bereits getestete und hochoptimierte Implementierungen verwenden.

All dies verringert jedoch nur die Wahrscheinlichkeit von Fehlern. Es wird niemals Fehler vollständig beseitigen. Sie werden also weiterhin den Debugger und die Protokolldateien verwenden, um sie zu verfolgen.

35
Christophe

Diese Frage lautet im Wesentlichen: "Können Sie jedes Mal das erste Mal fehlerfreien Code schreiben?" Die Antwort wird immer nein sein.

Ja, es gibt Methoden, die helfen können. Sie können Module isolieren. Sie können sowohl für den eingebetteten als auch für den Desktop kompilieren und dann auf dem Desktop testen und entwickeln. Sie können Hardware-Abstraktionsschichten erstellen, mit deren Hilfe diese Module isoliert werden können, damit Sie sie auf dem PC einfacher testen und debuggen können.

Es ist sicherlich sinnvoll, die Verwendung von Debuggern auf eingebetteten Plattformen zu reduzieren, da diese normalerweise viel langsamer sind als auf PCs und Ihr REPL ist daher viel langsamer.

Aber irgendwann wird etwas auftauchen, das einen Debugger erfordert. Manchmal ist das ein JTAG-Debugger, manchmal ein Oszilloskop oder eine blinkende LED.

22
whatsisname

Es gibt zwei grundlegende Arten von Softwarefehlern:

  1. Der Code macht nicht das, was Sie beabsichtigt haben.
  2. Was Sie beabsichtigten, war das Falsche.

Die Auswahl der Sprachen usw. kann sich auf die erste Art von Fehler auswirken (oder auch nicht), hat jedoch keinerlei Auswirkungen auf die zweite. Beachten Sie, dass mit "was Sie beabsichtigt haben" das tatsächlich beobachtbare Verhalten der Software gemeint ist, nicht interne Entwurfsentscheidungen.

Für ein in die reale Welt eingebettetes System ist die Wahrscheinlichkeit, dass Sie alles vollständig verstanden haben, dass die reale Welt auf Ihre Software werfen kann, realistisch gesehen Null. Erwarten Sie also die Insektenjagd!

10
alephzero

Wenn alles, was Sie tun, perfekt ist, benötigen Sie keinen Debugger. Niemand ist perfekt.

Es gibt eine große Klasse von Fehlern, die ich in meiner Karriere gesehen habe und die als Autor bezeichnet werden können dachte sie wussten, was der Code tat, aber es tat tatsächlich etwas anderes. In diesem Fall benötigen Sie ein Tool, das genau zeigt, was der Computer getan hat, und nicht, was Sie dachten. Dieses Tool ist der Debugger (oder eine Reihe verwandter Tools, z. B. hyperparanoide Protokollierungsstufen).

Ein Framework, das Sie buchstäblich daran hindert, den linken und den rechten Motor zu verwechseln, ist wahrscheinlich zu restriktiv, um etwas Interessantes zu tun. Wenn Sie ein verallgemeinertes Framework so anpassen, dass es diesen Punkt erreicht, haben Sie einen Code mit anständiger Größe einen Debugger brauchen. In der Tat bin ich kürzlich auf einen solchen Fall gestoßen, der durch die gleichzeitige Anwendung eines Debuggers, einer guten Softwaredokumentation und einiger Lego-Modelle gelöst wurde. Ich hätte das Problem nicht lösen wollen, wenn eines dieser grundlegenden Werkzeuge fehlte.

Es gab Programmierer, die den No-Debugger-Ansatz anwenden. Donald Knuth war berühmt dafür, ein Programm von Anfang bis Ende durchzudenken und erst dann mit dem Schreiben des Codes zu beginnen. Soweit ich weiß, war sein Code bemerkenswert fehlerfrei und wurde oft beim ersten Mal kompiliert und ausgeführt! Aber ich bin sicher, er würde sich über einen Debugger freuen, wenn Ihre Firmware aufgrund eines Timeouts eine PCI-e-Ausnahme auslöst!

5
Cort Ammon

Debugger sind zwar ein nützliches Werkzeug für viele Dinge, dienen aber per Definition in erster Linie dem ... De-Bugging. Ihre Frage lautet also, ob bewährte Verfahren und das Vertrauen in Code von Drittanbietern Fehler jemals vollständig beseitigen können.

[...] darauf vertrauen, dass die Wahl der Sprache und bewährte Verfahren Fehler weniger wahrscheinlich macht, wodurch der Debugger nicht mehr erforderlich ist.

Wie Sie sagten, haben Sie, selbst wenn Sie darauf vertrauen, dass Ihre Sprachen/Frameworks und bewährten Methoden Fehler weniger wahrscheinlich machen, nicht alle Fehler beseitigt , sondern die Fehler reduziert Wahrscheinlichkeit ihres Auftretens. Wie können Sie ohne einen Debugger (oder einen ähnlichen Ansatz wie die Protokollierung) die immer noch auftretenden Fehler diagnostizieren?

Wenn jeder seinen Sprachen und Frameworks zu 100% vertraut, wie werden dann Fehler in den Sprachen/Bibliotheken selbst entdeckt? Öffnen Sie ein Mainstream-Projekt auf GitHub und sehen Sie, wie viele Probleme gemeldet werden.

Gute Praktiken können sicherlich Softwarefehler reduzieren , aber selbst die besten Praktiken und Tools werden den Nutzen eines Debuggers niemals beseitigen.

Ich denke, Ihre Antwort ist in Ihrem eigenen Kommentar:

[...] Viele meiner Probleme treten auf, wenn Hardware unerwartetes Verhalten zeigt

Das Problem mit Bugs ist, wir sehen sie nie kommen!

1
Kyle McVay

Isolieren von zwei spezifischen Anwendungsfällen im Kontext der eingebetteten Entwicklung:

Als Entwicklungstool ist der Debugger für das Testen von Code und Ausführungszuständen in einer sterilen und kontrollierten Umgebung unerlässlich.

Als Diagnosetool ist der Debugger für die Diagnose und das Verständnis der Fehlermodi einer eingebetteten Firmware unerlässlich.

Also nein , es kann nicht beseitigt werden, zumindest nicht vollständig.

Eingebettete Geräte interagieren mit realen Bedingungen, sodass der endgültige Test einer eingebetteten Firmware unter realen Bedingungen und nicht unter Debugger-induzierten Belastungen (Umwelt- und Anwendungsstresstests) durchgeführt wird. Es gibt "Software-Fehler", die ausschließlich im Entwicklungsbereich des Software-Ingenieurs (SE) liegen, und "System-Fehler", die auftreten, wenn die Firmware mit den realen Bedingungen ihrer eingebetteten Anwendung interagiert.


Während der Embedded-Entwicklung definiert die SE in Zusammenarbeit mit dem Elektronikingenieur (EE), dem Maschinenbauingenieur (ME) und dem Projektmanager (PM) die nominalen Betriebsbedingungen und die erwartete Funktion Ihrer Firmware-Funktion. In dieser Entwicklungsaktivität sind der Debugger und das ICE/SWD-Gerät von unschätzbarem Wert, um dies zu ermöglichen

  • Systemüberwachung
  • Codefehlererkennung
  • Kontrollierte Testbedingung

Im Vergleich zur Protokollierung, die auf einem eingebetteten System viele Nebenwirkungen und Komplexitäten haben kann, ist dies eine besonders unaufdringliche Methode, um mit der Gewissheit zu entwickeln und zu testen, dass die nominalen Bedingungen der realen Welt nahe kommen und alle unmittelbaren "Software" -Fehler beseitigt werden.


Nachdem die Firmware nominell vollständig ist, ist ein Qualifizierungs- und Testzyklus erforderlich. Im Gegensatz zu reiner Software enthält ein eingebettetes Gerät normalerweise eine physische reale Komponente und die Effektivität der zugehörigen Firmware. Die Umgebung kann Dinge wie beeinflussen

  • Raten von Eingaben und Interrupts
  • Datenqualität von externen Sensoren
  • Betriebsbedingungen und Basisfehlerraten verschiedener Protokolle und E/A-Schnittstellen
  • Andere umweltabhängige Bedingungen.

All dies wird dazu dienen, Ihre eingebettete Firmware bis zu einem Punkt zu belasten, an dem alle von Ihnen durchgeführten Logik- und Fehlerzustandsprüfungen einem Stresstest unterzogen werden. Sie befinden sich sozusagen in rauer See im Vergleich zu Ihrer Entwicklungsumgebung ...

Ein Testzyklus für eingebettete Geräte wird also kombiniert

  • Umweltbelastung (Vibration, Wärme, Elektrik)
  • E/A-Stress (externe Protokolle und Schnittstellen)
  • Anwendungsstress (anspruchsvolle Leistung)
  • Jede andere anwendbare Belastung

Um das System und damit die eingebettete Firmware einem Stresstest zu unterziehen.

In diesem Zusammenhang ist der Debugger in Kombination mit dem ICE/SWD ein unschätzbares Diagnosewerkzeug für

  • Verstehe die Natur eines Fehlers oder einer Panne
  • Geben Sie dem EE die Schuld, dass er die Hardware vermasselt hat
  • Diagnostizieren und überwachen Sie das System, nachdem eine Schwachstelle aufgetreten ist

Selbst hier, nein , ist der Debugger ein unschätzbares Werkzeug.

0
crasic