Forum: Compiler & IDEs AVR (8-Bit) / C++ Toolchain


von Jasson (Gast)


Lesenswert?

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

von Einfach (Gast)


Lesenswert?

Arduino IDE

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Guest (Gast)


Lesenswert?

Atmel Studio 7, da ist GCC für C/C++ integriert, sowie viele Programmer 
zum Übertragen auf den Chip.

von Volker S. (vloki)


Lesenswert?

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
von Oliver S. (oliverso)


Lesenswert?

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
von Wilhelm M. (wimalopaan)


Lesenswert?

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 ...

von Oliver S. (oliverso)


Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

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.

von Oliver S. (oliverso)


Lesenswert?

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

von Veit D. (devil-elec)


Lesenswert?

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
von Rolf M. (rmagnus)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

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++

von Jasson J. (jasson)


Lesenswert?

>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.
von Oliver S. (oliverso)


Angehängte Dateien:

Lesenswert?

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
von Wilhelm M. (wimalopaan)


Lesenswert?

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
von Oliver S. (oliverso)


Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

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

von Wilhelm M. (wimalopaan)


Lesenswert?

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

von Oliver S. (oliverso)


Lesenswert?

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.
von Wilhelm M. (wimalopaan)


Lesenswert?

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
Noch kein Account? Hier anmelden.