Hi, hab hier ne kleine Lib geschrieben die einen Byte-Buffer verwaltet mit bis zu 255 Zeichen. Bei einem Bufferoverflow wird der Buffer auf null gesetzt. Das war für meine Anwendung ausreichend. Es ging darum Nachrichten an den UART mit Hilfe eines absolut minimalen Protokolls zu übertragen aka: START + PARAM1 + PARAM2 + DATA + STOP 1 1 1 ... 1 Vielleicht hilfts, vielleicht hat jmd. Verbesserungen. Danke Gruß das Schnitzel
P.S.: Funktionen sind alle als Inline implementiert. Speicher spielte bei mir keine Rolle.
Schnitzel schrieb: > P.S.: Funktionen sind alle als Inline implementiert. Speicher spielte > bei mir keine Rolle. Warum dann nicht gleich noch der Schritt zu 'inline static'? Dann bist Du das *.c vollends los. Die Funktionen sind ja ganz handlich in der Groesse.
Man kann es natürlich auch weg lassen. Der Compiler entscheidet ja mitlerweile selbstständig ob das inlining Sinn macht.
Marc P. schrieb: > Warum dann nicht gleich noch der Schritt zu 'inline static'? Dann bist > Du das *.c vollends los. Die Funktionen sind ja ganz handlich in der > Groesse Auch eine Möglichkeit
Wenn er allerdings inlined, die Funktion jedoch NICHT static ist, dann behält er immer noch die "aufrufbare" (nicht-inline) Funktion im Speicher vor. Deswegen macht es eigentlich nur Sinn, wenn man tatsächlich davon ausgehen will, dass sowas ge-inlined wird, "static inline" zu verwenden. Dazu zwinge ich den Compiler noch gern zu inlinen, weil er das (wegen Os Optimierung beispielsweise) nicht selbst tun will: __attribute__((always_inline)) für bspw. GCC Das ganze noch in ein Makro #define BYTE_BUFFER_INLINE static inline __attribute__((always_inline)) ;-) Übrigens, wenn sich nicht großartig was geändert hat am GCC (vorausgesetzt, der wird hier benutzt), dann ist Inlining NICHT möglich, wenn der Quellcode NICHT in der Header Datei steht.
:
Bearbeitet durch User
Okay. Vielen Dank. Wieder was gelernt. Werde das so anpassen und alles in eine Headerdatei packen.
Hi Schnitzel, ich finde die Aufteilung in Header- und C-File gut. Das macht es schön übersichtlich. Auch die Kapselung in einem Modul, welches nun universell eingesetzt werden kann, ist topp. Was mich auf den ersten Blick stört ist die Verwendung von malloc() und free(). Ich habe mal gelernt, das malloc() und free() in (kleinen) Embedded Systems nix verloren haben. Der Grund liegt einmal - in Programmabläufen, welche zwar ein malloc() ausführen, den allokierten Speicher aber nicht mehr freigeben (Anwenderfehler, Sonderbehandlung, ...) - und zweitens in der möglichen Fragmentierung des Speichers über die Laufzeit Selbst getestet habe ich es aber nie. Kann jmd. die Aussage bestätigen / widerlegen? Gruß nux
nux schrieb: > Was mich auf den ersten Blick stört ist die Verwendung von malloc() und > free(). Ich habe mal gelernt, das malloc() und free() in (kleinen) > Embedded Systems nix verloren haben. Komme nicht aus dem Embedded Bereich, hab daher keine Erfahrung in der Hinsicht. Das grundlegende Problem von malloc() etc. pp. sind ja die Gefahren von möglichen Speicherlecks. Das ist zum. das was ich so mitbekommen habe. Man kann natürlich die Funktion buffer_get und buffer_free entfernen bzw. belassen und eine buffer_init Funktion hinzufügen die den Puffer initialisiert. Das war auch der Grund weshalb ich auf malloc und free zurückgegriffen hatte, um klar zu machen das der Puffer initialisiert werden muss in der buffer_get Funktion. BUFFER_INLINE void_buffer_init(buffer_t *buffer) { buffer->size = 0; buffer->current = buffer->data; } Das hätte es mit Sicherheit auch getan. Vielleicht hat ja jmd. noch eine andere Idee.
Angepasst - malloc und free entfernt - buffer_init() hinzugefügt - Fehler in buffer_truncate behoben
Oh Mannomann, jetzt werde ich kleinlich - verzeiht mir das... Also in der struct gef"allt mir dein alignment nicht. Erstes Feld uint8, zweites Feld ein pointer (>1 byte! auf 'vielen' Architekturen). Das packt kein Compiler vern"unftig :( Geschickter w"are der Pointer als erstes.
Marc P. schrieb: > Oh Mannomann, jetzt werde ich kleinlich - verzeiht mir das... > > Also in der struct gef"allt mir dein alignment nicht. Erstes Feld uint8, > zweites Feld ein pointer (>1 byte! auf 'vielen' Architekturen). Seit wann ist sowas ein Problem? > Das packt kein Compiler vern"unftig :( Wieso das denn nicht? Ist doch völlig legitimes C. Dann ist der Compiler kaputt, wenn er das nicht automatisch alignen kann. > Geschickter w"are der Pointer als erstes. Und wieso? PS: Jetzt werde ich kleinlich: Diese Missbrauchten Gänsefüßchen sind sehr schlecht zu lesen
Simon K. schrieb: >> Also in der struct gef"allt mir dein alignment nicht. Erstes Feld uint8, >> zweites Feld ein pointer (>1 byte! auf 'vielen' Architekturen). > Seit wann ist sowas ein Problem? Seit es Architekturen mit Alignment-Requirements gibt. Also schon lange. >> Das packt kein Compiler vern"unftig :( > Wieso das denn nicht? Ist doch völlig legitimes C. Dann ist der Compiler > kaputt, wenn er das nicht automatisch alignen kann. Compiler können. Und verschwenden dabei unnötig ein paar bytes RAM. >> Geschickter w"are der Pointer als erstes. > Und wieso? Damit man sich die Padding-Bytes spart.
Hi, Habe das o.g korrigiert und eine Möglichkeit hinzugefügt mehr als 255 Zeichen zu puffern, wenn dies denn nötig ist. Man kann den Spass ja auch auf größeren Systemen verwenden. korrigiert. - Pointer an den Anfang der Struktur verschoben - Möglichkeit hinzugefügt mehr als 255 zeichen zu puffern - Inline definition angepasst für externe configuration
Dr. Sommer schrieb: > Simon K. schrieb: >>> Also in der struct gef"allt mir dein alignment nicht. Erstes Feld uint8, >>> zweites Feld ein pointer (>1 byte! auf 'vielen' Architekturen). >> Seit wann ist sowas ein Problem? > Seit es Architekturen mit Alignment-Requirements gibt. Also schon lange. Bitte? Der Compiler "packt es nicht vernünftig" (Zitat), wenn Padding bytes notwendig sind. Ist klar. Das es in bestimmten Fällen Speicher verschwenden kann ist klar. >>> Das packt kein Compiler vern"unftig :( >> Wieso das denn nicht? Ist doch völlig legitimes C. Dann ist der Compiler >> kaputt, wenn er das nicht automatisch alignen kann. > Compiler können. Und verschwenden dabei unnötig ein paar bytes RAM. Ja also. >>> Geschickter w"are der Pointer als erstes. >> Und wieso? > Damit man sich die Padding-Bytes spart. Also geht es nur darum das eine oder andere Byte zu sparen. Das ist kein Grund einen Post mit "Mannomann" nach dem Motto: Was ist das denn für ein Müll, mit so vielen offensichtlichen Fehlern...
Simon K. schrieb: > Grund einen Post mit "Mannomann" nach dem Motto: Was ist das denn für > ein Müll, mit so vielen offensichtlichen Fehlern... Okay ganz langsam. Ich war nicht deutlich genug. Das Mannomann bezog sich auf mich selbst, da ich gesehen hab, dass der Autor auf Vorschlaege eingeht und ich dann auch noch mit dem alignment komme. packt war eine schlechte Wahl, wenn ich damit das englische 'pack' meine. Sorry. Ich wollte nicht sagen, dass der Compiler davon abstuerzt sondern dass er viel Luft ins struct 'packt'.
:
Bearbeitet durch User
Marc P. schrieb: > Simon K. schrieb: >> Grund einen Post mit "Mannomann" nach dem Motto: Was ist das denn für >> ein Müll, mit so vielen offensichtlichen Fehlern... > > Okay ganz langsam. Ich war nicht deutlich genug. Das Mannomann bezog > sich auf mich selbst, da ich gesehen hab, dass der Autor auf Vorschlaege > eingeht und ich dann auch noch mit dem alignment komme. > > packt war eine schlechte Wahl, wenn ich damit das englische 'pack' > meine. > Sorry. Ich wollte nicht sagen, dass der Compiler davon abstuerzt sondern > dass er viel Luft ins struct 'packt'. Ah. Entschuldige bitte für das monströse Missverständnis :-)
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.