Hallo, ich interessiere mich für die Mikrocontrollerwelt, habe noch sehr
wenig Erfahrung darin. Ich habe aus privatem Interesse heraus auch etwas
Erfahrung mit C++ (Variablen, Datentypen, Schleifen, Funktionen,
Strukturen, Zeiger). Es gibt hier zwei große Fraktionen wie man erkennen
kann: AVR ud PIC. Ich tendiere eher zum PIC (warum auch immer). Aber
jetzt kommt das Problem, es gibt dafür keine C++ Compiler. Was mache ich
nun wenn ich C nicht kenne? C soll ja fast gleich mit C++ sein, nur wenn
ich C nicht kenne weis ich auch nicht was ich nutzen kann und was nicht.
Oder kennt jemand doch einen C++ COmpiler?
Johan schrieb:> nur wenn> ich C nicht kenne weis ich auch nicht was ich nutzen kann und was nicht.
da du eh lernen muss für einen µC zu programmieren, kannst du auch
gleich noch C lernen.
Der Compiler sagt dir schon was er nicht kennt.
> Variablen, Datentypen, Schleifen, Funktionen, Strukturen, Zeiger
das klingt nicht nach C++ sondern nach C.
C++ sind dann Klassen, Objekte, Templates
The MPLAB XC32++ compiler adds the flexibility to develop and reuse C++ projects and components for all 32-bit MCU devices with the following benefits:
2
3
Compliant with the majority of C++98 and C++ 2003 ANSI standards
4
Includes Dinkumware Standard C++ Library
5
Can be used with all C++ or mixed C/C++ projects in MPLAB XC
6
All Microchip C language extensensions are available for use
7
8
Microchip is offering a special edition of our C++ compiler software completely free for filling out a short registration.
Peter II schrieb:> ist denn jeder pic ein 32bitter?
Nein, aber PIC32 wurden im OP nicht ausgeschlossen - aber das
Vorhandensein eines C++-Compilers für PIC-Mikrocontroller schon.
cyno
Johan schrieb:> Es gibt hier zwei große Fraktionen wie man erkennen> kann: AVR ud PIC.
Dazu kommt aber noch stark wachsend die 32 Bitter mit Cortex-M0/3/4 von
ST, NXP und weiteren. Für diese gibt es gcc toolchains und C++
Bibliotheken. Und da die Cortex-M oft für kleines Geld viel Speicher
haben lassen die sich auch gut mit C++ nutzen.
Es gab hier auch schon ellenlange Threads über C++ auf µCs, die enden
alle nur in einer üblen Schlammschlacht.
Wenn es unbedingt C++ sein soll - dann kommen eigentlich nur 32 Bit
Mikrocontroller in Frage.
Die Datenblätter sind so dick - da kann man nicht mehr jedes einzelne
Bit kennen. Du kannst nicht mehr direkt auf der Hardware programmieren.
Brauchst unbedingt die Libraries. Hat mehr Ähnlichkeit mit
PC-Programmierung als mit 8-Bit-Mikrocontriller Programmierung.
Pic32? Hier findest du eher Leute, die dir bei Problemen mit Stm32
weiter helfen können.
Ich hab C++ für mein letztes AVR-Projekt benutzt.
Mit GCC funktionierte das ohne Probleme. Natürlich
sollte man bzgl. Code-Größe die Finger von großen Template-Bibliotheken
(boost) lassen und die Standard-C(++)-Bibliothek ist natürlich
auch nicht so einfach da.
Aber um den C-Code strukturiert hinter ein paar Klassen
zu verstecken hat das gut gereicht.
Ich verstehe nur nicht ganz, wie man C++ kennen kann, aber C nicht.
Da im Grunde C++ eine (nicht ganz exakte) Übermenge von C ist.
Daher häufig auch "C/C++" genannt. Insbesondere bzgl.:
> (Variablen, Datentypen, Schleifen, Funktionen, Strukturen, Zeiger)
hat sich nichts nennenswertes zwischen C++ und C verändert.
Ich würde sagen, da müssen einfach nur die Kenntnisse über C/C++
vertieft werden. Angefangen bei den Grundlagen
(Variablen, Datentypen, Schleifen, Funktionen, Zeiger).
Ich möchte C++ auch auf kleinere Prozessoren nicht missen. Dazu gibt es
zu viele schöne Dinge an C++, die auch z.B. im AVR Bereich benutzt
werden können:
Klassen und Objekte zum Kapseln und Gruppieren von Daten.
Konstruktoren zum sauberen Inititalisieren.
Default-Parameter in Funktionen.
Funktionen mit unterschiedlichen Parametern.
Alles das macht den Code übersichtlicher und einfacher wartbar.
Templates, Exceptions, RTTI und dynamischen Speicher kann man ja erst
einmal weglassen.
Und sobald man im 32-Bit Bereich ist, sollte die Codegröße auch egal
sein.
> Alles das macht den Code übersichtlicher und einfacher wartbar.
Es ist zum Verzweifeln. Bei C++ bekommt man noch 10000 Features dazu,
die mehr Verwirrung als Nutzen bringen. In Java kann man die
MC-Bitfummelei nicht machen.
Ich will ein C + deine Liste an Features. Ohne diesen ganzen anderen
Kram!
Nach meiner Erfahrung (ca. 10 Jahre Embedded-Programmierung) hat C++ auf
MCUs diese Größenklasse keine Vorteile, außer dass man den Code
vielleicht besser lesen kann, wenn man schon viel C++-Erfahrung hat. Die
echten Stärken von C++ (Templates, Vererbung, dynamische Erzeugung von
Objekten usw.) sind üblicherweise auf so kleinen Architekturen nicht
sinnvoll nutzbar. Wenn Du mit den etwas größeren Eisen (ARM9-Klasse oder
PIC32) arbeitest, ist das natürlich eine andere Sache.
Ich denke, es wird Dir nicht schwer fallen, C zu lernen, wenn Du C++
kannst. Du kannst eben keine Klassen und Objekte erzeugen sondern musst
Dich auf die klassischen Funktionen beschränken. Aber bei PIC/AVR ist
das sicher kein Nachteil
Cihan S. schrieb:> Ist die Arduino IDE nicht C++?
in welcher Sprache die IDE geschrieben ist, spielt doch keine Rolle.
Ja. mit der Arduino IDE schreibt man C++ Programme. Für AVRs ist c++
kein Problem, wenn man es will.
... schrieb:> Nun, die Vorteile von c++ scheinen wohl endlich zu sein,> im z.B. Linux-Kernel spielt es keine Rolle.
Das hat weniger mit Vorteilen als mit VorURteilen zu tun.
Ulrich F. schrieb:> Historische Gründe?>> Damals, als Unix erfunden wurde, gabs da OOP überhaupt schon?
Du wirst lachen: ja
Simula: erster Compiler 1964/1965
Unix: 1969
Noch einer schrieb:> Die Datenblätter sind so dick - da kann man nicht mehr jedes einzelne> Bit kennen. Du kannst nicht mehr direkt auf der Hardware programmieren.> Brauchst unbedingt die Libraries.Noch einer schrieb:> Es ist zum Verzweifeln. Bei C++ bekommt man noch 10000 Features dazu,> die mehr Verwirrung als Nutzen bringen.
Beide Aussagen sprechen von einer Überforderung durch Informationen und
Optionen. Du solltest hier vorsichtig sein die eigenen Grenzen zu
verallgemeinern.
Besonders, da ein C++ Programm nicht deswegen ein C++ Programm ist, weil
es alle Möglichkeiten möglichst kompakt anwendet, sondern weil
mindestens eine Fähigkeit genutzt wird, die im ursprünglichen C nur über
Umwege zu realisieren ist.
Jede Software, dass Klassen statt Instanz-Strukturen als Ersatz für das
Klassenkonzept nutzt (siehe z.B. die ASF) würde ich vorziehen, wenn es
keine andere Rahmenbedingung gibt, die dem Einsatz widerspricht. (Diese
gibt es im Fall der ASF, und sie ist eher logistischer denn technischer
Natur)
Karl H. schrieb:> Du wirst lachen: ja> Simula: erster Compiler 1964/1965
Ei!
64.... erster Schultag...
Kein Wunder, dass das an mir vorbei gegangen ist...
;-)
Robin R. schrieb:> Ich verstehe nur nicht ganz, wie man C++ kennen kann, aber C nicht.
Kann ich auch nicht so ganz nachvollziehen.
Man kann in C++ prozedural programmieren - dann ist es nahezu das
Gleiche wie üblicher C-Code.
Und tatsächlich kann man in C auch objektorientiert programmieren, wenn
man es unbedingt will. GTK+ macht's vor.
... schrieb:> Nun, die Vorteile von c++ scheinen wohl endlich zu sein,> im z.B. Linux-Kernel spielt es keine Rolle.
Auch der Windows-Kernel ist in C geschrieben.
Die meisten C++-Fähigkeiten sind in einem Kernel nicht nutzbar
(Exceptions) oder nur eingeschränkt sinnvoll (Templates, dynamischer
Speicher), und den Kernel in C zu schreiben verhindert zuverlässig, dass
ein Entwickler, der das nicht weiß, es auch nicht versucht. Im Prinzip
ist das der gleiche Grund wie auf einem Mikrocontroller: Ja, es geht,
aber man muss wissen, was man tut.
Davon abgesehen ist es nicht sinnvoll, den Linux-Kernel auf C++
umzuschreiben, weil die Infrastruktur in C vorhanden und getestet ist
und der Vorteil durch C++ den Aufwand nicht wettmacht. Das ist z.B. bei
gcc anders.
>Beide Aussagen sprechen von einer Überforderung durch Informationen und>Optionen. Du solltest hier vorsichtig sein die eigenen Grenzen zu>verallgemeinern.
Nö. Ich mach das bald 40 Jahre. Hab mit Assembler auf ZX80 angefangen
und dann alles mögliche gemacht. Hier handelt es sich um zwei andere
Probleme.
Im laufe der Jahrzehnte hat sich die Programmierung komplett geändert.
In die Register eines 8-Bit Controllers, oder auch in ein DOS-Programm
konnte man sich noch vollständig einarbeiten. Heutzutage ist es so
umfangreich - bis man alle Detail durchgearbeitet hat, ist es schon
wieder veraltet.
Es spaltet sich auf - der eine schreibt Python-Libraries für
Raspberry-Peripherie, der andere schreibt damit Web-Oberflächen für
Steuerungen. Pic32 liegt vielleicht noch an der Grenze, wo sich einer
alleine in alles einarbeiten kann. Bei Cortex-A geht das nicht mehr.
Und dann kommt noch etwas total bescheuertes dazu:
20 Entwickler lösen innerhalb eines Programmes 30 gleichartige Probleme
auf 40 verschiedene Arten. C++ ist da am schlimmsten. Man findet in
einem Programm alles von K&R bis Java-Stil; Selbst gebastelte Container
mit obskurer Garbage-Collection neben QList, STL und alten C-Arrays;
Präprozessor-Tricksereinen neben Inline-Funktionen.
Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während
man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon
wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut.
Das ist natürlich ein schlagkräftiges Argument: weil es manche/ viele
nicht oder zu gut beherrschen, sollte man auch von dien guten
Eigenschaften von C++ die Finger weg lassen.
Logik ist für mich ein wesentlicher Bestandteil des Programmierens (ich
verwende das Wort für den ganten Vorgang der Softwareerstellung) und muß
unabhängig von der Implementierungssprache beherrscht werden. Und es
gibt Abhängigkeiten: ohne Logik brauche man gar keine Programmiersprache
und dann ist es egal welche man nicht brauche. Oder änderst ausgedrückt:
nicht Programmieren können, kann man ihn jeder Sprache gleich gut.
Carl D. schrieb:> Das ist natürlich ein schlagkräftiges Argument: weil es manche/> viele nicht oder zu gut beherrschen
... ist es nicht unbedingt die optimale Programmierform: Hochflexibel
ja, aber dafür hochkomplex. Im Ergebnis Software die besser sein könnte.
Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie
nötig.
Ds C++ auch C beinhaltet ist das mal wieder eine sinnlose "Diskussion"
oder besser "Talkshow".
Man kann jeden µC ob 1bit, 22bit oder 666bit mit
C++/c/Assembler/Fotran/XYZ programmieren.
Der Compiler macht aus der "Hochsprache" erstmal passenden Assembler der
dann in den OP-Code umgesetzt wird.
Lediglich der Overhead bei Bibliotheken o.ä. kann zu Flashmangel führen.
Man muß aber keine STL o.ä. ins µC Projekt einbauen wenn's keinen Sinn
macht.
C reicht idR für µC Projekte ist aber in C++ enthalten.
Ergo kann man auch µC in C++ programmieren und Kapselung nutzen ohne das
es einen wirklich negativen Effekt hat.
Noch einer schrieb:> Es ist zum Verzweifeln. Bei C++ bekommt man noch 10000 Features dazu,> die mehr Verwirrung als Nutzen bringen. In Java kann man die> MC-Bitfummelei nicht machen.http://www.harbaum.org/till/nanovm/index.shtml> Ich will ein C + deine Liste an Features. Ohne diesen ganzen anderen> Kram!
Du mußt "diesen ganzen anderen Kram" nicht benutzen. Dann ist C++
nämlich haargenau das, was Du willst: C plus die genannte "Liste an
Features".
Schlappohr schrieb:> Nach meiner Erfahrung (ca. 10 Jahre Embedded-Programmierung) hat C++ auf> MCUs diese Größenklasse keine Vorteile, außer dass man den Code> vielleicht besser lesen kann
Das reicht doch schon.
> Die> echten Stärken von C++ (Templates, Vererbung, dynamische Erzeugung von> Objekten usw.) sind üblicherweise auf so kleinen Architekturen nicht> sinnvoll nutzbar.
Vererbung und Templates sind vollkommen problemlos nutzbar und erzeugen
überhaupt keinen zusätzlichen Overhead. Aber selbst wenn Deine Prämisse
zuträfe und nurmehr die Datenkapselung übrig bliebe, wäre alleine dies
bereits ein hinreichend großer Vorteil für C++ auf Mikrocontrollern.
> Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie
nötig.
Zum Glück ist die Welt grösser als die Kanten deines Basteltischs. Was
glaubst denn, was das für Leute sind, die, nicht als Hoby (bewusst
gewählte Schreibweise!), die Dinge um dich herum mit Software Versehen
haben. Waren das alles Idioten? Oder gibt es doch nur einen
Geisterfahrer.
Noch einer schrieb:> Nö. Ich mach das bald 40 Jahre.Noch einer schrieb:> 20 Entwickler lösen innerhalb eines Programmes 30 gleichartige Probleme> auf 40 verschiedene Arten.Noch einer schrieb:> Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während> man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon> wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut.
Das ist aber eher das Versagen eines Prozesses, welcher der Senior
Developer zu führen hat. Aufgrund deiner Erfahrung sollte man annehmen,
dass du weisst, dass es mit den Prozessen und Entwicklungsstrukturen
steht und fällt, was für eine "Suppe" abgeliefert wird.
Das Problem hättest du gar vermehrt in noch ganz anderen Sprachen, die
eben noch mehr Design Pattern zulassen.
Die Frage ist nun, wer macht diesen Aspekt des Jobs? Ein Projektleiter
mit wenig Zeit oder Hingabe für diese "Details", ein erfahrender aber
zurückhaltender Entwickler, der besser bei seinen Leisten geblieben
wäre, oder ein Jungspund, der noch nicht verstanden hat, dass ohne einen
festen Rahmen alles verläuft, wie die Suppe auf nem flachen Teller, oder
tatsächlich ein erfahrener und führender Senior Developer?
@Sheeva Plug:
> Das reicht doch schon.
Wenn das eine genügend große Rolle spielt, dann ja. Aber ich nehme auch
keinen Lieferwagen zum Brötchen kaufen, nur weil er eine
Anhängerkupplung hat.
> Vererbung und Templates sind vollkommen problemlos nutzbar und erzeugen> überhaupt keinen zusätzlichen Overhead. Aber selbst wenn Deine Prämisse> zuträfe und nurmehr die Datenkapselung übrig bliebe, wäre alleine dies> bereits ein hinreichend großer Vorteil für C++ auf Mikrocontrollern.
Sicher kannst du das alles machen, aber wo ist der Nutzen? Die
Komplexität eines 15000-Zeilen-Progrämmchens, das nachher ein paar kB
Flash belegt, rechtfertigt kaum OOP. Besonders pikant wird die Sache,
wenn Dein Controller harte Echtzeitanforderungen erfüllen muss. Wenn Du
unter diesen Bedingungen anfängst, dynamisch Objekte zu erzeugen und zu
vernichten, dann stehen Dir ein paar schlaflose Nächte bevor (abgesehen
davon, dass z.B. PICs gar nicht genug RAM für solche Späße haben, und
im Flash kannst Du nun mal nichts dynamisch anlegen). Du kannst
natürlich am Anfang alle benötigten Objekte erzeugen und dann verwenden,
aber dann ist Dein Programm statisch und Du kannst es genauso gut in C
schreiben. Das hat zudem den Vorteil, dass Dir schon der Compiler sagt,
wenn Du den Speicher sprengst.
Ich will es mal so zusammenfassen: Die Verwendung von C++ auf kleinen
Controllern ist letztlich Geschmackssache. Echte Vorteile gibt's kaum,
weil Du meistens nur einen Subset von C++ nutzen kannst. Um auf das OP
zurück zu kommen: Ich würde sicher keinen Controller danach auswählen,
ob es dafür einen C++-Compiler gibt.
schlappohr schrieb:> @Sheeva Plug:>>> Das reicht doch schon.>> Wenn das eine genügend große Rolle spielt, dann ja. Aber ich nehme auch> keinen Lieferwagen zum Brötchen kaufen, nur weil er eine> Anhängerkupplung hat.
Und nicht alles was hinkt ist ein Vergleich. Besserer Vergleich (wenn es
den schon ein Vergleich, statt Argumente, sein muss), wäre: Ich bin froh
über meinen Gurt im Auto und benutze Ihn nicht nur auf der Autobahn,
sondern auch auf dem Weg zum Bäcker.
> Sicher kannst du das alles machen, aber wo ist der Nutzen?
Die Aussage "Das reicht doch schon." von Sheeva bezog sich auf: "außer
dass man den Code vielleicht besser lesen kann". Lesbarer Code ist ein
Nutzen, auch in "15000-Zeilen-Progrämmchen".
> Wenn Du> unter diesen Bedingungen anfängst, dynamisch Objekte zu erzeugen und zu> vernichten, dann stehen Dir ein paar schlaflose Nächte bevor
das hat überhaupt niemand vorgeschlagen. "Vererbung und Templates"
lassen sich ganz hervorragend ohne dynamische Speicherverwaltung nutzen.
> Ich will es mal so zusammenfassen: Die Verwendung von C++ auf kleinen> Controllern ist letztlich Geschmackssache. Echte Vorteile gibt's kaum,
Wenn es Vorteile gibt, dann nutze ich sie. Einige C compiler sind eh nur
noch abgespeckte C++ compiler, wenn ich so einen C compiler habe, muss
ich nur noch die Dateien anders benennen und ein anderen
Compiler-Schalter setzen um diese Vorteile zu nutzen:
- keine implizite Konvertierung von void*
- namespaces
- templates
- überladende Funktionen
- Operatoren für eigene Typen
- typesichere enums
- //-Kommentare
- constexpr
- Konstruktoren / Destruktoren
- umfangreichere Standardlibraries:
- crc
- random number generators
- algorithmen (Suchen, Sortieren, Permutieren...)
Alles für "umsonst" zu haben. Ansonsten lässt sich C++ auch ganz
hervorragen in der Verbindung mit C verwenden.
> weil Du meistens nur einen Subset von C++ nutzen kannst. Um auf das OP> zurück zu kommen: Ich würde sicher keinen Controller danach auswählen,> ob es dafür einen C++-Compiler gibt.
Das liegt eher an dem Subset von C++, das Du kennst.
mfg Torsten
Torsten R. schrieb:> Compiler-Schalter setzen um diese Vorteile zu nutzen:>> - keine implizite Konvertierung von void*> - namespaces> - templates> - überladende Funktionen> - Operatoren für eigene Typen> - typesichere enums> - //-Kommentare> - constexpr> - Konstruktoren / Destruktoren> - umfangreichere Standardlibraries:> - crc> - random number generators> - algorithmen (Suchen, Sortieren, Permutieren...)
- Möglichkeit der Datenkapselung mit private und protected (ja, ich
weiss, man kann sie umgehen) und inline Gettern/Settern -> kein runtime
Penalty und trotzdem kann ich wilden Zugriffen auf Variblen einen Riegel
vorschieben.
Zum Thema: 15 Programmierer lösen dieselbe AUfgabe auf 40 verschiedene
Arten:
Das Problem hast du in C genauso. Das ist kein Problem der Sprache
sondern ein Problem der Teamführung. Code Review von Anfang an und
regelmässige Meetings in denen Richtlinien ausgegeben werden, schaffen
da schnell Abhilfe. Muss man sich in einem Code Review verantworten,
dann werden auch weniger 'Schweinereien' gemacht, in denen Mechanismen
absichtlich ausgehebelt werden.
schlappohr schrieb:> Du kannst> natürlich am Anfang alle benötigten Objekte erzeugen und dann verwenden,> aber dann ist Dein Programm statisch und Du kannst es genauso gut in C> schreiben.
Wie bitte? Ob Objekte dynamisch oder statisch erzeugt werden, sagt nun
wirklich nichts darüber aus, welche Sprache sinnvoll ist. Umgekehrt
zwingt einem die Sprache auch keine dynamische Allozierung auf. Auch in
vielen grösseren C++-Projekten braucht man höchst selten dynamische
Speicherallokation mit 'new' oder dessen RAII-Wrappern.
Dass man mit so viel Halbwissen alle drei Wochen einen Thread mit 500
Beiträgen füllen kann, ist schon amüsant.
schlappohr schrieb:> Wenn das eine genügend große Rolle spielt, dann ja. Aber ich nehme auch> keinen Lieferwagen zum Brötchen kaufen, nur weil er eine> Anhängerkupplung hat.
Abgesehen davon, daß die Sinnhaftigkeit eines Lieferwagens und seiner
Anhängerkupplung zum Brötchenholen direkt von der Menge der zu kaufenden
Brötchen abhängt, bleiben mir der Sinn sowie der Realitätsbezug dieses
merkwürdigen Vergleiches leider verschlossen.
>> Vererbung und Templates sind vollkommen problemlos nutzbar und erzeugen>> überhaupt keinen zusätzlichen Overhead. Aber selbst wenn Deine Prämisse>> zuträfe und nurmehr die Datenkapselung übrig bliebe, wäre alleine dies>> bereits ein hinreichend großer Vorteil für C++ auf Mikrocontrollern.>> Sicher kannst du das alles machen, aber wo ist der Nutzen? Die> Komplexität eines 15000-Zeilen-Progrämmchens, das nachher ein paar kB> Flash belegt, rechtfertigt kaum OOP.
Muß man OOP jetzt rechtfertigen? So ein Unsinn. OOP ist nur ein
Paradigma zur Organisation von Sourcecode, um die Wiederverwendbarkeit,
Wartbarkeit und Übersichtlichkeit zu verbessern. Daß die OOP hilft,
diese Designziele besser und einfacher umzusetzen als mit anderen
Paradigmen, genügt schon, um ihren Einsatz in jeder möglichen Umgebung
nicht nur zu rechtfertigen, sondern sogar zu empfehlen. Für alle
Entwickler, die dieses ausgesprochen mächtige und leistungsfähige
Werkzeug beherrschen, ist die OOP eine große Vereinfachung und
Erleichterung ihrer Arbeit.
> Besonders pikant wird die Sache, wenn Dein Controller harte> Echtzeitanforderungen erfüllen muss.
Auch das ist mit C++ überhaupt kein Problem -- jedenfalls kein größeres,
als es mit C eins wäre. Zum Glück kann man, wenn man die genaue
Kontrolle über die verbrauchten Taktzyklen benötigt, selbstverständlich
problemlos auch Assembler-Code in C++ integrieren -- genau wie in C.
> Wenn Du unter diesen Bedingungen anfängst, dynamisch Objekte zu erzeugen > und
zu vernichten, dann stehen Dir ein paar schlaflose Nächte bevor
So ein Unsinn. Die dynamische Erzeugung und Zerstörung von Objekten hat
zunächst einmal überhaupt gar nichts mit der OOP zu tun. Kennst Du C's
"malloc()"- und "free()"-Funktionen nicht? Die werden im
Mikrocontroller-Umfeld auch selten genutzt. Allerdings nicht, weil dafür
nicht genügend Rssourcen zur Verfügung stehen, sondern weil das bei den
meistens eher einfachen Mikrocontroller-Programmen nicht notwendig ist.
Und genau aus demselben Grund braucht man das auch mit C++ oder anderen
OO-Sprachen in diesem Umfeld eher selten. Möglich und ganz, ganz selten
sogar sinnvoll ist es aber trotzdem, und ich habe das auch schon ganz
ohne schlaflose Nächte benutzt. Trotzdem Dank für Deine Sorge um meine
Nachtruhe.
> Ich will es mal so zusammenfassen: Die Verwendung von C++ auf kleinen> Controllern ist letztlich Geschmackssache. Echte Vorteile gibt's kaum,> weil Du meistens nur einen Subset von C++ nutzen kannst. Um auf das OP> zurück zu kommen: Ich würde sicher keinen Controller danach auswählen,> ob es dafür einen C++-Compiler gibt.
Ich schon. Weil nämlich die Untermenge von OOP-Features, die auf einem
Mikrocontroller sinnvoll und gewinnbringend genutzt werden können, so
umfangreich und nützlich ist, daß sich die OOP in den meisten Fällen
einfach lohnt und signifikante Vorteile bietet. Daß die sich dem Laien
möglicherweise nicht erschließen, spricht nicht gegen ihre Existenz.
Keine Frage: auf Mikrocontrollern (und auch in den meisten anderen
Fällen) geht es auch ohne OOP. Aber mit geht es fast immer viel
leichter.
Nimm halt nicht so einen grottigen Controller.
PIC und AVR sind Relikte aus dem letzten Jahrtausend.
Schau dir mal die Gecko Reihe von Silabs oder die STM32 an. DAS sind
Controller auf denen man arbeiten möchte. Ggf. noch MSP430 mit FRAM von
TI.
Der AVR Kram ist aufm Arduino oder so noch ok, aber wenn man wirklich
damit arbeiten möchte sind diese in meinen Augen nicht mehr zeitgemäß.
Und sollte jetzt die Fraktion "aber wenn 8bit reichen" auftauchen: Dann
arbeitet gefälligst gleich mit einem 8051, der ist dann sicher auch
ausreichend und in der Massenproduktion bestimmt auch viel billiger.
Aber hier im Hobbybereich und auch in vielen Firmen tut man sich mit ARM
einen Gefallen, allein schon der Segger J-Link Edu für 50€ ist Gold wert
im Vergleich zu den Debuggern von Microchip (tolle GPL Violation begehen
die übrigens) oder Atmel.
Michael schrieb:> Der einfachste Weg um als Neuling mit C++ auf einem Controller zu> starten ist Arduino.
Wobei Arduino eine recht schlechte C++-Umsetzung für den Zugriff auf die
AVR-Hardware verwendet.
Mit ein bischen mehr C++ (Templates etc) hätte man das "digitalWrite"
usw. so hinkriegen können, dass der GCC es zu exakt einer
ASM-"Set-Bit"-Instruktion optimiert.
So befeuert Arduino nur die Vorurteile, dass C++ auf µC "zu langsam"
sei.
Planlos schrieb:> So befeuert Arduino nur die Vorurteile, dass C++ auf µC "zu langsam"> sei.
Michael schrieb ja auch vom "einfachsten" Weg, nicht dem besten Weg ;-)
SCNR
Wie immer verläuft auch diese Diskussion, wenn es um C versus C++ geht.
Man könnte meinen, dass Diskussionen sinnlos seien - vor allem in diesem
Forum.
Darf ich anregen, das Thema PIC versus AVR versus ARM nochmal zu
vertiefen? :-)
Stefan U. schrieb:> Darf ich anregen, das Thema PIC versus AVR versus ARM nochmal zu> vertiefen? :-)
Ja, bitte! Ich überlege schon die ganze Zeit, ob ich mir mit
meinen Arduinos und AVR DILs einen Gefallen tue. Und obs nicht
evtl. besser wäre sich mal STM32 anzusehen für meinen Briefkasten-Melder
mit Blink-LED. Aber 3,3V vs. meine ganzen 5V-Bauteile ist dann auch
wieder ein Problem. Oder soll ich gleich 1,8V nehmen, weil 3,3V
schon nicht mehr "Zeitgemäß" ist? ;-)
Robin R. schrieb:> Und obs nicht> evtl. besser wäre sich mal STM32 anzusehen für meinen Briefkasten-Melder> mit Blink-LED.
Nenene... immer der größten Community folgen!
Der logische Schritt ist Arduino --> RaspberryPI, nicht AVR --> STM32!
Noch einer schrieb:> Die Datenblätter sind so dick - da kann man nicht mehr jedes einzelne> Bit kennen. Du kannst nicht mehr direkt auf der Hardware programmieren.> Brauchst unbedingt die Libraries. Hat mehr Ähnlichkeit mit> PC-Programmierung als mit 8-Bit-Mikrocontriller Programmierung.
So ein Unsinn. Schau bitte mal ins Reference-Manual eines beliebigen ARM
Cortex-Mx Controllers. Die Controller sind kaum komplexer als die
gängigen 8Bit Mikrocontroller, allerdings kann die Peripherie oft mehr.
Die Libraries braucht man ebenfalls nicht.
Karl H. schrieb:>> Compiler-Schalter setzen um diese Vorteile zu nutzen:>>>> - keine implizite Konvertierung von void*>> - namespaces>> - templates>> - überladende Funktionen>> - Operatoren für eigene Typen>> - typesichere enums>> - //-Kommentare>> - constexpr>> - Konstruktoren / Destruktoren>> - umfangreichere Standardlibraries:>> - crc>> - random number generators>> - algorithmen (Suchen, Sortieren, Permutieren...)>> - Möglichkeit der Datenkapselung mit private und protected (ja, ich> weiss, man kann sie umgehen) und inline Gettern/Settern -> kein runtime> Penalty und trotzdem kann ich wilden Zugriffen auf Variblen einen Riegel> vorschieben.
- static_assert
Planlos schrieb:> Michael schrieb:>> Der einfachste Weg um als Neuling mit C++ auf einem Controller zu>> starten ist Arduino.>> Wobei Arduino eine recht schlechte C++-Umsetzung für den Zugriff auf die> AVR-Hardware verwendet.
Eigentlich nicht. Ja, im Vergleich zu anderen Lösungsmöglichkeiten ist
das ineffizient, aber das Designziel der Arduino-Umgebung war und ist ja
nicht die Effizienz, sondern die Einfachheit. Kernthema des
Arduino-Projekts ist schließlich, die Welt der
Mikrocontroller-Programmierung auch für weniger technikaffine Menschen
möglichst einfach zugänglich zu machen, und dieses Ziel wurde IMHO
hervorragend erreicht.
> Mit ein bischen mehr C++ (Templates etc) hätte man das "digitalWrite"> usw. so hinkriegen können, dass der GCC es zu exakt einer> ASM-"Set-Bit"-Instruktion optimiert.
Ja. Aber das hätte dem Designziel widersprochen. Aber wenn Du möchtest,
kannst Du auch in der Arduino-Umgebung an den Bits herumpopeln, um die
maximale Effizenz bei minimaler Codegröße zu erreichen.
Sheeva P. schrieb:> Eigentlich nicht. Ja, im Vergleich zu anderen Lösungsmöglichkeiten ist> das ineffizient, aber das Designziel der Arduino-Umgebung war und ist ja> nicht die Effizienz, sondern die Einfachheit.
was wäre an der ineffizienteren Lösung komplizierter gewesen? Man hätte
beides haben können.
Sheeva P. schrieb:> Aber das hätte dem Designziel widersprochen.
Naja...
Wenn man z.B. bereit wäre,
statt
1
LiquidCrystallcd(12,11,5,4,3,2);
etwas in dieser Art zu schreiben:
1
LiquidCrystal<12,11,5,4,3,2>lcd;
dann hätte der Compiler viel viel mehr Möglichkeiten zur Optimierung.
Ok, Compile-Zeit steigt dabei etwas an, aber solang man nicht grad einen
ganzen Sack von LCDs gleichzeitig am Arduino betreiben will, spart man
enorm Flash.
und soooo viel komplizierter wäre die zweite Schreibweise auch nicht.
Davon abgesehen, dass die sowieso in 99% der Fälle durch Copy&Paste aus
dem Tutorial in den Programmcode wandert.
Der Arduino Jünger, erwartet, dass ein digitalWrite() den pin auch auf
das gewünschte Potential zieht.
Und das bekommt er!
Dazu muss digitalWrite(), unter Umständen, eine auf dem Pin laufende PWM
abschalten.
Planlos schrieb:> Wenn man z.B. bereit wäre,> stattLiquidCrystal lcd(12, 11, 5, 4, 3, 2);>> etwas in dieser Art zu schreiben:LiquidCrystal<12, 11, 5, 4, 3, 2> lcd;
Ach, das ist ja nur eine Lib...
Die kann man sich machen, wie man will...
Und vielleicht wirds ja mal so umgesetzt.
Andere Libs machen das schon so.
Carl D. schrieb:>> Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie nötig.> Zum Glück ist die Welt grösser als die Kanten deines Basteltischs. Was> glaubst denn, was das für Leute sind, die, nicht als Hoby (bewusst> gewählte Schreibweise!), die Dinge um dich herum mit Software Versehen> haben. Waren das alles Idioten? Oder gibt es doch nur einen> Geisterfahrer.
Eine adäquate Antwort auf mein Argument war das nun nicht gerade ...
Und schau Carl, kein Basteltisch der Welt existiert für sich allein.
Da gelten die gleichen Gesetze so wie überall. Man sollte sich immer vom
Verstand inspirieren lassen- und nicht von blinder Emotion so wie Du
gerade.
Stefan U. schrieb:> Man könnte meinen, dass Diskussionen sinnlos seien - vor allem in diesem> Forum.> Darf ich anregen, das Thema PIC versus AVR versus ARM nochmal zu> vertiefen? :-)
Nein sind sie ganz und gar nicht. Es könnte um ganz grundlegende
Weichenstellungen gehen! Ich möchte anregen, immer die realen
Bedürfnisse der konkreten oder zukünftig geplanten App im Auge zu
behalten. Sie ist es doch, die letztlich nützt, die motivieren und keine
unnötige, kontraproduktiv frustrierende Arbeit machen soll. Deshalb ist
Einfachheit so wichtig. Dann kommt der Spaß von ganz allein!
Moby A. schrieb:> Carl D. schrieb:>>> Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie nötig.>>> Zum Glück ist die Welt grösser als die Kanten deines Basteltischs. Was>> glaubst denn, was das für Leute sind, die, nicht als Hoby (bewusst>> gewählte Schreibweise!), die Dinge um dich herum mit Software Versehen>> haben. Waren das alles Idioten? Oder gibt es doch nur einen>> Geisterfahrer.>> Eine adäquate Antwort auf mein Argument war das nun nicht gerade ...
Weil deine Aussage schon Quatsch war.
Deine Ansage war, dass nicht allzuviele eine Sprache wie C++ gut genug
beherrschen.
Das ist Unsinn. Es gibt jede Menge C++ Programmierer, die ihr Werkzeug
mehr als ausreichend gut beherrschen. Du tust gerade so, als ob das
Raketentechnik wäre, für die es weltweit nur eine Handvoll Spezialisten
gibt. Dem ist nicht so.
Lass dich nicht vom Forum hier in die Irre führen. Wir sehen hier nur
die, die zu faul oder zu arrogant sind, ihre Programmiersprache auch zu
erlernen. Zumal es für die µC Programmierung da gar nicht so viel aus
der Sprache benötigt. Auf jeden, der hier hilfesuchend aufschlägt,
kommen tausende, die mehr als genügend Ahnung haben.
Karl H. schrieb:> Lass dich nicht vom Forum hier in die Irre führen. Wir sehen hier nur> die, die zu faul oder zu arrogant sind, ihre Programmiersprache auch zu> erlernen. Zumal es für die µC Programmierung da gar nicht so viel aus> der Sprache benötigt. Auf jeden, der hier hilfesuchend aufschlägt,> kommen tausende, die mehr als genügend Ahnung haben.
Und wenn ich das hinzufügen darf:
Die Programmiersprache ist letzten Endes nur ein Werkzeug. Ein Werkzeug
um damit Algorithmen zu implementieren. Und da fängt dann Informatik
erst richtig an. Das was du unter Optimierung verstehst, das sind alles
nur Peanuts in Relation dazu, was man mittels Algorithmen-Arbeit noch
aus einem Computer herausholen kann.
Auf diese Ebene wirst du aber nie vorstossen, wenn du deine Zeit damit
verplemperst dir zu überlegen welcher Branch Befehl denn jetzt
eigentlich der richtige wäre und wie der vorhergehende Compare gestaltet
sein muss, damit du 2 Taktzyklen einsparen kannst, die global gesehen
völlig irrelevant sind. Ein Quicksort schlägt einen Bubblesort nicht
deswegen, weil die Vergleichsbefehle so taktsparend programmiert wären.
Ein Travelling Salesman ist nicht deswegen schwer, weil man nicht
wüsste, wie man Speicher schnell indirekt adressieren könnte. Ein
Simplex lebt nicht davon, dass Array Operationen besonders taktsparend
implementiert werden können.
Da gibt es noch eine ganze Wissens-Welt, die auf dich wartet und die es
zu erforschen gilt.
@Sheeva Plug
> [...]bleiben mir der Sinn sowie der Realitätsbezug dieses> merkwürdigen Vergleiches leider verschlossen.
Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen
braucht.
Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen
MCU sinnvoll nutzen kann.
Sorry wenn das zu kompliziert war.
> Muß man OOP jetzt rechtfertigen? So ein Unsinn. OOP ist nur ein
Wenn ich als Projektleiter entscheiden soll, ob wir auf eine andere
Controller-Architektur umsteigen, die ein anderes Konzept hat, teurer
ist, Einarbeitung in eine neue Toolchain erfordert und am Ende dasselbe
leistet, und das nur weil jemand C++ toll findet, ja, dann verlange ich
eine Rechtfertigung. Für einen Hobbybastler mag das vielleicht keine
Rolle spielen.
> OOP ist nur ein> Paradigma zur Organisation von Sourcecode, um die Wiederverwendbarkeit,> Wartbarkeit und Übersichtlichkeit zu verbessern.
<Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++
Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere
Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem, das nur
Sinn macht, wenn Du es auch nutzt. Die komfortablen Sprachlemente
bezahlst Du immer mit einem ineffizienteren Maschinencode (bei jeder
Sprache). Das ist einer der Gründe, warum viele MCU-Hersteller eben
(noch) keinen C++-Compiler anbieten.
> Auch das ist mit C++ überhaupt kein Problem -- jedenfalls kein größeres,
Ich rede nicht von Assembler-Inlining. Ich rede davon, dass Code, der
dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit
schwieriger vorherzusagen ist. Deswegen wird in RT-Systemen
üblicherweise alles so weit wie möglich statisch gemacht, und damit geht
ein wesentlicher Vorteil von C++ verloren.
Dabei sind dynamische Objekte nur ein Aspket von vielen. Realtime-C++
ist ein ziemlicher Act, da gibt es ganze Fachbücher drüber. Und der
allgemeine Konsens ist: Wenn es nicht unbedigt sein muss, dann lass es
sein. Es gibt ein nettes Zitat von Linux Torvalds: "writing kernel code
in C++ is a BLOODY STUPID IDEA [...]" und das, obwohl Linux nicht mal
echtzeitfähig ist. Noch ein schönes Zitat von einer Webseite von Texas
Instruments: "Do not think that Embedded C++ code is always more
efficient. Even the C++ features allowed by Embedded C++ can be used
poorly, with ill effect. The bad news is you have to understand the
efficiency aspects of the C++ code you write.[...]". Deine
OOP-Always-and-Everywhere-These solltest Du also nochmal überdenken.
> Kennst Du C's "malloc()"- und "free()"-Funktionen nicht? Die werden im
Das ist jetzt aber nicht Dein Ernst, oder? malloc reserviert Speicher,
das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht. Der
Aufruf eines Konstruktors legt Datenstrukturen an, kopiert Code falls
notwendig und ruft Initialiserungsfunktionen und weitere Konstrktoren
auf. Je nach Art der Klasse ist das geringfügig komplizierter, stimmst
Du mir da zu?
> Die werden im> Mikrocontroller-Umfeld auch selten genutzt. Allerdings nicht, weil dafür> nicht genügend Rssourcen zur Verfügung stehen, sondern weil das bei den> meistens eher einfachen Mikrocontroller-Programmen nicht notwendig ist.
So ist es. Genau das ist der Punkt. Und jetzt erklär mir mal bitte,
warum Du unbedingt einen Compiler verwenden willst, der dynamische
Objekte unterstützt, obwohl Du die nie brauchst. Oder Exceptions. Oder
dynamische Typprüfung. Wenn Du einen Compiler hast, der das alles kann,
ok. Aber warum Du die Entscheidung für einen Prozessortyp davon abhängig
machen willst, kann ich nicht nachvollziehen.
C++ ist eine der komplexesten Programmiersprachen, die es gibt. Für
einen MCU-Anfänger ist C++ daher ein gutes Mittel, um den Frust zu
maximieren. Gerade auch wenn man ganz unbedarft anfängt, C++ wie auf dem
PC zu nutzen.
schlappohr schrieb:> @Sheeva Plug>>>> [...]bleiben mir der Sinn sowie der Realitätsbezug dieses>> merkwürdigen Vergleiches leider verschlossen.>> Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen> braucht.> Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen> MCU sinnvoll nutzen kann.> Sorry wenn das zu kompliziert war.
Ja ok.
Aber wenn ich keinerlei Nachteile damit habe, mit dem Lieferwagen zu
fahren, dann spricht auch nichts dagegen ihn zu benutzen.
> Wenn ich als Projektleiter entscheiden soll, ob wir auf eine andere> Controller-Architektur umsteigen, die ein anderes Konzept hat, teurer> ist, Einarbeitung in eine neue Toolchain erfordert und am Ende dasselbe> leistet, und das nur weil jemand C++ toll findet,
versteh ich nicht.
Was hat jetzt die andere Controller-Architektur mit C++ zu tun?
Die einzig relevante Frage lautet: gibt es dafür einen C++ Compiler - ja
oder nein?
Und dieselbe Frage stellt sich auch bei einem C Compiler.
> <Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++> Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere> Speicherverwaltung.
Äh. Nein.
> Sie haben ein komplizierteres Runtimesystem, das nur> Sinn macht, wenn Du es auch nutzt.
Aber der springende Punkt ist doch: wenn ich nicht will, dann muss ich
Teile davon nicht nutzen. Auch für C++ gilt: You don't pay for what you
don't use.
> Die komfortablen Sprachlemente> bezahlst Du immer mit einem ineffizienteren Maschinencode (bei jeder> Sprache).
Wo hast du denn das her?
Soll heissen: dieses Vorurteil hält sich schon so lange, so lange es C++
Compiler gibt. Richtig wird es dadurch aber auch nicht.
> Das ist einer der Gründe, warum viele MCU-Hersteller eben> (noch) keinen C++-Compiler anbieten.
?
Da viele MCU Hersteller als allererstes auf den gcc setzen anstatt eine
Eigenentwicklung zu starten, ist das ein etwas müdes Argument.
Eines ist natürlich klar: ein C Compiler ist schneller entwickelt als
ein C++ Compiler. Allerdings muss man das auch nicht. Mit dem gcc steht
ein Werkzeug zur Verfügung, mit dem ein C++ Compiler auch nicht mehr
Aufwand ist als ein C Compiler, weil nur das Backend angepasst werden
muss. Dann geht zb auch Fortran damit in einem Aufwasch.
> Ich rede nicht von Assembler-Inlining. Ich rede davon, dass Code, der> dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit> schwieriger vorherzusagen ist.
Ja.
Und wir reden davon, dass das in C auch nicht anders ist, WENN du
dynamisch zur Laufzeit Objekte erzeugst.
Die Lösung ist da wie dort dieselbe: tus einfach nicht, wenn du nicht
musst!
> Deswegen wird in RT-Systemen> üblicherweise alles so weit wie möglich statisch gemacht, und damit geht> ein wesentlicher Vorteil von C++ verloren.
Und wie gezeigt und aufgezählt wurde, bleibt dann von C++ immer noch
genügend übrig, was einen Einsatz rechtfertigen kann.
> Das ist jetzt aber nicht Dein Ernst, oder? malloc reserviert Speicher,> das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht.
Ja. Und.
Was dankst du was new macht?
Genauso einen Eintrag in eine Tabelle. Und zusätzlich wird noch ein
Konstruktor aufgerufen, wenn es sich um ein Klassenobjekt handelt, das
über einen Konstruktor verfügt.
> Der> Aufruf eines Konstruktors legt Datenstrukturen an, kopiert Code falls> notwendig
Ah. Nein.
COde wird da überhaupt nicht kopiert. Und die Datenstruktur (genauer der
Speicher dafür) existiert schon, wenn der Konstruktor aufgerufen wird.
Das ist der Teil der Objektinstanziierung, der mittels new gemacht
wurde, WENN das Objekt dynamisch erzeugt wurde.
Der Unterschied zwischen
1
classA
2
{
3
public:
4
A():i_=5{}
5
6
private:
7
inti_;
8
};
9
10
intmain()
11
{
12
AmyA;
13
}
und
1
structA
2
{
3
inti_;
4
};
5
6
voidinit(structA*pA)
7
{
8
pA->i_=5;
9
}
10
11
intmain()
12
{
13
AmyA;
14
15
init(&myA);
16
}
ist ein rein syntaktischer.
Der daraus resultierende Maschinencode ist sehr wahrscheinlich Byte für
Byte identisch. Wenn überhaupt, dann werden sich Unterschiede in der
hinzugelinkten Runtime feststellen lassen. Diesen Preis zahlt man
allerdings nur einmal pro Programm.
> und ruft Initialiserungsfunktionen und weitere Konstrktoren> auf.
Ja und?
Wenn du in C eine init Funktion hast, die dir eine komplexe
Datenstruktur initialisiert, dann ist das doch genau dasselbe!
Der einzige Unterschied: In C kannst du den Aufruf als Programmierer
vergessen, in C++ kannst du es nicht vergessen.
Und wenn ich mal so zurückdenke, wieviele Bugs auf das Konto von
vergessenen Initialisierungen gehen, dann bin ich heilfroh, wenn mir der
Compiler nach jeder Objekt-Instanziierung (die genau gleich abläuft wie
in C) eine entsprechende Init-Funktion automatisch und ohne das ich
daran denken muss, einbaut.
> Je nach Art der Klasse ist das geringfügig komplizierter, stimmst> Du mir da zu?
Klar, stimmt da jeder zu.
Aber das ist doch gar nicht der springende Punkt. Der springende Punkt
ist, dass du für eine komplizierte Initialisierung in C genauso den
enstprechenden COde aufrufen musst.
Gibt es keine Initialisierung, dann bezahlst du auch in C++ keinen Preis
dafür. Der SPeicher wird allokiert und das wars. Genau gleich wie in C.
schlappohr schrieb:> Sie haben ein komplizierteres Runtimesystem, das nur> Sinn macht, wenn Du es auch nutzt. Die komfortablen Sprachlemente> bezahlst Du immer mit einem ineffizienteren Maschinencode
Das ist falsch und leider immernoch ein sehr verbreitetes Vorurteil.
Ineffizienter Maschinencode wird durch ineffiziente Programmierung
hervorgerufen, nicht durch die Sprache.
schlappohr schrieb:> Es gibt ein nettes Zitat von Linux Torvalds: "writing kernel code> in C++ is a BLOODY STUPID IDEA [...]" und das, obwohl Linux nicht mal> echtzeitfähig ist.
Nett ist ein blödes Wort, wenn etwas aus dem Kontext gerissen wird. Hat
auch nichts mit echtzeit zu tun gehabt, als er das sagte.
schlappohr schrieb:> Noch ein schönes Zitat von einer Webseite von Texas> Instruments: "Do not think that Embedded C++ code is always more> efficient. Even the C++ features allowed by Embedded C++ can be used> poorly, with ill effect.
Das ist tatsächlich schön, sagt es doch, dass man auch mit C++ schlecht
programmieren kann, aber im normalfall nicht ;-)
schlappohr schrieb:> malloc reserviert Speicher,> das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht.
Genau und der ganze Rest muss dann zu Fuss gegangen werden.
schlappohr schrieb:> So ist es. Genau das ist der Punkt. Und jetzt erklär mir mal bitte,> warum Du unbedingt einen Compiler verwenden willst, der dynamische> Objekte unterstützt, obwohl Du die nie brauchst.
C (Pre)Compiler unterstützen auch alle XMakros obwohl die weitgehend
unbekannt sind. Sollte man diese Compiler nur alle nicht mehr benutzen,
weil sie etwas unterstützen, dass man nicht braucht?
Karl H. schrieb:> Da gibt es noch eine ganze Wissens-Welt, die auf dich wartet und die es> zu erforschen gilt.
Wissenswelten warten viele. Viel zu viele. Die Frage ist doch aber
gerade: Was braucht man davon? Deshalb rücke ich die konkrete App ja so
vehement in den Fokus. Uns schließlich: Das Wissen, von dem wir hier
reden ist zu guten Teilen auch Wissen über aktuelle Sprachfeatures und
Werkzeuge. Wissen, daß sich schnell wieder ändert und vieles in der
Versenkung verschwindet. Deshalb: Klären: Was brauch ich wirklich ?!!!
Darüber hinaus interessieren kann man sich gern noch für vieles.
Hardware- und Softwareentwicklung sind spannend. Wenn nicht so vieles
wieder vergänglich wäre... Für die tägliche Praxis bedeutet das: Bloß
nicht verzetteln! Konzentration auf das Wesentliche!
schlappohr schrieb:> Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen> MCU sinnvoll nutzen kann.
Zwingt dich jemand dazu alle zu nutzen? Heißt das also, wenn ich nicht
alle Features von C nutze, soll ich doch lieber die Finger davon lassen?
schlappohr schrieb:> <Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++> Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere> Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem, das nur> Sinn macht, wenn Du es auch nutzt. Die komfortablen Sprachlemente> bezahlst Du immer mit einem ineffizienteren Maschinencode (bei jeder> Sprache). Das ist einer der Gründe, warum viele MCU-Hersteller eben> (noch) keinen C++-Compiler anbieten.
Das kompliziertere Runtimesystem rührt aber von Exceptions und RTTI her
und nicht OOP. Schalte Exceptions und RTTI aus, dann hast du die
gleichen Bedingungen wie unter C. Und nein komfortable Sprachelemente
erzeugen eben nicht pauschal ineffizienten Maschinencode, einige lassen
sich nämlich zur Kompilierung auflösen. In C++ gibts eine Menge
Sprachelemente, die zur Laufzeit nichts kosten.
schlappohr schrieb:> Ich rede davon, dass Code, der> dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit> schwieriger vorherzusagen ist. Deswegen wird in RT-Systemen> üblicherweise alles so weit wie möglich statisch gemacht, und damit geht> ein wesentlicher Vorteil von C++ verloren.
Dann schreib halt keinen Code, der Objekte zur Laufzeit erzeugt. Da
lassen sich immer noch viele (fast alle?) C++ Features nutzen.
schlappohr schrieb:> Und der> allgemeine Konsens ist: Wenn es nicht unbedigt sein muss, dann lass es> sein. Es gibt ein nettes Zitat von Linux Torvalds: "writing kernel code> in C++ is a BLOODY STUPID IDEA [...]"
Da gibt es keinen "allgemeinen" Konsens. Im übrigen sind Torvalds
aussagen dazu sehr umstritten.
schlappohr schrieb:> So ist es. Genau das ist der Punkt. Und jetzt erklär mir mal bitte,> warum Du unbedingt einen Compiler verwenden willst, der dynamische> Objekte unterstützt, obwohl Du die nie brauchst.
Ja himmel Hergott, weil es andere Features gibt (siehe oben) die mir C
nicht bieten kann.
schlappohr schrieb:> Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen> braucht.> Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen> MCU sinnvoll nutzen kann.> Sorry wenn das zu kompliziert war.
Das ist immer so das Problem mit Vergleichen. Du wolltest wohl sagen,
das die Kosten für die Nutzung eines C++ compilers gegenüber eines C
compilers (Lieferwagen vs. Fahrrad) höher ist, bei gleichem Nutzen
(Brötchen). Das kann aber niemand verstehen, der nicht der Meinung ist,
dass dem so ist. Wenn Du der Meinung bist, dass die Kosten für die
Nutzung eines C++ Compilers höher sind, dann sag es doch so und bringe
einfach konkrete Aspekte.
Es hat ja schon seinen Grund, warum Vergleiche hauptsächlich in der
Politik und Theologie verwendet werden ;-)
> Für einen Hobbybastler mag das vielleicht keine> Rolle spielen.
Uhhh, Faul!
> C++> Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere> Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem, das nur> Sinn macht, wenn Du es auch nutzt.
Ich habe gerade mal bei einem nicht trivialen C++ Beispiel alle system
libraries raus geworfen. Das ist der Teil, den ich gegenüber einer
C-Lösung hinzu fügen musste:
@Moby AVR Was machst du eigentlich in einem C++ Thread? Widme dich
lieber diesem hier "C versus Assembler->Performance". Dort kannst du bei
dem Wettstreit endlich die Überlegenheit von ASM demonstrieren. Also wo
bleibst du? Oder kannst du doch nur hohle Phrasen wiederholen?
Torsten R. schrieb:> Das ist immer so das Problem mit Vergleichen.
Vielleicht so:
C++ bietet einen ganzen Fuhrpark an Fahrzeugen. Dieser ist etwas
umfangreicher als der Fuhrpark, der von C zur Verfügung gestellt wird.
Wenn ich nur Brötchen holen will, lasse ich den Lieferwagen stehen, und
nehm das Fahrrad.
Nur dass das C++ Fahrrad schön Bunt ist und eine bessere Gangschaltung
als das C-Fahrrad hat.
Nur weil im Fuhrpark auch ein 50-Tonnen-Panzer steht, zwingt mich
niemand den durch die enge Gasse zu fahren. Wenn ich das trotzdem tue,
bin ich selber schuld, wenn ich steckenbleibe.
@ Karl Heinz
> versteh ich nicht.> Was hat jetzt die andere Controller-Architektur mit C++ zu tun?> Die einzig relevante Frage lautet: gibt es dafür einen C++ Compiler - ja> oder nein?> Und dieselbe Frage stellt sich auch bei einem C Compiler.
Aus Originalpost ergab sich die Frage, ob man einen Controller auswählen
sollte, für den es einen C++-Compiler gibt, oder ob man den Controller
nach anderen Kriterien auswählt und dann evtl eine andere Sprache (in
diesem Fall C) erlernen muss. Ich würde nicht von Controller A zu
Controller B wechseln, nur weil es für B einen C++-Compiler gibt.
> Punkt ist doch: wenn ich nicht will, dann muss ich> Teile davon nicht nutzen. Auch für C++ gilt: You don't pay for what you> don't use.
Natürlich nicht. Aber was bringt Dir dann C++, wenn Du im Endeffekt
nicht viel davon nutzen kannst.
Ich will hier nicht den x-ten C vs. C++ Flamewar anzetteln. Ich benutze
beides und finde C++ als Sprache viel effizienter. Aber da ich auf einem
Controller nur Teile davon sinnvoll nutzen kann, würde ich die
Entscheidung für einen Controller nicht davon abhängig machen.
> Ah. Nein.> COde wird da überhaupt nicht kopiert.
Kommt drauf an: Auf Multicore-Systemen mit lokalen Speichern evtl schon,
wenn Du den Linker anweist, für bestimmte Objekte den lokalen Speicher
anstelle des Shared memory zu verwenden. Aber im allgemeinen ist das
nicht der Fall, da hast Du recht.
> Der springende Punkt> ist, dass du für eine komplizierte Initialisierung in C genauso den> enstprechenden COde aufrufen musst.
Du wirst mir zustimmen, dass das Handling komplexer dynamischer Objekte
in C++ wesentlich einfacher ist als in C. Wenn ich also eine Anwendnung
habe, die mit vielen solchen Objekten arbeitet, dann geht das mit C++
viel einfacher. Bei den meisten MCU-Anwendungen ist das nicht der Fall,
daher kann dieser Vorteil von C++ nicht genutzt werden. Das ist der
springende Punkt.
Planlos schrieb:> Torsten R. schrieb:>> Das ist immer so das Problem mit Vergleichen.>> Vielleicht so:>> C++ bietet einen ganzen Fuhrpark an Fahrzeugen. Dieser ist etwas> umfangreicher als der Fuhrpark, der von C zur Verfügung gestellt wird.
Ja, das ist schön ;-) Mit einem Vergleich kann man sagen, was man möchte
und weicht dabei der Diskussion mit Argumenten aus. Es sagt viel mehr
darüber aus, wie jemand denkt als das es irgend etwas beweisen / belegen
würde. Wenn ich einem Laien etwas verständlich machen möchte, dann
taugen sie ganz gut aber für eine Diskussion unter Kollegen erschließt
sich mir der Sinn nicht.
schlappohr schrieb:> @ Karl Heinz>>> versteh ich nicht.>> Was hat jetzt die andere Controller-Architektur mit C++ zu tun?>> Die einzig relevante Frage lautet: gibt es dafür einen C++ Compiler - ja>> oder nein?>> Und dieselbe Frage stellt sich auch bei einem C Compiler.>> Aus Originalpost ergab sich die Frage, ob man einen Controller auswählen> sollte, für den es einen C++-Compiler gibt, oder ob man den Controller> nach anderen Kriterien auswählt und dann evtl eine andere Sprache (in> diesem Fall C) erlernen muss. Ich würde nicht von Controller A zu> Controller B wechseln, nur weil es für B einen C++-Compiler gibt.
Ah. OK
Da hab ich dann wohl im Laufe des Threads den Faden verloren.
Ja. Unter dem Gesichtspunkt stimme ich zu.
schlappohr schrieb:> Natürlich nicht. Aber was bringt Dir dann C++, wenn Du im Endeffekt> nicht viel davon nutzen kannst.TriHexagon schrieb:>>> - keine implizite Konvertierung von void*>>> - namespaces>>> - templates>>> - überladende Funktionen>>> - Operatoren für eigene Typen>>> - typesichere enums>>> - //-Kommentare>>> - constexpr>>> - Konstruktoren / Destruktoren>>> - umfangreichere Standardlibraries:>>> - crc>>> - random number generators>>> - algorithmen (Suchen, Sortieren, Permutieren...)>>>> - Möglichkeit der Datenkapselung mit private und protected (ja, ich>> weiss, man kann sie umgehen) und inline Gettern/Settern -> kein runtime>> Penalty und trotzdem kann ich wilden Zugriffen auf Variblen einen Riegel>> vorschieben.>> - static_assert
Alle statisch nutzbar auf einem µC. Und das sind hier längst nicht alle.
schlappohr schrieb:> Ich würde nicht von Controller A zu> Controller B wechseln, nur weil es für B einen C++-Compiler gibt.
Da werden dir die Meisten auch zustimmen. Aber nicht C++ zu brauchen, da
man nicht alle features benötigt, die die Sprache bietet, ist dann doch
"etwas" engstirnig.
Aber wir haben jetzt einen C/C++ Krieg hier, Kicad diskussion da, fehlt
nurnoch der Troll im A&B Forum und der Freitag ist perfekt :-)
Operator S. schrieb:> Da werden dir die Meisten auch zustimmen. Aber nicht C++ zu brauchen, da> man nicht alle features benötigt, die die Sprache bietet, ist dann doch> "etwas" engstirnig.
Sehe ich auch. C++ auf einem AVR geht wunderbar, man muss die Sprache
aber können und wissen was man macht, das ist hier der Punkt. Und so wie
der TO schreibt, ist er davon noch etwas entfernt.
@Viele, ohne Sortierung
> Zwingt dich jemand dazu alle zu nutzen? Heißt das also, wenn ich nicht> alle Features von C nutze, soll ich doch lieber die Finger davon lassen?
Nein. Es heißt, dass Du besser keine Zeit verschwenden sollst mit der
Suche nach einem C++-Compiler, wenn Du schon einen C- Compiler hast, der
das tut, was Du willst.
> Das ist falsch und leider immernoch ein sehr verbreitetes Vorurteil.> Ineffizienter Maschinencode wird durch ineffiziente Programmierung> hervorgerufen, nicht durch die Sprache.
Respekt, Du hast gerade ganz Compilerbau-Vorlesungen ausgehebelt.
Übersetze ein Programm mit drei verschieden Compilern und Du bekommst
drei verschiedene Binaries (außer bei Hello World vielleicht). Es gibt
tausend Arten wie Du ein Programm übersetzen kannst. Und das gilt schon
für Compiler derselben Sprache. Und die Unterschiede in den Ergebnissen
wirken sich umso mehr aus, je kleiner die Zielarchitektur ist.
>> Für einen Hobbybastler mag das vielleicht keine>> Rolle spielen.> Uhhh, Faul!
Ich arbeite beruflich und privat mit Controllern und treffe privat auch
andere Entscheidungen. Deswegen diese Bemerkung. Sorry, wenn ich
jemandem auf die Füße getreten habe.
> Nur weil im Fuhrpark auch ein 50-Tonnen-Panzer steht, zwingt mich> niemand den durch die enge Gasse zu fahren. Wenn ich das trotzdem tue,> bin ich selber schuld, wenn ich steckenbleibe.
Und Du würdest Dir einen Fuhrpark mit einem 50-Tonnen-Panzer anschaffen,
obwohl Du nur Brötchen holen fähst und das Fahrrad schön bunt ist? Vor
allem , wenn Du dafür erst noch ein eine Stadt ziehen musst?
> Nett ist ein blödes Wort, wenn etwas aus dem Kontext gerissen wird. Hat
Zitate sind immer ohne Kontext, und der Rest von Torvalds' Aussage ist
im wesentlichen eine Begründung für den zitierten Satz.
> auch nichts mit echtzeit zu tun gehabt, als er das sagte.
Das habe ich im folgenden Satz auch geschrieben. Aber es zeigt deutlich,
das C++ nicht so everybody's Darling ist, wie man manchmal meinen
könnte.
> Das ist tatsächlich schön, sagt es doch, dass man auch mit C++ schlecht> programmieren kann, aber im normalfall nicht ;-)
Den interessanten Teil hast Du weggelassen:
"The bad news is you have to understand the efficiency aspects of the
C++ code you write.[...]"
> Aber wir haben jetzt einen C/C++ Krieg hier,
Nein, das haben wir nicht. Die Frage, ob ein bestimmter Compiler für
einen bestimmten Zweck geignet ist, ist schon gerechtfertigt, und ich
bin der Meinung, dass das hier trotz der gegensätzlichen Ansichten recht
sachlich abläuft, im Vergleich zu anderen Foren.
In diesem Sinne, ein schönes Wochenende an alle.
Hallo Johan,
Diese Entscheidung ist relativ leicht, hol dir einen PIC oder AVR
(Kannst ja eine Münze werfen, wenn du dir unschlüssig bist) und danach
beginnst du mit C.
Wenn du schon etwas C++ kannst sollte dir der Syntax von C keine
Schwierigkeiten bereiten.
C würde ich vor allem empfehlen, da es viel mehr Beispiele in C als C++
gibt. Da du noch ein Anfänger bist, kommt dir das sicher zu gute.
Wenn du dann etwas Vertrauter mit dem uC-Welt bist kannst du immer noch
auf C++ umsteigen.
schlappohr schrieb:> Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen> braucht.
Auf die Gefahr hin, mich zu wiederholen: das hängt von der Menge der
Brötchen ab. Verstehst Du das?
> Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen> MCU sinnvoll nutzen kann.
Ein C++-Compiler bietet trotzdem etliche Funktionen, die man auf einer
kleinen MCU sinnvoll nutzen kann. Und alleine diese Funktionen sind es,
die seinen Einsatz sinnvoll machen.
> Wenn ich als Projektleiter entscheiden soll, ob wir auf eine andere> Controller-Architektur umsteigen, die ein anderes Konzept hat, teurer> ist, Einarbeitung in eine neue Toolchain erfordert und am Ende dasselbe> leistet, und das nur weil jemand C++ toll findet, ja, dann verlange ich> eine Rechtfertigung.
Wer redet hier von einer anderen Controller-Architektur in einem
kommerziellen Setting? Der TO ist ein Hobbyist und fragt, ob er PICs mit
C++ programmieren kann oder welche Alternative er hat, wenn er in C++
programmieren möchte. Und da ist AVR eine gute Alternative, nicht
zuletzt weil die Hardware sogar eigens für die Verwendung mit einer
Hochsprache konzipiert und optimiert worden ist.
> <Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++> Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere> Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem
Tatsächlich erzeugt der avr-g++ haargenau denselben Maschinencode wie
der avr-gcc, wenn man beiden Compilern äquivalenten C- bzw.
C++-Quellcode vorsetzt. Keine Spur von einem "komplexen Runtimesystem"
oder einem "ineffizienteren Maschinencode". Klassen, Methoden,
Konstruktoren und Templates: davon findest Du am Ende im
Assembler-Zwischencode genau gar nichts mehr, das optimiert der Compiler
einfach weg. Töfte, wa?
Probiers doch einfach mal aus, anstatt hier irgendwelchen Quatsch zu
erzählen. Ich habs gemacht und durch Analyse des Assembler-Zwischencodes
und der Maschinencodes festgestellt, daß die Unterschiede marginal bis
nicht vorhanden sind und in einigen Fällen der C++-Compiler sogar einen
minimal kleineren Maschinencode erzeugt.
> Ich rede nicht von Assembler-Inlining. Ich rede davon, dass Code, der> dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit> schwieriger vorherzusagen ist.
Dieser Einwand ist an Irrelevanz kaum zu überbieten, weil dynamische
Allokation und die Notwendigkeit der Initialisierung von Speicher rein
überhaupt gar nichts mit OOP zu tun hat.
> Das ist jetzt aber nicht Dein Ernst, oder? malloc reserviert Speicher,> das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht. Der> Aufruf eines Konstruktors legt Datenstrukturen an, kopiert Code falls> notwendig und ruft Initialiserungsfunktionen und weitere Konstrktoren> auf. Je nach Art der Klasse ist das geringfügig komplizierter, stimmst> Du mir da zu?
Nein. Weil es Unfug ist, was Du schreibst. Der new-Operator in C++ ist
im Prinzip nichts anderes als:
1
void*operatornew(size_tsize){
2
returnmalloc(size);
3
}
Ob mein Konstruktor Datenfelder initialisiert,
Initialisierungsfunktionen oder weitere Konstruktoren aufruft, ist dem
Programmierer überlassen. Das kann man natürlich machen, aber wenn man
eine Datenstruktur in C erzeugt -- ganz gleichgültig, ob dynamisch oder
nicht -- dann muß die genauso wie in C++ initialisiert werden. Ob ich
den dazu notwendigen Code nun in einen C++-Konstruktor packe oder als
C-Funktion aufrufe, ist überhaupt keinerlei Unterschied.
> Und jetzt erklär mir mal bitte,> warum Du unbedingt einen Compiler verwenden willst, der dynamische> Objekte unterstützt, obwohl Du die nie brauchst. Oder Exceptions. Oder> dynamische Typprüfung.
Will ich gar nicht, das ist nur eine Unterstellung Deinerseits. Ich
könnte auf Mikrocontrollern auch prima mit einem C++-Compiler leben, der
keines dieser Features hat. Keines dieser Features macht C++ aus, und
demzufolge hat der avr-g++ standardmäßig nichtmal eine Implementierung
für new() und delete() bzw. deren Placement-Pendants. Man kann das
selbst nachrüsten, wenn man es denn braucht, aber auf Mikrocontrollern
hat das nur in den allerwenigsten Situationen einen Nutzen.
Manchmal, ganz selten, aber eben doch, beispielsweise wenn man mehrere
komplexe Datenstrukturen verarbeiten muß, für die der verfügbare
Speicher nicht ausreicht. Dann muß man entweder einen größeren
Controller nehmen, oder die Datenstrukturen dynamisch erzeugen und
zerstören -- mit malloc() in C oder mit new() in C++, das spielt keine
Rolle, und ist auch intern haargenau dasselbe. Wie gesagt: probier's
einfach aus.
> Wenn Du einen Compiler hast, der das alles kann,> ok. Aber warum Du die Entscheidung für einen Prozessortyp davon abhängig> machen willst, kann ich nicht nachvollziehen.
Weil der Compiler immer noch genügend viele Vorteile bietet, wenn man
auf Features verzichtet, die auf einem Mikrocontroller meist überflüssig
sind. Niemand zwingt einen alle Features von C++ zu benutzen, aber
selbst wenn man nur den für Mikrocontroller sinnvollen Teil benutzt,
gibt es mehr als genug Gründe dafür.
Eine Kettensäge hat Vorteile gegenüber einer Handsäge, und Du versuchst
uns hier zu verklickern, daß man zum Entasten von gefällten Bäumen
lieber eine Handsäge benutzen sollte, weil so eine Kettensäge ja
schließlich auch beim Fällen von Bäumen Vorteile hat. Atme bitte mal
tief durch, ja?
Moby A. schrieb:> Deshalb: Klären: Was brauch ich wirklich ?!!!
Um eine vernünftige Antwort auf diese Frage zu finden, müßte man doch
erst einmal die zur Verfügung stehenden Möglichkeiten und ihre Vor- und
Nachteile kennen. Bei Deiner tiefen, immer wieder gebetsmühlenartig
vorgetragenen Abneigung gegenüber Hochsprachen können wir wohl davon
ausgehen, daß Du die Möglichkeiten und Fähigkeiten von Hochsprachen
nicht kennst und schon aus diesem Grunde nichts zur Diskussion beitragen
kannst.
TriHexagon schrieb:> Das kompliziertere Runtimesystem rührt aber von Exceptions und RTTI her> und nicht OOP. Schalte Exceptions und RTTI aus, dann hast du die> gleichen Bedingungen wie unter C.
Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal
ausschalten. Im Artikel "C++"
(https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite
wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und
nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise
sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch.
Vergleichende Beispiele könnten die Diskussion konkretisieren und
Interessierten eine Einstieg in C++ bieten.
Die verfügbare Literatur für Embedded C++ ist mir zwei bis drei Nummern
zu kompliziert.
Mcucpp ist für mich nachvollziebar. Leider nicht kommentiert. Das zwingt
aber die Sache ganau zu studieren. So lernt man auch, Schritt für
Schritt...
Ich für mich werde den Weg mit C++ weitergehen, auch wenns öfters
schwierig ist...
schlappohr schrieb:> Aus Originalpost ergab sich die Frage, ob man einen Controller auswählen> sollte, für den es einen C++-Compiler gibt, oder ob man den Controller> nach anderen Kriterien auswählt und dann evtl eine andere Sprache (in> diesem Fall C) erlernen muss. Ich würde nicht von Controller A zu> Controller B wechseln, nur weil es für B einen C++-Compiler gibt.
Aus dem Originalpost ergibt sich aber, daß es nicht um einen Wechsel von
einem auf einen anderen Controller geht, sondern zunächst einmal um die
Auswahl eines Mikrocontrollers. Und da der TO bereits C++ beherrscht, C
jedoch nicht, ist es sinnvoller für ihn, AVRs zu benutzen, weil dafür
mit dem avr-g++ ein ausgereifter, freier C++-Compiler verfügbar ist.
schlappohr schrieb:>> Punkt ist doch: wenn ich nicht will, dann muss ich>> Teile davon nicht nutzen. Auch für C++ gilt: You don't pay for what you>> don't use.>> Natürlich nicht. Aber was bringt Dir dann C++, wenn Du im Endeffekt> nicht viel davon nutzen kannst.
Weil das, was Du nutzen kannst -- Datenkapselung, Vererbung, Templates,
Überladen von Funktionen, Methoden und Operatoren etc. -- alleine schon
mehr als genug Vorteile bietet, die eindeutig für C++ sprechen. Daß C++
noch andere Features hat, die im Mikrocontroller-Bereich nicht sinnvoll
eingesetzt werden können, spricht nicht dagegen, C++ zu benutzen,
sondern nur dagegen, diese Features zu benutzen.
> Kommt drauf an: Auf Multicore-Systemen mit lokalen Speichern
Es geht hier immer noch um Mikrocontroller, oder?
> Du wirst mir zustimmen, dass das Handling komplexer dynamischer Objekte> in C++ wesentlich einfacher ist als in C. Wenn ich also eine Anwendnung> habe, die mit vielen solchen Objekten arbeitet, dann geht das mit C++> viel einfacher. Bei den meisten MCU-Anwendungen ist das nicht der Fall,> daher kann dieser Vorteil von C++ nicht genutzt werden. Das ist der> springende Punkt.
Das Problem an diesem Punkt ist, daß er nicht nur springend, sondern
vollkommen irrelevant ist. Die Frage ist letztlich immer nur, ob man
dynamischen Speicher braucht oder nicht.
Wenn man dynamischen Speicher braucht, geht es mit C++ viel einfacher.
wie Du schon erkannt hast -- und trotzdem kostet das in C++ am Ende
nicht mehr als in C, weil der Assembler- und Maschinencode für die
Allokation und die Initialisierung am Ende genau dieselben sind.
Trotzdem C++ hier also mehr Komfort bietet, erzeugt es am Ende überhaupt
gar keinen Overhead. Ist doch prima: mehr Komfort ohne die geringsten
Nachteile, findest Du nicht?
Wenn man keinen dynamischen Speicher braucht, tun sich C und C++ wieder
nichts, außer daß C++ viele komfortable Möglichkeiten bietet, die C eben
leider nicht hat. Auch dabei kostet der zusätzliche Komfort überhaupt
gar nichts: mehr Komfort ohne die geringsten Nachteile eben.
Was spricht da also noch für C? Richtig: nichts. Nicht einmal ein
bereits vorhandener Haufen C-Code, denn der läßt sich ja weiterhin auch
unter C++ benutzen oder mit üblicherweise minimalem Aufwand portieren.
Das Einzige, was ansonsten noch für C sprechen könnte, wäre, wenn man
einen Haufen von Ignoranten und / oder Ideologen in seiner
Entwicklungsabteilung sitzen hat, die jede Neuerung ablehnen. Aber das
ist kein technisches, sondern primär ein soziales und sekundär ein
Führungsproblem.
Sheeva P. schrieb:
Ich stimme dir in praktisch allem zu.
Nur das hier
> Und da der TO bereits C++ beherrscht
Lese ich das Originalposting
> Ich habe aus privatem Interesse heraus auch etwas Erfahrung mit> C++ (Variablen, Datentypen, Schleifen, Funktionen, Strukturen, Zeiger).
dann ist 'C++ beherrschen' wohl etwas weit hergeholt.
Wenn er den hier von ihm angegebenen Sprachraum von C++ tatsächlich
beherrscht, dann sind wir sowieso eher bei C als bei C++.
Viele der Anwesenden scheinen ein äußerst nebulöses Bild von C++ (und
auch von OOP im allgemeinen) zu haben (und auch von anderen Themen aus
dem unbekannten bedrohlichen Land hinter dem Tellerrand) und assoziieren
die ungeheuerlichsten Dinge und Schreckgespenster damit, feuerspuckende
Drachen, menschenfressende Konstruktoren, Handbücher mit mehr als 100
Seiten, etc.
Ich musste mehrmals laut lachen beim Lesen.
Sheeva P. schrieb:> TriHexagon schrieb:>> Das kompliziertere Runtimesystem rührt aber von Exceptions und RTTI her>> und nicht OOP. Schalte Exceptions und RTTI aus, dann hast du die>> gleichen Bedingungen wie unter C.>> Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal> ausschalten. Im Artikel "C++"> (https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite> wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und> nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise> sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch.
Ah das hab ich mir schon gedacht, hab ich aber nie nachgeprüft. Danke.
Sheeva P. schrieb:> Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal> ausschalten. Im Artikel "C++"> (https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite> wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und> nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise> sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch.
Gibts dazu irgendwelche weiteren Infos wie das funktioniert? Zumindest
der neuste (5.2) arm-g++ macht das nicht und der generierte Code ist
ohne "-fno-exceptions -fno-rtti" einmal mal 60% größer (60KB vs. 38KB).
sebi707 schrieb:> Sheeva P. schrieb:>> Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal>> ausschalten. Im Artikel "C++">> (https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite>> wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und>> nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise>> sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch.>> Gibts dazu irgendwelche weiteren Infos wie das funktioniert? Zumindest> der neuste (5.2) arm-g++ macht das nicht und der generierte Code ist> ohne "-fno-exceptions -fno-rtti" einmal mal 60% größer (60KB vs. 38KB).
Bei mir wird immer mit -Os und -flto optimiert und zuletzt mit avr-strip
die Symbole entfernt. Wie bist Du zu Deinem Ergebnis gekommen?
>> der neuste (5.2) arm-g++ macht das nicht und der generierte Code ist>> ohne "-fno-exceptions -fno-rtti" einmal mal 60% größer (60KB vs. 38KB).> Bei mir wird immer mit -Os und -flto optimiert und zuletzt mit> avr-strip die Symbole entfernt. Wie bist Du zu Deinem Ergebnis gekommen?
arm-gcc, nicht avr-gcc!
Ist es nicht so, daß der avr-gcc gar keine Exceptions und keine RTTI
unterstützt? arm-gcc hat diese beiden Dinge sicher mit dabei, weshalb
das Abschalten dieser sich auch bemerkbar macht.
Moby schrieb im Beitrag #4260564:
>> Cortex-Mx Controller. Die Controller sind kaum komplexer als die>> gängigen 8Bit Mikrocontroller ...>> Da lachen ja (schon) die Hühner ;-)
Wieso? Diese Aussage ist doch korrekt? Sie mögen wohl intern mehr und
kleinere Transistoren haben und mehr verschiedene Peripherie auf dem
selben Chip anbieten (die man nutzen kann wenn man sie braucht oder
ignorieren wenn nicht) aber die jeweils im konkreten Projekt zu
verwendende Peripherie lässt sich auch kein bisschen anders oder gar
komplizierter handhaben (und nur darauf kommt es an) als beispielsweise
bei nem AVR: Jedes einzelne Peripheriegerät hat vielleicht ein halbes
Dutzend Register und ein eigenes Kapitel im Handbuch in dem alles schön
erklärt ist, genauso wie auch schon zu 8-Bit Zeiten, und die
Funktionsweise von beispielsweise einem 6-Kanal Timer auf nem Kinetis zu
verstehen und zwei Kanäle davon in Betrieb zu nehmen (und die anderen 4
identisch aufgebauten einfach links liegen zu lassen) dauert auch keine
Sekunde länger als beispielsweise die von einem 2-Kanal Timer auf nem
AVR, in dem konkreten Fall übrigens eher sogar eher weniger weil
logischer aufgebaut und nicht so verkrampft verknotet wie die 2 Kanäle
auf nem AVR-Timer.
Du kannst mir zum Beispiel nicht erzählen daß Du zwar einerseits fähig
bist beispielsweise auf nem Atmega den ADC von einem Timer triggern zu
lassen und nach der Wandlung einen Interrupt auszulösen imstande bist
indem Du ein halbes Dutzend Bits in einer Handvoll Register entsprechend
konfigurierst, so wie Du es aus dem Handbuch durch Lesen gelernt hast,
jedoch das grundlegend selbe Vorhaben auf einem vergleichbar kleinen
ARM-Controller als irgendwie komplizierter empfindest obwohl da
ebenfalls nur eine Handvoll Bits in einer Handvoll Registern zu setzen
sind, Register und Bits deren Namen einem sogar schon irgendwie seltsam
vertraut vorkommen sollten und (o Wunder) im Wesentlichen die
vergleichbaren Funktionen haben wie bei der anderen Architektur die Du
vorher verwendet hast, das kannst Du mir nicht erzählen.
Es ist nämlich kein bisschen komplizierter, es ist der exakt selbe alte
Kram in grün statt blau. Kein Unterschied. Du kannst es übrigens auch in
asm machen wenn Du unbedingt willst, auch das macht keinen Unterschied.
Moby A. schrieb im Beitrag #4261484:
> TriHexagon schrieb:>> Die Qual der Wahl>> ...fällt zum Beispiel von Automobil-Steuergerätesoftware ganz eindeutig> zugunsten von prozeduralem C aus. In vielen Embedded-Bereichen schauts> ähnlich aus.
Und was spricht konkret gegen prozedurales C++? Ich sehe da keinen
Nachteil, sondern sogar Vorteile wie z.B. Typsicherheit (verhindert
Fehler), typsichere Konstanten, static_assert um Fehler/Probleme zur
compilezeit zu entdecken, etc.. Gerade bei
"Automobil-Steuergerätesoftware" ist Sicherheit doch sehr wichtig, da
helfen die eben genannten Features.
Ich kann mir vorstellen, dass da ein paar Klassen der Sicherheit
zuträglich sein könnte, da man mit Klassen Daten kapseln und vor
unbefugten Zugriff schützen kann.
Da fällt mir gerade ein, gab es vor einem Jahr nicht Werbung von BMW als
Arbeitgeber? Ich kann mich nicht mehr erinnern um welche Software es
ging, aber auf jeden Fall um Softwareentwicklung bei BMW. Kann gut sein,
dass es besagte Auto-Steuerungssoftware war (Fahrerassistenzsysteme?).
Auf jeden Fall war der gezeigte Code in C++.
TriHexagon schrieb:> da man mit Klassen Daten kapseln und vor> unbefugten Zugriff schützen kann.
Nicht nur das, es macht die Überprüfung der übergebenen Daten auch
leichter (da zentral).
TriHexagon schrieb:> "Automobil-Steuergerätesoftware" ist Sicherheit doch sehr wichtig, da> helfen die eben genannten Features.
... und werden dort trotzdem nicht in nennenswertem Umfang eingesetzt.
Warum? Vielleicht hilft ein Zitat aus der Wikipedia:
"Das breite Leistungsspektrum und die vielfältigen
Gestaltungsmöglichkeiten der Sprache sowie die Bibliotheken führen zu
verhältnismäßig langen Einarbeitungszeiten. Im Vergleich mit C bietet
C++ eine enorme Fülle an Sprachmitteln."
Ich würde daraus folgende Schlüsse ziehen:
-> Es gibt nicht genügend qualifizierte Entwickler
-> Die durchschnittliche C++ Software könnte besser sein
Sprachen mit weniger Sprachmitteln tun es offensichtlich genauso.
Je vielfältiger die Gestaltungsmöglichkeiten, desto schwieriger fällt es
den Überblick zu behalten. Vielfältige Sprachmittel wollen richtig
angewendet werden, sonst produzieren sie nur vielfältig suboptimalen
Code.
Nicht die Theorie vielfältiger Gestaltungsmöglichkeiten entscheidet,
sondern die reale Praxis ihrer Umsetzung.
Bernd K. schrieb:> Du kannst mir zum Beispiel nicht erzählen daß Du zwar einerseits fähig> bist beispielsweise auf nem Atmega den ADC von einem Timer triggern zu> lassen [...] jedoch das grundlegend selbe Vorhaben auf einem vergleichbar> kleinen ARM-Controller als irgendwie komplizierter empfindest [...]
Sagen wir's mal so ... auf einem AVR den ganzen Standardkram (bis hin zu
parallel Primzahlen ausrechnen, LEDs blinken, Knöpfe registrieren und
eine Melodie spielen) habe ich relativ schnell hinbekommen.
Die Hardware-PWM auf einem SAM3X stellt mich aber nach wie vor vor
größere Probleme. Nach meinem Dafürhalten (und ich sehe mich auch auf
den Teilen nicht mehr als totalen Grünschnabel) habe ich die paar Bits
korrekt gesetzt, es funktioniert trotzdem nicht. (Auf dem STM32 lief es
wieder relativ zügig; aber dank Befehl von oben sind die Teile out.)
> Es ist nämlich kein bisschen komplizierter, es ist der exakt selbe alte> Kram in grün statt blau. Kein Unterschied. Du kannst es übrigens auch in> asm machen wenn Du unbedingt willst, auch das macht keinen Unterschied.
Einspruch, euer Ehren. Dieses ganze "ARM ist nicht schwerer als
AVR"-Gerede ist großer Unfug und das wisst ihr selbst. Das fängt damit
an, dass die klassische AVR-Toolchain einfach "tut", und die klassische
ARM-Toolchain ohne eigenen Startup-Code nicht. Und es hört noch lange
nicht damit auf, dass ein AVR-Datenblatt alle wesentlichen Bestandteile
enthält, ein ARM-Datenblatt in der Regel aber nicht. Das ist der
Komplexität und der Mächtigkeit der 32-Bitter geschuldet. Ein AVR hat
keinen nennenswerten Clock-Tree; ein STM32 oder SAM3X schon.
Obwohl das mit ein bisschen Einarbeitung alles nicht unmöglich ist, es
bleibt schwerer, als in die AVR-Welt einzutauchen. Punkt.
Und komme mir nicht mit IDEs wie Keil oder Arduino. Die verstecken die
Magie auch nur, und wenn du mal einen zu neuen Chip bekommst oder deine
eigene Hardware aufbaust, stehst du trotzdem erstmal im Regen.
S. R. schrieb:> Und komme mir nicht mit IDEs wie Keil oder Arduino. Die verstecken die> Magie auch nur, und wenn du mal einen zu neuen Chip bekommst oder deine> eigene Hardware aufbaust, stehst du trotzdem erstmal im Regen.
So ist es beim AVR auch. Hier wird der Startup-Code auch dazu gelinkt.
Oder was glaubst du wer die C-Laufzeitumgebung initialisiert und die
main()-Methode aufruft? Seit Winavr relativ tot ist gibts nur noch die
Tools von Atmel selbst. Und es interessiert auch niemanden warum was wie
geht. Wenn du es einfach haben willst, dann nimm halt die IDE die dir
der Hersteller empfiehlt und oft wie Sauerbier anpreist. Arduino und
Keil in einen Topf zu werfen grenzt wirklich fast an Blödheit.
S. R. schrieb:> und wenn du mal einen zu neuen Chip bekommst
Wenn er aus der selben Linie kommt ist das sicher kein Problem. Wenn es
etwas völlig anderes ist, dann wird das ganze wohl ähnlich ablaufen als
wenn du versuchst einen PIC mit dem Atmel-Studio programmieren.
Es wäre sicher besser die ganzen Nörgler setzen sich mal 2 Tage hin und
versuchen die Zusammenhänge zu verstehen. Das ist besser angelegte Zeit
als hier die Threads mit Unwissen, Falschaussagen und Gespenstern voll
zu müllen.
Moby A. schrieb:> TriHexagon schrieb:>> "Automobil-Steuergerätesoftware" ist Sicherheit doch sehr wichtig, da>> helfen die eben genannten Features.>> ... und werden dort trotzdem nicht in nennenswertem Umfang eingesetzt.
Noch. Darum gibt es sogar schon einen Codingstandard dafür:
MisraC++:2008.
> Ich würde daraus folgende Schlüsse ziehen:> -> Es gibt nicht genügend qualifizierte Entwickler
Viele Embedded-Entwickler sind noch mit C unterwegs; das liegt
einerseits an derselben Vorurteilen, die Du hier so gerne behauptest,
aber auf der anderen Seite natürlich auch daran, daß C++ und
C++-Werkzeuge erst in den letzten Jahren so ausgereift wurden, wie sie
es heute sind. Daher ist es nur noch eine Frage der Zeit, bis sich die
Vorteile von C++ auch im Embedded-Umfeld in der Breite durchsetzen
werden. Wer das nicht mitgehen will, sollte sich rechtzeitig nach einem
neuen Job umschauen, sofern er nicht bereits kurz vor der Rente steht.
> -> Die durchschnittliche C++ Software könnte besser sein
Dank höherer Typsicherheit, besserer Codeorganisation und einer besseren
Wiederverwendbarkeit kann in C++ stabilere, komplexere, besser getestete
und besser wartbare Software mit geringerem Aufwand umgesetzt werden. Da
ist die Prognose, daß sich diese Vorteile durchsetzen werden, sicherlich
nicht überraschend. Das ist übrigens ähnlich mit Deinem Assembler: das
wird heutzutage in der Industrie kaum mehr benutzt, weil das außer in
wenigen Randgebieten kaum noch Vorteile gegenüber C hat, dafür aber viel
höhere Entwicklungskosten bedingt.
S. R. schrieb:> Einspruch, euer Ehren. Dieses ganze "ARM ist nicht schwerer als> AVR"-Gerede ist großer Unfug und das wisst ihr selbst.
Ich finde es gibt ein paar Anfangsschwierigkeiten, danach ist es im
Endeffekt irgendwie doch dasselbe wie beim AVR.
S. R. schrieb:> Das fängt damit> an, dass die klassische AVR-Toolchain einfach "tut", und die klassische> ARM-Toolchain ohne eigenen Startup-Code nicht.
Ja das stimmt, aber bei STM (keine Ahnung wie es bei den anderen ist)
ist fertiges Linkerscript und Startupcode verfügbar. Das heißt man muss
nur lernen es einzubinden. Wenn man ein mal gelernt hat wie es geht, ist
es kein Problem mehr. Die meisten benutzen sowieso eine IDE, da geht das
vollautomatisch. Beim AVR benutzen ja auch viele das AVR Studio. Ich
persönlich benutze lieber Toolchain + Makefile + QtCreator auf Linux.
S. R. schrieb:> Und es hört noch lange> nicht damit auf, dass ein AVR-Datenblatt alle wesentlichen Bestandteile> enthält, ein ARM-Datenblatt in der Regel aber nicht.
Es gibt das Datasheet, Reference- und Programmingmanual. Das Datasheet
brauche ich kaum, nur zum Herausfinden an welchen Bus die Peripherie
hängt, welche Pins zu benutzen sind und welche Nummer die alternate
function hat (um den Multiplexer einzustellen, da man sich oft aussuchen
kann, welche Funktion welcher Pin übernehmen soll). In dem
Referencemanual ist die Peripherie und deren Register genau beschrieben,
so wie man es vom AVR kennt. Das Programmingmanual beinhaltet das
Instructionset und die Beschreibung des ARM Kerns (ARM Cortex-Mx). Das
braucht man kaum (das schaut man sich eher einmal an und gut ist),
höchstens wenn man den NVIC direkt ansteuern will etc.. Ist aber sehr
interessant, vor allem für jemanden der ein OS schreiben will, dann ist
das die erste Anlaufstelle.
S. R. schrieb:> Das ist der> Komplexität und der Mächtigkeit der 32-Bitter geschuldet.
Das ist nicht die Schuld von 32-Bit, die 32-Bitter die ich bisher
getroffen habe, könnten einfach mehr als der 8-Bit AVR. Man könnte
sicher einen minimalistischen 32-Bit µC bauen, aber bisher kenne ich
niemanden der das versucht hat.
S. R. schrieb:> Obwohl das mit ein bisschen Einarbeitung alles nicht unmöglich ist, es> bleibt schwerer, als in die AVR-Welt einzutauchen. Punkt.
Ich gebe zu, dass es ein wenig schwerer ist. Aber überdramatisieren darf
man das nicht.
TriHexagon schrieb:> S. R. schrieb:>> Das ist der>> Komplexität und der Mächtigkeit der 32-Bitter geschuldet.>> Das ist nicht die Schuld von 32-Bit, die 32-Bitter die ich bisher> getroffen habe, könnten einfach mehr als der 8-Bit AVR. Man könnte> sicher einen minimalistischen 32-Bit µC bauen, aber bisher kenne ich> niemanden der das versucht hat.
Das habe ich vorherigen Post wohl falsch verstanden. Ja die höhere
Komplexität kommt mit der höheren Mächtigkeit. Aber ich finde die
Komplexität hält sich auch beim ARM ziemlich in Grenzen. Dazu kommt ja,
dass es da Cortex-M0, M0+, M3, M4, M7 (neu) gibt. Die Mächtigkeit und
die Komplexität nimmt nach rechts zu. Während man mit M4/M7 schon einen
richtigen Rechner bauen kann (eigentlich fehlt nur eine MMU, eine MPU
ist schon da), ist der M0 mit einem AVR besser zu vergleichen.