Hallo, ich möchte den << Operator einer Ausgabeklasse so überladen, dass String Pointer sowohl auf Flash als auch auf Ram aufgelöst und separat behandelt werden können. Z.B. so: Uart << "TextImRam" << PSTR("TextImFlash"); Wahrscheinlich geht das nicht, da ja letztendlich beide Pointer gleich aussehen (word auf die Adresse). Wenn ich aber den << Operator wie folgt deklariere: CUart& operator << (char*); gibt es einen Complilerfehler "ambiguous overload for 'operator<<' in 'Uart<<({...})'" Also gibt es doch eine Möglichkeit eine Überladung für den PSTR zu definieren? Sowas wie CUart& operator << (char*); CUart& operator << (PROGMEM char*); funktioniert nicht. Auch einen neuen Type für char* definieren und beim beim Aufruf casten geht nicht (z.B. Uart << (flChar_t)PSTR("TextImFlash");) Gibt es vielleicht doch eine halbwegs elegante Lösung für dieses Problem?
Mit der seit gcc 4.7 veerfügbaren __flash Erweiterung könnte es gehen http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#__flash_und_Embedded-C Hab aber keine Erfahrung damit, kann daher auch sein, dass ich da jetzt Blödsinn rede.
Johann L. schrieb: > Nein, __flash gibt's nicht für g++. Liegt das eigentlich nur daran, dass der C++-Standard sowas bislang nicht vorsieht, oder gibt es technische Gründe? Ich glaube mich zu erinnern, dass andere Compiler (wie IAR) durchaus auch __flash im C++-Modus verstehen.
Ich habe nun eine (allerdings unschöne) Variante gefunden:
1 | char OutputBuffer[20]; |
2 | #define _FL(s) strcpy_P(OutputBuffer,PSTR(s))
|
3 | |
4 | Uart << "TextImRam" << _FL("TextImFlash"); |
_FL() gibt einen Pointer auf den vom Flash in den RAM kopierten String zurück, der keiner weiteren besonderen Behandlung bedarf ...
Jörg Wunsch schrieb: > Johann L. schrieb: >> Nein, __flash gibt's nicht für g++. > > Liegt das eigentlich nur daran, dass der C++-Standard sowas bislang > nicht vorsieht, oder gibt es technische Gründe? Zunächst liegt es daran, daß niemand es machen will oder machen kann. Embedded-C sagt, daß es als C++ Erweiterung implementiert werden kann, aber eine Erweiterung der C++ Spez ist nicht anbei. Erschwerend kommt hinzu, daß Embedded-C in einigen Punkten nicht fertig gedacht ist und selbst in C11 keinen Einzug fand. So ist es bekanntlich nicht möglich, eine locale, statische Variable im non-generic zu haben. Und Code wie der folgende ist auch nicht möglich, was die Portierung hin zu Embedded-C mitunter deutlich erschwert:
1 | const __flash char* str[] = { "Kund", "Matze", "Haus" }; |
Und während es in C immer möglich ist, statische const-Objekte in eine readonly Section zu legen — vorausgesetzt man hat ein Target wie ELF, das diese unterstützt — ist das in C++ nicht der Fall. Z.B. ist es nicht möglich, sich in C++ eine Fixedpoint-Implementierung zu basteln, und die dadurch modellierten Zahlen in einer Lookup-Tabell ins Flash zu legen. M.M. ist bereits das ein Beleg dafür, daß diese aufgeblähte Sprache kläglich versagt: Wenn C++ noch nicht mal schafft, das bisschen Embedded-C Zeugs mit all dem Template- und Overload- und Operator- und Ableite- und Konstruktor- und User-defined-Literal-Zeugs nachzubilden, dann stimmt irgendwas grundlegendes nicht. > Ich glaube mich zu erinnern, dass andere Compiler (wie IAR) durchaus > auch __flash im C++-Modus verstehen. Ja, mag sein. Wenn man das haben will, dürfe es jedoch um Größenordnungen günstiger sein, sich nen IAR anzuschaffen als einen GCC-Entwickler für die Implementierung der entsprechende Erweiterung anzuheueren — den unwahrscheinlichen Fall gesetzt, daß man überhaupt eines entspechend qualifizierten GCC-Entwicklers habhaft wird.
Warum wird Embedded-C immer zu einem Buch verlinkt? Wie kann ich das abschalten? Ich will keine Links zu einem Buch weil es nicht um irgendein Buch geht!
Johann L. schrieb: > Und während es in C immer möglich ist, statische const-Objekte in eine > readonly Section zu legen — vorausgesetzt man hat ein Target wie ELF, > das diese unterstützt — ist das in C++ nicht der Fall. > > Z.B. ist es nicht möglich, sich in C++ eine Fixedpoint-Implementierung > zu basteln, und die dadurch modellierten Zahlen in einer Lookup-Tabell > ins Flash zu legen. Weshalb sollte das nicht gehen? Sowas geht in c++ problemlos: float const PROGMEM s[2]={1.1,1.2};
Es geht nicht mehr, sobald du ein nicht POD nimmst, wie es für eine Fixedpoint-Implementierung in C++ der Fall sein würde.
Johann L. schrieb: > Warum wird Embedded-C immer zu einem Buch verlinkt? Das musst du Andreas fragen ... Johann L. schrieb: > Wenn man das haben will, dürfe es jedoch um Größenordnungen günstiger > sein, sich nen IAR anzuschaffen als einen GCC-Entwickler für die > Implementierung der entsprechende Erweiterung anzuheueren OK, ich nahm an, dass sich das mehr oder weniger geradezu aus der C-Implementierung übernehmen ließe. Wenn dem nicht so ist, dann ist mir auch klar, dass das nicht so schnell passieren wird.
Jörg Wunsch schrieb: > Johann L. schrieb: >> Warum wird Embedded-C immer zu einem Buch verlinkt? > > Das musst du Andreas fragen ... Der wird kaum was ändern daran. Ich schreib einfach Embedded–C statt Embedded-C, scheint zu funktionieren. > Johann L. schrieb: >> Wenn man das haben will, dürfe es jedoch um Größenordnungen günstiger >> sein, sich nen IAR anzuschaffen als einen GCC-Entwickler für die >> Implementierung der entsprechende Erweiterung anzuheueren > > OK, ich nahm an, dass sich das mehr oder weniger geradezu aus der > C-Implementierung übernehmen ließe. Wenn dem nicht so ist, dann > ist mir auch klar, dass das nicht so schnell passieren wird. Keine Ahnung wie die Fronts aufgebaut sind, auf Platte liegen sie in gcc/c, gcc/cp und gcc/c-family. Wieviel und ob C++ von C verwendet weiß ich net, ich würd aber davon ausgehen, daß das C++-Front nicht auf dem C-Front basiert. Da meiner Erfahrung nach nichts in GCC einfach ist, ist das C++-Front garantiert nicht einfach. Aber das ist natürlich eine Sache der Vertrautheit damit. Außer Gaby fällt mir niemand ein, der sowas implementieren könnte. Allerdings ist er Mitgied in der WG21 (C++) und was Qualifier angeht, steht die definitiv auf "Njet". Zum Thema gab's nen längeren Tratsch: > In general, there is an aversion [of WG21] towards more qualifiers. > I suspect this is mostly because of the committee being burned > by "volatile" and also because qualifiers tend to lead to > combinatorial explosion when it comes to implicit conversions > and overload resolution. http://lists.gnu.org/archive/html/avr-gcc-list/2012-05/msg00044.html Neben der Unterstützung im Sprachkern wäre zu klären, ob libsupc++ oder libstdc++ erweitert werden müssen, um sowas zu unterstützen. Und als C++-Maintainer würd ich dann erstmal nachfragen, warum die Sprache für ein Target aufgebohrt werden sollte, das noch nicht einmal die o.g. Bibliotheken generiert. Und Gaby weiter: > The trend has been to use classes (sometimes with compiler > support) to render abstractions such as these. See for example > how C++11 handles atomics (std::atomic<T>) compared to C11 (_Atomic). Was immer das bedeutet ;-) Für Flash wäre das dann wohl ein std::flash<T>? Was ist "flash" in dem Zusammenhang? Und wer wo wie wird das implementiert und spezifiziert?
Johann L. schrieb: > Was ist "flash" in dem Zusammenhang? Und wer wo wie wird das > implementiert und spezifiziert? Na ich würde aus >> to use classes (sometimes >> with compiler support So interpretieren, dass der Compiler bestimmte Klassen "kennt" oder speziell behandelt (analog zum 'native' Konstrukt in Java), man würde dann halt nur die definition per header einbinden, und die Implementierung kommt "irgendwie" (entweder durch den Compiler oder eine speziell gebaute lib) dazu.
Johann L. schrieb: > Es geht nicht mehr, sobald du ein nicht POD nimmst, wie es für eine > Fixedpoint-Implementierung in C++ der Fall sein würde. Was ist ein POD? Innerhalb eines Klassenkontextes muss ich natürlich mit diversen Einschränkungen leben (falls du das meinst). Auserhalb einer Klasse habe ich aber noch keine Einschränkungen bzgl. C bemerkt. Da ich c und c++ beliebig mischen kann, kann ich auch alles implementieren (wenn auch nicht besonders elegant).
Johann L. schrieb: > Was ist "flash" in dem Zusammenhang? Und wer wo wie wird das > implementiert und spezifiziert? Das wäre die Frage, die ich mir dabei auch stellen würde. ;-) Auch, wenn ich an sich natürlich einen gewissen Sinn darin sehe, dass man das (zumindest auf User-Ebene) über Klassen abstrahiert. Im Prinzip könnte man ja trotzdem den Qualifier __flash dann haben (der die nötigen Aktionen im Compiler triggert), nur dass man derartiges halt nicht im Standard sehen will. Die "offizielle" Implementierung ist dann eine Klasse, die in einem compilerspezi- fischen Header darauf aufbauend implementiert wird. > Da meiner Erfahrung nach nichts in GCC einfach ist, ist das C++-Front > garantiert nicht einfach. Überzeugt. ;-)
Da gabs doch mal was ... Beitrag "Re: C++ Klassenbibliothek für AVR" Löst zwar nicht ganz direkt das Problem, könnte aber helfen, es zu lösen. Oliver
c++User schrieb: > Johann L. schrieb: >> Es geht nicht mehr, sobald du ein nicht POD nimmst, wie es für eine >> Fixedpoint-Implementierung in C++ der Fall sein würde. > > Was ist ein POD? Innerhalb eines Klassenkontextes muss ich natürlich mit > diversen Einschränkungen leben (falls du das meinst). Ja, z.B: keine Konstruktoren ;-) "Plain Old Data" http://stackoverflow.com/questions/146452/what-are-pod-types-in-c Jörg Wunsch schrieb: > Johann L. schrieb: >> Was ist "flash" in dem Zusammenhang? Und wer wo wie wird das >> implementiert und spezifiziert? > > Das wäre die Frage, die ich mir dabei auch stellen würde. ;-) Von der Syntax her wäre es ein Template, das eine gewisse Magie implementiert aber weder vom Standard spezifiziert ist noch allgemen im GCC bekannt. Ich vermute mal "atomic" is im C++ Standard, nebst unterschiedlicher Speichermodelle. Wenn es denn ein Template ist bzw. syntaktisch so funktionieren soll, dann braucht GCC eine Möglichkeit, targetspezifische Templates zu definieren, die mehr oder weniger beliebige Semantik haben können: - Datenablage - Diagnostics - Adressbildung und Pointer-Casts - Überladungen von -> und was auch immer - Konstruktion spätestens zur Linkzeit, oder es braucht nen Booltoader - Testing und Rückwirkungsfreiheit auf nicht-betroffene Architekturen - Support und zeitnahes Beheben von Front-End und Middle-End Bugs Ansonsten fliegt der ganze Krempel wieder raus, wär nicht der 1. Mal - ... Viel Spaß :-) Selbst bei meinen rudimentären GCC und C++ Kenntnissen wird mir da ganz schummrig... Und die POD-Einschränkung hätte man immer noch, in Endeffekt Mücke PR50807 aufgeblasen zum Elefanten. Dies weil ein Konstruktor ausgeführt werden muss, d.h. ein nicht-POD erst zur Loadzeit konstruiert werden kann. >> Da meiner Erfahrung nach nichts in GCC einfach ist, ist das C++-Front >> garantiert nicht einfach. > > Überzeugt. ;-) Vielleicht funktioniert ein klassischen Anti-Pattern: "Feature Creep" per PR43745 (Vtables im Flash). Da wäre der Qualifier "unter der Motorhaube" und (noch) keine Spracherweiterung. Wer std::flash<T> zum GCC beitragen mag, kann sich mit PR43745 ja schon mal warmlaufen :-))
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.