Forum: Compiler & IDEs C++ Klassen in AVR-Studio


von Zacharias Foxx (Gast)


Lesenswert?

Hallo,

bin ein C++ Head und
versuchte eine Klasse (c++ syntax "class") im AVR-Studio mit dem
AVR-GCC Compiler zu erzeugen. Ging nicht.
Weil ich eine C++ Syntax mit einem C Compiler übersetzen wollte.
So viel weiß ich jetzt.

Wie erzeuge ich denn eine Klasse in C?
(brauche nämlich ein Objekt mit bestimmten Eigenschaften öfter im
Programm)

Oder besser, wie muss ich AVR-Studio konfigurieren, damit ich C++
Syntax verwenden kann?

..einen ähnlichen Beitrag gab es schon mal in diesem Forum, allerdings
brachten mich die Antworten nicht weit.

Bitte um Hilfe

von Rolf Magnus (Gast)


Lesenswert?

> Wie erzeuge ich denn eine Klasse in C?

In C gibt's keine Klassen. Du müßtest das dann zu Fuß machen.

> Oder besser, wie muss ich AVR-Studio konfigurieren, damit ich C++
> Syntax verwenden kann?

Die Datei als C++ compilieren ;-)
Du mußt dazu g++ statt gcc nehmen. Wie das mit AVR-Studio geht, weiß
ich nicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Wie das mit AVR-Studio geht, weiß
> ich nicht.

Meines Wissens gar nicht.  Muss man halt eine andere Bedien-
oberfläche nehmen als AVR Studio, PN2 zum Beispiel.

von Zacharias Foxx (Gast)


Lesenswert?

Ok, danke.

Das habe ich mir fast gedacht.
Werde es wahrscheinlich dann von Hand, mit dem WinAVR, kompilieren.

Schade, das wäre noch eine Erweiterung im AVR-Studio wert.

von Ingo (Gast)


Lesenswert?

Das geht schon mit AVR Studio:

Dateien können so benannt bleiben (.c).
Im Menüpunkt Bulid->ExportMakefile exportierst Du das vom AVRStudio
generierte Makefile
Im Menüpunkt Project->ConfigurationOptions klickst Du die Checkbox
"Use External Makefile" an und wählst das Makefile.
Das Makefile musst Du dann öffnen und als Compiler den avr-c++.exe
auswählen: CC = avr-c++.exe
In der Compile-Section des Makefile noch die Pfade richtig einstellen:
## Compile
test.o: ../test.c (hier muss das ../ meistens weg, abhängig vom Pfad
des Makefiles zu den .c Dateien.

Das AVR Studio kennt schon die C++ Schlüsselworte und highlighted die.

von Marco S (Gast)


Lesenswert?

avr-gcc kompiliert C++-Code, wenn die Sourcedatei auf .cpp, .c++, .C
(für weiteres siehe manual) endet.

von Detlev (Gast)


Lesenswert?

Hat denn schon jemand Erfahrung mit C++ auf AVRs?
(Speicherbedarf/Performance)?

von Rolf Magnus (Gast)


Lesenswert?

Kommt drauf an, was man machen will. Exceptions und RTTI gehen (noch)
nicht, und werden, wenn sie dann gehen, vermutlich viel Platz brauchen.
Ich versuche gerade, die Exception-Unterstützung zum laufen zu bringen.
Virtuelle Memberfunktionen brauchen RAM (Pro Klasse und virtueller
Funktion ein Zeiger), da die vtables bisher dort gespeichert werden. Es
gibt keine C++-Standardbibliothek.
Der Rest funktioniert soweit und hat keinen besonderen Overhead
gegenüber C. Teilweise wird der Code sogar kompakter. Mit Templates und
Klassen lassen sich auch so schon ganz nette Sachen auf einem AVR
machen.

von Karl (Gast)


Lesenswert?

ich nehm für AVR C++ das hier:

http://www.myavr.de/download/myAVR_WorkpadPLUS_Demo.exe


gruß Karl

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Solltest zumindest erwähnen, dass es sich dabei um Payware handelt.
Das dürfte in der GCC-Gruppe nicht so selbstverständlich sein.

von Karl (Gast)


Lesenswert?

ich arbeite mit der DEMO, geht eben nur der Codewizard nicht...
Einschränkungen in punkto Codegröße habe ich nicht bemerkt, ansonsten
gibts ja noch Eclips oder DEV++ die gehen sollten, beim der
workpad-demo brauchte ich für AVR C++ nix weiter mehr konfigurieren es
ging eben einfach ;-)

von Ingo (Gast)


Lesenswert?

Rolf Magnus, hast Du new und delete schon zum Laufen bekommen?

Ich bin leider beruflich sehr eingespannt würde aber gerne meine
(schmale) Unterstützung anbieten: ogni42(at)gmx.de

von Zacharias Foxx (Gast)


Lesenswert?

Hallo Ingo,

respekt, ich wäre da so schnell nicht hingekommen.

Hab mich an deine Anleitung gehalten und funktioniert.

Vielen Dank!!!!!!!!!

von Ingo (Gast)


