Abend zusammen, nach den üblichen Recherche-Ansätzen habe ich keine abschließende Antwort gefunden. Ich möchte mit C++ auf 8 Bit AVR´s gehen und kann mir einige Fragen nicht sicher beantworten. Welche Toolchain funktioniert? (Ab Atmel Studio 'X', mit Compiler 'Y', mit Programmer 'Z') Ich habe gesehen, es gibt einen Thread in der Richtung Beitrag "AVR C++ Toolchain" Da geht es aber nicht dediziert um 8Bitter. viele Grüße
Ich habe folgendes: * avr-g++ (aktuell 9.2, oder 10.0 von trunk selbst compilieren) * make * QtCreator oder VsCode * avrdude (für ISP) * pyupdi für UPDI Weil oft gefragt: ein C++-StdLib ist beim avr-g++ nicht(!) dabei, wenngleich man viele templates aus der OSS-Implementierung des g++ kopieren/anpassen kann. Kommt etwas auf Deine C++-Skills an.
Atmel Studio 7, da ist GCC für C/C++ integriert, sowie viele Programmer zum Übertragen auf den Chip.
MPLABX IDE: https://www.microchip.com/mplab/mplab-x-ide AVR Toolchain: https://www.microchip.com/mplab/avr-support/avr-and-arm-toolchains-c-compilers Atmel ICE, PICkit4, ICD4 oder MPLAB SNAP als Progranner/Debugger Scheint zu funktionieren und kann mit einem MPLABX Plugin auch Arduino Projekte importieren. (erste Tests erfolgreich, inklusive Debuggen)
:
Bearbeitet durch User
Jeder avr-gcc ist ein gcc, und kann daher so viel C++, wie ein gcc halt so kann. Die üblichen verfügbaren avr-gcc-toolchains machen auch alles mit. Es braucht ein paar paar zusätzliche Funktionen für new, delete, und für einen virtuellen Funktions-Handler (google weiß Bescheid), damit lassen sich dann C++-Programme problemlos kompilieren. https://www.avrfreaks.net/forum/avr-c-micro-how?page=all Es fehlt hat, wie oben schon geschrieben wurde, die C++Standardlib. Das, was Microchip dazu schreibt, gilt sinngemäß für alle toolchains auf Basis avr-gcc (also alle): https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_cplusplus.html Oliver
:
Bearbeitet durch User
Oliver S. schrieb: > Es braucht ein paar paar zusätzliche Funktionen für new, delete Darauf würde ich komplett verzichten, und alle Allokationen statisch machen. Also std::array<> verwenden oder sich einen FixedCapacityVector<> schreiben. Ggf. brauch man ein placement-new, falls man einen Ctor in-place aufrufen will. Kommt aber sehr selten vor, wenn überhaupt ...
Kann jeder halten und machen, wie er will. std::array scheitert zunächst an der fehlenden Standard-lib, das muß man sich alles selber schreiben. Wie, ist dann einfach Ermessenssache. Virtuelle Klassen sind auch nicht optimal, da avr-gcc die vtables ins eh knappe Ram legt. Wer die aber trotzdem nutzen will, braucht die o.a. Funktionen. Wer nicht, der nicht. Oliver
Oliver S. schrieb: > std::array scheitert zunächst > an der fehlenden Standard-lib, das muß man sich alles selber schreiben. Ich gehe davon aus, dass der TO C++ Erfahrung hat, sonst würde er nicht mit C++ Richtung µC gehen wollen. Daher sollte ein (für µC optimiertes) template std::array<> nichts weiter als eine Fingerübung sein.
Wilhelm M. schrieb: > Ich gehe davon aus, dass der TO C++ Erfahrung hat Die Art der Fragestellung lässt eigentlich nicht erkennen, worin der TO Erfahrung hat. Sie lässt nur klar erkennen, worin er keine hat... Oliver
Jasson schrieb: > Welche Toolchain funktioniert? (Ab Atmel Studio 'X', mit Compiler 'Y', > mit Programmer 'Z') Du müßtest deine Frage konkretisieren. Welcher µC? Welche C++ Version? Weil grundlegend kannst du in Atmel Studio 7 alle 8Bitter ATmegas programmieren. AS7 kommt standardmäßig mit avr-gcc 5.4.0 daher. Für C++11 reicht das. Ansonsten kannst du AS7 jederzeit eine neuere Toolchain an die Hand geben.
:
Bearbeitet durch User
Wilhelm M. schrieb: > Oliver S. schrieb: >> std::array scheitert zunächst >> an der fehlenden Standard-lib, das muß man sich alles selber schreiben. > > Ich gehe davon aus, dass der TO C++ Erfahrung hat, sonst würde er nicht > mit C++ Richtung µC gehen wollen. Daher sollte ein (für µC optimiertes) > template std::array<> nichts weiter als eine Fingerübung sein. In Beitrag "Re: Initialwert von globalen Variablen zur Laufzeit verwenden" hattest du doch geschrieben, dass es die schon gibt. Du hast da nur nicht verraten, wo.
Rolf M. schrieb: > In Beitrag "Re: Initialwert von globalen Variablen zur Laufzeit > verwenden" hattest du doch > geschrieben, dass es die schon gibt. Du hast da nur nicht verraten, wo. 1) Die C++-Std_Lib ist OSS. Also: reinschauen und/oder kopieren, soweit es die Lizenz für Dich zulässt. 2) https://www.etlcpp.com/array.html 3) Die non-library-writers Version behandelt man im Anfängerkurs C++
>Also danke schon mal für die konstruktiven Antworten!
Offenbar kann ich´s im Rahmen meines Hobbys mit positiver Hoffnung drauf
ankommen lassen.
Ich setzte einfaches C++ ein. Das komplexeste ist eine abstrakte Klasse,
welche auf eine Templateklasse vererbt wird, aus der dann verschiedene
abgeleitete Klassen erzeugt werden.
Ich hab noch ein Visitor Pattern am Werk - ich werd´s erleben.
Habe oben gelesen, dass das vtables im RAM landen, muss ich dann sehen,
ob´s hinkommt.
Ziel wird wahrscheinlich Mega64/128 o.ä. sein. Etwas mechanisch großes,
was im DIP Format zu kriegen ist.
Beitrag #6070859 wurde vom Autor gelöscht.
Wie gesagt, du brauchst dazu eine handvoll Funktionen, ansonsten gibt es undefined references (zumindest im Debug-Build). Aus dem avrfreaks-Thread habe ich mit mal das im Amhang zusammengetsellt, das hat bisher mit allen avr-gcc-toolchains, die ich benutzt haben, funktioniert. Ob die guard-Funktionen darin tatsächlich bei aktuellen Compilern noch benötigt werden, habe ich nie ausprobiert. Der avrfreaks-Thread ist ja doch inzwischen uralt. Oliver
:
Bearbeitet durch User
Jasson J. schrieb: > Ich setzte einfaches C++ ein. Das komplexeste ist eine abstrakte Klasse, > welche auf eine Templateklasse vererbt wird, aus der dann verschiedene > abgeleitete Klassen erzeugt werden. Ich weiß nicht, ob diesen etwas wirren Satz richtig verstehe. Aber: Dyn. Polymorphie und statische Polymorphie gleichzeitig (in einer(!) Klassenhierarchie) zu verwenden, ist meistens keine gute Idee. Vielleicht meinst Du aber auch das OO template-pattern, was nichts mit C++-template-Mechanik zu tun hat.
:
Bearbeitet durch User
Oliver S. schrieb: > Ob die guard-Funktionen darin tatsächlich > bei aktuellen Compilern noch benötigt werden, habe ich nie ausprobiert. > Der avrfreaks-Thread ist ja doch inzwischen uralt. Weils mich dann doch jetzt mal interssiert hat: Hier gibts eine gute Erklärung: https://iamroman.org/blog/2017/04/cpp11-static-init/ Und -fno-threadsafe-statics ist das Compilerflag der Wahl ;) Dann brauchts die guards nicht. Oliver
Oliver S. schrieb: > Und -fno-threadsafe-statics ist das Compilerflag der Wahl ;) Ja, das sollte auf einem µC ohne OS eingeschaltet werden. Dazu gab es einen gcc-bug, der mich schon mal echt Nerven gekostet hatte: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83730
Bei
1 | struct A { |
2 | A() {} |
3 | int m{42}; |
4 | };
|
5 | |
6 | namespace { |
7 | void g() { |
8 | static A a; |
9 | }
|
10 | }
|
11 | |
12 | int main() { |
13 | g(); |
14 | }
|
werden die guards immer noch (trotz -fno-threadsafe-statics) generiert, aber nicht mehr verwendet.
1 | $ avr-size bm00.elf |
2 | text data bss dec hex filename |
3 | 224 0 8 232 e8 bm00.elf |
1 | $ avr-nm -C bm00.elf | grep guard |
2 | 00802800 b guard variable for (anonymous namespace)::g()::a |
Wilhelm M. schrieb: > werden die guards immer noch (trotz -fno-threadsafe-statics) generiert, > aber nicht mehr verwendet. Was in deinem Bespiel daran liegt, daß der Compiler alles wegoptimiert. Wilhelm M. schrieb: > 00802800 b guard variable for (anonymous namespace)::g()::a Das erste Byte enthält das Initialisierungsflag, das hat mit den guards nichts zu tun (und das wird bei der Initialisierung auch gelesen und geschrieben, auch mit -fno-threadsafe-statics). Warum der Block dafür allerdings nicht nur 1 Byte, sondern gleich 8 Byte lang ist, wissen wohl nur die gcc-Götter. Oliver
:
Bearbeitet durch User
Beitrag #6071325 wurde vom Autor gelöscht.
Oliver S. schrieb: > Was in deinem Bespiel daran liegt, daß der Compiler alles wegoptimiert. Nein. Eben nicht. Das init-flag wird gesetzt und die guards nicht verwendet. Das hat nichts mit der Optimierung zu tun, sondern mit dem flag -fno-threadsafe-statics. Was aber eben nicht gut ist, dass die guard-variable nicht auch gleich unterdrückt wird.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.