Hallo! Ich sammle gerade meine ersten Erfahrungen mit dem avr-gcc. Vorher habe ich bereits unter Win und Linux mit C++ programmiert, so dass ich Gott sei dank nicht ganz im Regen stehe. Jedenfalls brauche ich eine dynamische Speicherstruktur für einen struct, der eben beliebig viele male vorkommen kann. Dazu würde ich sowas wie den vector-Template in der stl nutzen, aber sowas gibt es hier ja (scheinbar) nicht. Muss ich jetzt das Rad neu erfinden und eine verkettete Liste mit all ihren Funktionen schreiben, die benötigt werden oder geht es auch irgendwie anders? Grüße! P.S.: Leider gibt es das malloc-Tutorial noch nicht. Wird sicher sehr interessant.
du solltest davor wissen wieviel du an speicher brauchst. ERzähl mal was du machen willst und irgendjemand sagt dir dan wie dus machen könntest....
@ Günther Frings: AVR gcc unterstützt keine Objektorientierung ! Daher alles schön im alten C Linked-List-Stil machen. Wobei "beliebig viel" bei ein paar k RAM eigentlich keinen Sinn macht ? Wäre dann sowas:
1 | typedef struct linkedlist { |
2 | int datum; |
3 | struct linkedlist *next; |
4 | } llist; |
5 | |
6 | llist *head = NULL; |
Und stl mit Containern kannste gleich vergessen :P Und statt new mit malloc und free arbeiten :P
Hi! Ja, das sind ganz neue Herausforderungen im Programmierstil. Habe auch rausgefunden, dass man statt überladener Funktionen auch einfach ein DEFINE nutzen kann, um z.B. sowas zu machen: void fkt_xy(uint8_t x, uint8_t y); #define fkt_x(x) fkt_xy(x, 0) Das spart schonmal ein paar Bytes. Muss man echt clever sein. Meine LCD-Displayroutine belegt nämlich schon so etwa 564 Byte Flash. Also ursprünglich wollte ich mit der dyn. Struktur auf meinem Display Bereiche definieren. Dann macht man einen Ausgabebefehl und er beschreibt nur diesen Bereich. Jetzt bin ich jedoch -platzschonender- dazu übergegangen einfach einen out_xy-Befehl zu erzeugen und dann mit define Konstanten zu definieren, die praktisch meine Bereiche darstellen. (z.B. out_xy("12%", EMPFANGSANZEIGE_X, EMPFNGSANZEIGE_Y); ) Mal davon ab. Habe gestern mal sowas versucht: typedef struct { irgendwas... } mytype; mytype* myvar; myvar = malloc(sizeof(mytype)); myvar.irgendwas=...; // myvar jetzt nutzen free(myvar); Habe ich das so richtig verwendet? Denn mit dem Debugger kam ich noch nicht so recht zurecht. Der zeigte mir nach der Zuweisung zu myvar.irgendwas immernoch 0 an. (Ich habe eh den Eindruck, dass der Debugger manchmal etwas rumspinnt) Grüße!
Der Schritt von C nach C++ ist verdammt schwierig, aber zurück ist es leider genauso. Vergiß alles, was du über Objekte, Verebung, Überladung, etc. kennst. Das gibt es nicht mehr. Ab jetzt geht es nur noch funktionsorientiert, und hardwarenah. Und solche Verrenkungen wie void fkt_xy(uint8_t x, uint8_t y); #define fkt_x(x) fkt_xy(x, 0) sparen NullKommaGarnix, sie führen nur zu völlig unlesbarem und damit zu mit Sicherheit nicht fehlerfreiem Code. "Meine LCD-Displayroutine belegt nämlich schon so etwa 564 Byte Flash." Wow. Welchen AVR benutzt du denn? Wenn dich schon 564 byte Flash in Bedrängnis bringen, dann hat der so wenig RAM, daß du über C, C++, oder gar malloc() wirklich nicht nachzudenken brauchst. Oliver
Nachtrag: Die Doku ist eigentlich eindeutig: If malloc() fails, a NULL pointer is returned Oliver
> AVR gcc unterstützt keine Objektorientierung !
So'n Quatsch.
Davon abgesehen, dass man objektorientiert auch in C programmieren
kann, ist C++ sehr wohl (mit Einschränkungen) unterstützt.
Hallo nochmals! @Oliver: Nein, das mit den 564 Bytes bringt mich nicht in Bedrängnis. Es ist ein ATMega8515 und das sind gerade mal 6%. Aber ich wollte noch höher hinaus und GPS auswerten, Modem ansteueren und sowas. Ich hoffe, das ich später nicht noch den Kontroller wechseln muss. Aber nicht das hier jetzt jemand sagt: 564 Bytes nur für ein Display- was hast Du da denn gemacht? Ich habe nämlich auch schonmal Asembler für avr geschrieben und meine nicht so große Texte geschrieben zu haben. Jedenfalls malloc lieferte einen Wert zurück. Nur die Zuweisung war im Debugger nicht sichtbar, obwohl die Variable erschien - kann es sein, dass sie wegen fehlender Benutzung rausoptimiert wurde? Und dann noch die Frage: Wenn define unübersichtlich wird, was kann ich statt dessen benutzen, um nicht immer einen Parameter mitübergeben zu müssen, der sich praktisch fast nie ändert? Grüße!
@ Jörg Wunsch: >So'n Quatsch. > >Davon abgesehen, dass man objektorientiert auch in C programmieren >kann, ist C++ sehr wohl (mit Einschränkungen) unterstützt. Guckste hier: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_cplusplus Was nützt Dir da 'nen .cc file, wenn die ganzen Vorteile von C++ nicht nutzbar sind ? Vom Overhead wegen der notwendigen Runtimeverwaltung mal ganz abgesehen. @ Günther Frings: Für Displays gibt es guten Code in der Codesammlung und die Fleury-LCD-Lib ist auch OK ;) Also ein Präprozessorstatement ist schon OK, nur wenn Du sowieso eine LCD Routine für die Ausgabe hast, dann reicht doch dort einmal die Funktion mit der Null hinten reinzuschreiben ? Wäre dann z.B. sowas:
1 | void updatedisplay(uint_8t spalte, char* inhalt) |
2 | {
|
3 | fkt_xy(spalte, 0); |
4 | fkt_schreibwas(inhalt); |
5 | }
|
Oder hab' ich was verpaßt ? Wegen Comilerschaltern einfach mal in der Doku nachsehen und im Fall des Falles kann auch alle Optimierung ausgeschaltet werden.
"Was nützt Dir da 'nen .cc file, wenn die ganzen Vorteile von C++ nicht nutzbar sind ?" Weil noch einiges bleibt. Saubere Modularisierung, Vererbung/Abstrahierung einschliesslich virtual functions, Templates. Beispiele für nützliche Templates: - Generische Pufferklasse, verwendbar für I/O-Pufferung von UART Daten, CAN-Messages, ... Wie üblich kann man das auch in C, aber wenn man C++ schon kennt ist das deutlich eleganter. - Konfigurierbare I/O-Module mit Konfigurationsparametern als Template-Argumente statt #defines. If/else-Konstruktionen sind meist erheblich lesbarer als zigfaches unübersichtliches #ifdef/#else. - Puffergrösse als Template-Argument erlaubt statische Speicherallokation. Als Funktionsparameter eines I/O-Moduls hingegen benötigt das dynamische Allokation, bei der man weit weniger Übersicht über den belegten Speicher hat. Auch das geht anders, aber verletzt dann bisweilen Modularisierungsregeln. Dynamische Speicherverwaltung sollte man sich allerdings bei Controllern abgewöhnen.
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.