Lesenswert?

Gern geschehn :)

Habe aber vergessen darauf hinzuweisen, dass die Nutzung des Debuggers
(noch) nicht funktioniert.

Rolf Magnus' Hinweis kann ich nur stützen: Bei mir benötigt der C++
tendenziell weniger RAM als ein entsprechender C Code aber etwas mehr
Flash (ca. 1%). Das kann aber natürlich auch am Programmierstil liegen.

von Rolf Magnus (Gast)


Lesenswert?

> Rolf Magnus, hast Du new und delete schon zum Laufen bekommen?

Wie man's nimmt. Vom Prinzip her sind die kein Problem. Eine triviale
Implementation könnte einfach intern malloc/free aufrufen. Die Version,
die in der libsupc++ *) enthalten ist, macht das auch, ruft aber auch
noch evtl. installierte new-Handler auf und wirft im eine Exception,
wenn malloc 0 zurückgibt. Und da liegt das Problem. Diese Exception
zieht ca. 11kB Code in das Programm und funktioniert dann nicht mal.

*) libsupc++ ist die Biblitothek, die die grundlegenden
Implementationen für C++-Support enthalten, also z.B. operator new, die
typeid-Implementatioenen für RTTI oder den unwinding-Code für
Exceptions.

> Ich bin leider beruflich sehr eingespannt würde aber gerne meine
> (schmale) Unterstützung anbieten: ogni42(at)gmx.de

Naja, ich habe festgestellt, daß das Wühlen durch die gcc-Eingeweide
trotz der eigentlich ziemlich guten Dokumentation recht schwierig und
aufwendig ist. Du könntest dich in die Mailingliste
avr-gcc-list@nongnu.org eintragen.

von Ingo (Gast)


Lesenswert?

Dann werde ich mich am WOchenende mal um einen Eintrag in der
Mailinglist kümmern und mir eine Kopie der libsup++ ziehen. Ich melde
mich dann hier wieder....

von Karl heinz B. (kbucheg)


Lesenswert?

> Diese Exception zieht ca. 11kB Code in das Programm

Das ist allerdings heftig.

Könntest du dich mit der Variante anfreunden die MS lange
Zeit gefahren ist? new liefert im Fehlerfall 0 zurück.

Ist zwar nicht Standard-konform, aber Speicherplatz geht
in diesem Fall vor :-)

> Der Rest funktioniert soweit und hat keinen besonderen Overhead
> gegenüber C.

Das wäre dann allerdings mal eine Überlegung wert.

von Entnervter (Gast)


Lesenswert?

> Könntest du dich mit der Variante anfreunden die MS lange
> Zeit gefahren ist? new liefert im Fehlerfall 0 zurück.

Im Prinzip schon. Man könnte es ja auch davon abhängig machen, ob
Exceptions an sind oder nicht.
Es ging ja auch erstmal darum, zu schauen, ob die libsupc++ mit dem AVR
zum Laufen zu bekommen ist. Vielleicht könnte man den Overhead von
Exceptions auch drücken, aber ich habe keine Ahnung davon, wie
Exception-Handling intern funktioniert. Nach dem Code zu urteilen, ist
es sehr aufwendig.
Ich glaube, man kann für bestimmte Targets einzelne Dateien der
libsupc++ durch andere Implementationen ersetzen. Das werde ich mal mit
Operator new probieren.

>> Der Rest funktioniert soweit und hat keinen besonderen Overhead
>> gegenüber C.
>
> Das wäre dann allerdings mal eine Überlegung wert.

Ich benutze oft C++ auf den AVRs. Es muß ja nicht immer gleich alles
mit Polymorphie und Exceptions sein.
Man kann auch mit dem Rest noch viel machen, z.B. ein nettes
Klassentemplate für Fixkomma-Zahlen oder Bigint. Ich habe sogar
rausgefunden, daß es einen Weg gibt, diese für Berechnungen zur
Laufzeit in inline-ASM zu implementieren (z.B. um bei kaskadierten
Additionen das Carry-Flag nutzen zu können), aber trotzdem auch
Constant-Folding zu ermöglichen.
Oder ein Queue-Klassentemplate mit der zu verwendenen Speichergröße als
Template-Parameter. So eine benutze ich auch schon, um Textausgaben an
eine USART-Interruptroutine zu übergeben, damit ich nicht immer auf die
Schnittstelle warten muß. Das war das erste Mal, daß ich
Memberfunktionen als volatile deklarieren mußte ;-)
Ich habe mir auch schon 'Smart'-Pointers zum Zugriff auf Flash und
EEPROM gebastelt. Eine Dereferenzierung macht automatisch den Zugriff.
Leider den operator-> nicht brauchbar implementieren.
An einer reduzierten iostream-artigen Klasse arbeite ich auch schon
rum.

von Rolf Magnus (Gast)


Lesenswert?

Ups, da war noch ein Name eingstellt, den ich gestern verwendet hab, als
ich so entnervt war ;-)

von Karl heinz B. (kbucheg)


Lesenswert?

> Ich benutze oft C++ auf den AVRs

