Ich habe einige grundlegende objektorientierte Programmierung mit C++ durchgeführt (Erstellen eines B-Baums, Hashing-Algorithmen, doppelt verknüpfte Listen) und ich habe ein kleines Projekt in C durchgeführt (wie einen wissenschaftlichen Taschenrechner erstellen usw.).
Wie unterscheidet sich die Hardwareprogrammierung (insbesondere für Mikrocontroller) von der software-/objektorientierten Programmierung in Bezug auf die Denkweise und das "Denken", das der Programmierer haben muss?
Gilt einer meiner meisten Leute normalerweise als härter als der andere?
Benötige ich mit meinem Hintergrund (wie oben beschrieben) viel Vorbereitung, um in die Hardwareprogrammierung einzusteigen, oder kann ich ohne allzu große Vorbereitung direkt einsteigen?
Bei den meisten Mikrocontrollern müssen Sie das objektorientierte Paradigma vollständig aufgeben.
Mikrocontroller sind im Allgemeinen register- und RAM-begrenzt, mit langsamen Taktraten und ohne Pipelining / parallele Codepfade. Sie können zum Beispiel Java auf einem PIC vergessen.
Sie müssen sich in eine Assembler-Denkweise versetzen und prozedural schreiben.
Sie müssen Ihren Code relativ flach halten und Rekursionen vermeiden, da RAM-Beschränkungen oft zu Stapelproblemen führen können.
Sie müssen lernen, wie man Interrupt-Service-Routinen schreibt, die effizient sind (normalerweise in Assemblersprache).
Möglicherweise müssen Sie Teile des Codes manuell in Assemblersprache umgestalten, um Funktionen zu implementieren, die der Compiler nicht (oder nur unzureichend) unterstützt.
Sie müssen mathematischen Code schreiben, der die Wortgröße und den Mangel an FPU-Fähigkeiten der meisten Mikrocontroller berücksichtigt (dh 32-Bit-Multiplikation auf einem 8-Bit-Mikro = böse).
Es ist eine andere Welt. Ein Informatik- oder professioneller Programmierhintergrund kann für mich im Umgang mit Mikrocontrollern genauso hinderlich sein wie gar keine Kenntnisse.
Sie müssen an mehrere Dinge denken:
Es gibt andere Einschränkungen, die ins Spiel kommen, wie z. B. begrenzte Geschwindigkeit und Speicher. Als allgemeine Richtlinie vermeide ich also:
Die Liste geht weiter, ich bin wahrscheinlich unterdurchschnittlich in Sachen Softwareprogrammierung, ich bin mir sicher, dass es bessere Praktiken gibt.
Ich mache beides, also hier ist meine Ansicht.
Ich denke, die mit Abstand wichtigste Fähigkeit in Embedded ist Ihre Debugging-Fähigkeit. Die erforderliche Denkweise ist insofern anders, als so viel mehr schief gehen kann, und Sie müssen sehr offen dafür sein, all die verschiedenen Möglichkeiten zu berücksichtigen, wie das, was Sie zu tun versuchen, schief gehen kann.
Dies ist das größte Einzelproblem für neue Embedded-Entwickler. PC-Leute haben es tendenziell rauer, da sie es gewohnt sind, so viel nur für sie zu arbeiten. Sie verschwenden viel Zeit damit, nach Tools zu suchen, die Dinge für sie erledigen (Tipp: Es gibt nicht viele). Es gibt eine Menge Köpfe, die immer wieder gegen Wände schlagen, ohne zu wissen, was sie sonst tun sollen. Wenn Sie das Gefühl haben, festzustecken, treten Sie einen Schritt zurück und finden Sie heraus, ob Sie erkennen können, was alles schief läuft. Grenzen Sie systematisch Ihre Liste potenzieller Probleme ein, bis Sie es herausgefunden haben. Aus diesem Prozess folgt direkt, dass Sie den Umfang der Probleme begrenzen sollten, indem Sie nicht zu viel auf einmal ändern.
Erfahrene Embedded-Leute neigen dazu, das Debuggen als selbstverständlich zu betrachten ... die meisten Leute, die es nicht gut können, halten nicht lange durch (oder arbeiten in großen Unternehmen, die einfach "Firmware ist schwer" als Antwort darauf akzeptieren, warum ein bestimmtes Feature ist Jahre zu spät)
Sie arbeiten an Code, der auf einem externen System zu Ihrem Entwicklungssystem ausgeführt wird, mit unterschiedlichem Grad an Sichtbarkeit Ihres Ziels von Plattform zu Plattform. Wenn Sie dies unter Ihrer Kontrolle haben, drängen Sie auf Entwicklungshilfen, um diese Sichtbarkeit in Ihrem Zielsystem zu erhöhen. Verwenden Sie serielle Debug-Ports, Bit-Banging-Debug-Ausgang, das berühmte Blinklicht usw. Lernen Sie zumindest, wie man ein Oszilloskop verwendet und Pin-I / O mit dem Oszilloskop verwendet, um zu sehen, wann bestimmte Funktionen eintreten / verlassen, ISRs ausgelöst werden usw Ich habe gesehen, wie Leute buchstäblich Jahre länger als nötig kämpften, einfach weil sie sich nie die Mühe gemacht haben, einen richtigen JTAG-Debugger-Link einzurichten/zu lernen.
Es ist viel wichtiger, genau zu wissen, welche Ressourcen Sie im Verhältnis zu einem PC haben. Lesen Sie die Datenblätter sorgfältig durch. Berücksichtigen Sie die Ressourcen-"Kosten" von allem, was Sie zu tun versuchen. Lernen Sie ressourcenorientierte Debugging-Tricks wie das Füllen von Stack-Speicherplatz mit einem magischen Wert, um die Stack-Nutzung zu verfolgen.
Während sowohl für PC- als auch für eingebettete Software ein gewisses Maß an Debugging-Fähigkeiten erforderlich ist, ist dies bei eingebetteter Software viel wichtiger.
Ich gehe davon aus, dass Ihre C++-Erfahrung PC-basiert ist.
Programmierer, die von PCs auf Mikrocontroller umsteigen, machen häufig den Fehler, dass sie nicht erkennen, wie begrenzt Ressourcen sein können. Auf einem PC wird Sie niemand aufhalten, wenn Sie eine Tabelle mit 100.000 Einträgen erstellen oder ein Programm schreiben, das zu 1 MB Maschinencode kompiliert.
Es gibt Mikrocontroller, die über eine Fülle von Speicherressourcen verfügen, insbesondere im High-End-Bereich, aber es ist immer noch weit entfernt von dem, was Sie gewohnt sind. Bei einem Hobbyprojekt können Sie wahrscheinlich immer das Maximum herausholen, aber bei einem professionellen Projekt werden Sie oft gezwungen sein, mit dem kleineren Gerät zu arbeiten, weil es billiger ist .
An einem Projekt arbeitete ich mit einem TI MSP430F1101. 1 KB Programmspeicher, 128 Byte Konfigurations-Flash, 128 Byte RAM. Das Programm passte nicht in die 1K, also musste ich eine 23-Byte-Funktion in das Konfigurations-Flash schreiben. Mit diesen kleinen Controllern rechnen Sie byteweise . Bei einer anderen Gelegenheit war der Programmspeicher 4 Byte zu klein. Boss ließ mich den Controller nicht mit mehr Speicher verwenden, stattdessen musste ich einen bereits optimierten Maschinencode (der bereits in Assembler geschrieben war) optimieren, um die zusätzlichen 4 Bytes einzufügen. Sie erhalten das Bild.
Abhängig von der Plattform, auf der Sie arbeiten, müssen Sie mit I/O auf sehr niedrigem Niveau umgehen . Einige Entwicklungsumgebungen haben Funktionen, um auf ein LCD zu schreiben, aber bei anderen sind Sie auf sich allein gestellt und müssen das Datenblatt des LCDs von Anfang bis Ende lesen, um zu wissen, wie man es steuert.
Möglicherweise müssen Sie ein Relais steuern, das ist einfacher als ein LCD, aber Sie müssen auf die Registerebene des Mikrocontrollers gehen. Wieder ein Datenblatt oder Benutzerhandbuch. Den Aufbau des Mikrocontrollers, den Sie in einem Blockschaltbild wiederfinden, müssen Sie noch einmal im Datenblatt kennenlernen. Zu Zeiten des Mikroprozessors sprachen wir von einem Programmiermodell, was im Grunde eine Anordnung der Register des Prozessors war. Heutige Mikrocontroller sind so komplex, dass eine Beschreibung aller Register den größten Teil eines 100-seitigen Datenblatts einnehmen kann. IIRC nur die Beschreibung des Taktmoduls für den MSP430 war 25 Seiten lang.
Sie müssen sich oft mit Echtzeit- Event-Handling befassen. Ein Interrupt , den Sie innerhalb von 10 bearbeiten müssen s zum Beispiel und haben währenddessen einen anderen Interrupt, der die gleiche Zeitgenauigkeit erfordert.
Mikrocontroller werden oft in C programmiert . C++ ist ziemlich ressourcenhungrig, also ist das normalerweise out. (Die meisten C++-Implementierungen für Mikrocontroller bieten eine begrenzte Teilmenge von C++.) Wie gesagt, je nach Plattform steht Ihnen möglicherweise eine umfangreiche Funktionsbibliothek zur Verfügung, mit der Sie einiges an Entwicklungszeit sparen können. Es lohnt sich, sich etwas Zeit zu nehmen, um es zu studieren, es kann Ihnen später viel Zeit sparen, wenn Sie wissen, was verfügbar ist.
"Hardwareprogrammierung" kann vieles bedeuten. Das Programmieren eines sehr kleinen Chips (denken Sie an 10F200, 512 Befehle, ein paar Bytes RAM) kann fast wie das Entwerfen einer elektronischen Schaltung sein. Andererseits kann die Programmierung eines großen Cortex-Mikrocontrollers (1 Mb FLASH, 64 kB RAM) der PC/GUI-Programmierung mit einem großen GUI-Toolkit sehr ähnlich sein. Meiner Meinung nach benötigt ein guter Embedded-/Echtzeitprogrammierer Fähigkeiten sowohl auf der Seite der Softwareentwicklung als auch auf der Seite des Schaltungsdesigns. Für die größeren uC ist C++ eine gute Sprachwahl, für die ganz kleinen dürfte C die einzige Wahl sein. Montagekenntnisse können nützlich sein, aber ich würde nicht empfehlen, ernsthafte Projekte vollständig in Montage durchzuführen.
Ich habe ernsthafte eingebettete Arbeit mit Leuten von beiden Seiten (SWI und EE) gemacht. Ich bevorzuge im Allgemeinen die SWI-Leute, vorausgesetzt, sie haben etwas Erfahrung mit Multi-Thread-Programmierung.
Ihre Frage klingt, als wollten Sie in die eingebettete Programmierung eintauchen. Tun Sie das auf jeden Fall. Für die Low-Level-Aspekte (Verbindung der Peripheriegeräte in Ihrem Chip und der Hardware darum herum) müssen Sie einige neue Fähigkeiten erlernen, aber es ist nur eine Menge Arbeit ohne viele neue Konzepte. Für die höheren Schichten Ihrer Projekte können Sie auf Ihr vorhandenes Wissen zurückgreifen.
Für jede Arduino-Bibliotheksmethode, die Sie aufrufen, gibt es eine Fülle von C/C++-Code, der dies ermöglicht, es ist einfach schön verpackt, damit Sie es als API verwenden können. Werfen Sie einen Blick auf den Arduino-Quellcode unter dem Verzeichnis hardware/arduino/* und Sie sehen das gesamte für Sie geschriebene C/C++, das direkt mit den Registern des AVR-Mikrocontrollers interagiert. Wenn Sie lernen möchten, wie man solche Dinge schreibt (direkt für die Hardware), dann gibt es viel zu tun. Wenn Ihr Ziel darin besteht, etwas mit ihren Bibliotheken zum Laufen zu bringen, gibt es möglicherweise nicht viel zu besprechen, da die meiste harte Arbeit für Sie erledigt wird und ihre Bibliotheken und Entwicklungsumgebungen sehr einfach zu bedienen sind.
Einige Faustregeln bei der Arbeit mit ressourcenbeschränkten Geräten, die entweder für Arduino-Umgebungen oder andere gelten könnten:
Achten Sie darauf, wie viel Speicher Sie verwenden. Sowohl die Codegröße (die in den Flash-Speicher geht) als auch die statische RAM-Nutzung (Konstanten in Ihrem Code, die immer im RAM vorhanden sind). Ich würde argumentieren, dass die statische RAM-Nutzung am Anfang etwas wichtiger ist, da sie leicht zu übersehen ist. Es ist nicht ungewöhnlich, dass Sie nur 1000 Bytes für Ihren Stack, Heap und Ihre Konstanten haben. Seien Sie klug, wie Sie es ausgeben, vermeiden Sie also Dinge wie lange Arrays von Ganzzahlen (jeweils 4 Bytes), wenn Bytes oder Zeichen ohne Vorzeichen (jeweils 1 Byte) ausreichen. Eine andere Antwort hier deckt einige andere wichtige Punkte sehr gut ab, also höre ich hier auf. Ich wollte hauptsächlich klarstellen, dass es viel zu behandeln gibt, wenn Sie die Arduino-Bibliothek nicht verwenden und Ihre eigenen C-Bibliotheken schreiben.
In Bezug auf die Programmierung von Mikrocontroller und OOP sind sie keine Gegensätze. Es stimmt, dass alle Herstellerbibliotheken in reinem C vorliegen, aber alle Plattformen unterstützen auch C++ OOP. Entwickler können darüber hinaus C++ High-Level-Bibliotheken und Geräte-Firmware erstellen und erstellen. Das gute Beispiel sind Arduino-Bibliotheken, offizielle und vom Benutzer erstellte - hauptsächlich C++-Klassen. Möglicherweise können nicht alle OOP-Vorteile in einer eingebetteten Umgebung vollständig genutzt werden, aber auch hier gelten die bekannten Vorteile von C++ gegenüber C.
In Bezug auf die Denkweise und das Denken sind Mikrocontroller, wie in anderen Antworten erwähnt, sehr ressourcenbeschränkte Plattformen (insbesondere im RAM, weniger in der Geschwindigkeit) - Dinge wie die dynamische Speicherzuweisung, C++-Ausnahmen sind normalerweise ausgeschlossen. Wenn die richtige Hardware ausgewählt ist, ist es einfach, sich an diese Einschränkungen anzupassen und andere Techniken zu verwenden (die auch auf anderen Plattformen weit verbreitet sind).
Meiner Ansicht nach könnte die schwierigere Herausforderung eine weitere zusätzliche Dimension sein, die in der eingebetteten Programmierung zu finden ist – das Timing. Dies liegt daran, dass eingebettete Software normalerweise viel mit Echtzeitereignissen, streng zeitgesteuerten Protokollen zum Ansteuern von Peripheriehardware und allgemeinen Aufgaben selbst zu tun hat (dies sind auch einige Parallelen zu anderen "High-Level" -Plattformen, wie z. B. Multithread-Anwendungen).
Seien Sie bereit, viele Datenblätter zu lesen, wenn Sie sich mit neuer Hardware befassen - ich denke, es könnte mit dem Fragenteil "Mindset" zusammenhängen :) Sicherlich wären einige EE- und Hardwarekenntnisse erforderlich.
Ich möchte auch darauf hinweisen, dass die Entwicklung eingebetteter Software heutzutage keine Assemblersprache erfordert. Tatsächlich ist Java (übrigens ist es standardmäßig OOP) bereits da und wird stärker (zumindest für einige Klassen von eingebetteten Geräten, zum Beispiel IoT-Geräten, könnte es eine sehr gute Zukunft haben).
drxzcl
Jon L
rrazd
Nur Jeff
Jon L
DarenW
stevenvh