Ich hab mich bisher noch nicht drübergetraut.
Na ja. Ich hatte auch noch keinen wirklichen Bedarf :-)

> mit Polymorphie und Exceptions sein.

Sehe ich auch so. Auf Exceptions kann ich verzichten.
Polymorphie wäre schon schmerzhafter :-)

> Ich habe mir auch schon 'Smart'-Pointers zum Zugriff auf Flash und
> EEPROM gebastelt.

Die wären natürlich toll.
Oder auch die std::string wäre natürlich kein Vergleich zu
strcpy() und co.

Mal eine vernünftige Timer-Klasse ohne jedesmal im Datenblatt
nachzuschauen, wo denn nun wieder die Bits rumlungern und wie
denn wieder dieser besch... ISR Name war, etc...
Oder den USART Kapseln, oder ...

von Rolf Magnus (Gast)


Lesenswert?

>> mit Polymorphie und Exceptions sein.
>
> Sehe ich auch so. Auf Exceptions kann ich verzichten.
> Polymorphie wäre schon schmerzhafter :-)

Naja, Polymorphie funktioniert durchaus mit avr-g++. Leider werden aber
die vtables im RAM abgelegt, was dort pro polymorpher Klasse und
virtueller Funktion Platz für einen Zeiger kostet.
Bisher gibt es keine Lösung, um das komplett im Flash zu machen.
Theoretisch möglich wäre es, da die vtables zur Laufzeit eh konstant
sind. Das Problem ist, daß beim GCC die vtables im Prinzip einfach als
globale Variablen definiert werden. Auf Variablen kann er aber
bekanntlich nur zugreifen, wenn sie im RAM stehen, da GCC keinerlei
Support für Harvard-Architekturen hat.

>> Ich habe mir auch schon 'Smart'-Pointers zum Zugriff auf Flash
>> und EEPROM gebastelt.
>
> Die wären natürlich toll.

Funktionieren eigentlich ganz gut ;-)
So in der Art sehen meine AVR-Programme heute aus:

#include <avr++/pgmspace>

const char helloworld[] PROGMEM = "Hello, world";

void put_string(pgmspace_ptr<char> p)
{
    while (*p++)
        usart::write(*p);
    usart::write('\n');
}

int main()
{
    put_string(pgmspace(helloworld));
}

Mittlerweile auch:

    cout << pgmspace(helloworld) << '\n';

Die cout-Variante könnte sparsamer werden als printf, da printf einen
Formatstring-Parser und alle unterstützten Konvertierungen enthält.
Selbst wenn ich nur einen String ausgebe, wird gleich alles mit
reingenommen. Bei cout fällt der Parser weg und es werden immer nur die
Konvertierungen übernommen, die im Programm verwendet werden. Einfache,
wie die für char können auch gleich inline expandiert werden und lösen
sich damit in Wohlgefallen auf.

> Oder auch die std::string wäre natürlich kein Vergleich zu
> strcpy() und co.

Naja, ob das so sinnvoll ist, ist die Frage. Da muß halt immer viel
dynamisch allokiert werden.

> Mal eine vernünftige Timer-Klasse ohne jedesmal im Datenblatt
> nachzuschauen, wo denn nun wieder die Bits rumlungern und wie
> denn wieder dieser besch... ISR Name war, etc...
> Oder den USART Kapseln, oder ...

Jo, gibt viele nette Sachen, die man machen könnte. Muß nur mal jemand
in Angriff nehmen ;-)

von Michael Z. (incunabulum)


Lesenswert?

Nur als Hinweis: Das WinAvr-Plugin für Eclipse eignet sich auch ganz gut
für die C++ Entwicklung. Für die, die Eclipse kennen und lieben,
vielleicht eine nette Alternative.

Die Kapselung von all den Atmel-internen Funktionen wär aber was :-)
Momentan scheint ja jeder fallspezifisch sein eigenes Ding zu
entwickeln

von Peter D. (peda)


Lesenswert?

@Ingo,

"Bei mir benötigt der C++
tendenziell weniger RAM als ein entsprechender C Code aber etwas mehr
Flash (ca. 1%). Das kann aber natürlich auch am Programmierstil
liegen."


Könnte aber auch sein, das dann Variablen mit malloc angelegt werden
und nicht mehr in der Statistik auftauchen.

Die wirkliche Speicherauslastung läßt sich nur zur Laufzeit ermitteln
und das auch nicht gerade einfach.

Da ich kein malloc benutze, fülle ich einfach den freien Bereich mit
0x77 und prüfe dann nach einiger Laufzeit, wieviel davon noch
unverändert ist.


Peter

von Rolf Magnus (Gast)


Lesenswert?

> Könnte aber auch sein, das dann Variablen mit malloc angelegt
> werden und nicht mehr in der Statistik auftauchen.

Nein. Es gibt Momentan keine libsupc++. Diese wäre das einzige, was
malloc aufrufen könnte. Ich wüßte auch nicht, wo sowas implizit nötig
wäre (abgesehen von operator new, für welchen aber auch keine
Implementation existiert).

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.