Moin,
Benutzt ihr sprintf aufm 8bit uC?
Wenn ja, nur für Hobby Projekte?
Wenn nein "nur" wegen dem Speicherverbrauch?
1
#include <avr/io.h>
2
#include <stdio.h>
3
4
int main(void)
5
{
6
char buffer[40];
7
8
while(1)
9
{
10
sprintf(buffer, "value of %f", 12.22);
11
}
12
}
Der Code verbraucht schon aufm Atmega644 mit der printf_flt schon 3254
bytes und sind 5%.
Ich stelle die Frage, weil ich Hobbybastler bin und die Funktion halt
gerne verwende, weil die halt wirklich zur string Formatierung alles
kann.
Aber wie sehen das Leute die wirklich Ahnung davon haben? :D
Möchte mich auch gerne verbessern und wollte auch gerne nach einer
weniger speicher fressenden Funktion fragen die ebenfalls die Funktion
bietet mit *%8.2f*
(Das halt immer 8 Zeichen reserveriert sind, nach der zweiten stelle
nach komma stelle abgeschnitten wird und rechtsbündig ist.)
Dieses %8.2f benutz ich halt im string am häufigsten.
Habt ihr sowelchen Sachen dann selber geschrieben oder gibts da iwo eine
schon fertige abgespeckte lib iwo im www?
(Das automatische Runden der nachkommastelle wäre mir persönlich nicht
wichtig.)
Gruß
Bei den großen Atmega spielen die 3K keine große Rolle.
Für die Kleinen gibt es stark abgemagerte Varianten.
Ja ich verwende es sehr gerne.
Weil ich fast immer UART oder Display habe.
Wenn es nicht geht, auf den Tiny zb., dann lass ich es halt weg.
Ich benutze sprintf praktisch gar nicht (mehr). Stattdessen habe ich mir
ein eigenes printf "gebastelt", bei dem die eigentliche Ausgaberoutine
über einen Funktionspointer realisiert wird. Für das Schreiben in den
Speicher gibt es dann eine eigene Subroutine, die dann z.B. auch auf
Arraygrenzen achten kann.
wedelos schrieb:> Ich benutze immer sprintf von Georges Menie (www.menie.org).
Genauer:
http://www.menie.org/georges/embedded/
Ist hier nur nicht hilfreich - kann kein float.
(Auf der Seite gibt es zwar einen Link auf eine Variante, die float
können soll, der Link aber ist tot und auch via archive.org nicht zu
beleben)
Hey Leute,
Vielen dank für eure Antworten!
Ich denke ich werde mir die Version von Georges Menie mal genauer
angucken!
Meistens kann man mit einen bisschen selber umrechnen ja auch die Floats
umgehen.
Werde mein nächstes Projekt dann mal damit probieren.
Vielen dank nochmal :)
Es gibt 3 gute Gründe, (s(n))printf nicht zu nutzen:
1) Textbastelroutinen werden nicht gebraucht
2) Zu fragil für Deine Programmierdisziplin
3) passt nicht in den Speicher.
Selber frickeln sollte man nur bei Punkt 3), nicht schon im
vorauseilenden Gehorsam.
Achim S. schrieb:> 1) Textbastelroutinen werden nicht gebraucht
Sind aber hilfreich, wenn man Display und/oder UART hat.
> 2) Zu fragil für Deine Programmierdisziplin
Sehe ich anders. Gesunden Menschenverstand in der Benutzung
vorausgesetzt.
> 3) passt nicht in den Speicher.
Hängt von der Nutzung ab.
> Selber frickeln sollte man nur bei Punkt 3), nicht schon im> vorauseilenden Gehorsam.
Wenn in der Entwicklung kein Grund auftaucht, der die Benutzung von
printf in Frage stellt (Speichermangel, garantiert deterministisches
Timing, Zertifizierung), kann man es gern benutzen. Den Flash-Verbrauch
für printf bezahlt man auch nur einmal, dann ist sowieso alles da.
Ich greife erst dann zu Krücken, wenn die Beine nicht richtig
funktionieren. Vorher sehe ich keinen Grund dazu.
Eine der ersten Funktionen, die ich auf einer neuen Plattform zum Laufen
bringe, ist printf. Deren Existenz macht viele Dinge in der Entwicklung
einfacher, auch wenn sie im Endprodukt nicht mehr verwendet wird.
Naja, {s,sn}printf(...) ist schon schön bequem. Es gibt dennoch
Alternativen. Das Konvertieren von Zahlen mit z.B. lota(...) im
Zusammenspiel mit strncpy(...) etc.
Das ist allerdings bei führendenden Nullen im Zahlenbuffer dann ein
wenig Gefummel. Insgesamt jedoch, insbesondere für "preformated" Strings
schnell und einigermaßen schlank. Vermutlich auch etwas kleiner als die
sprintf(...) Derivate, da zumindest bei "preformatted" Ausgaben, viele
der möglichen Optionen in sprintf(...) von vorne herein weg fallen.
Nur elegant sieht das natürlich nicht unbedingt aus, darüber sollte man
sich nicht hinwegtäuschen. sprintf(...) ist auf alle Fälle besser
lesbar, auch wenn der Code dahinter entsprechend 'deutlich gewichtiger'
ist.
Aber kleiner und meist auch schneller geht natürlich immer! Einfach
Zahlen in einen Buffer fester Größe hinein konvertieren, anschliessend
in den "preformatted String" an der vorgesehenen Stelle einfügen und
schon geht die Reise in Richtung UART & Co los.
Der Gewinn besteht dabei selbstverständlich nicht in der expliziten
Konvertierung einer Zahl 'bin >> Ascii', das macht sprintf(...) auch
nicht anders, sondern vielmehr im Weglassen der Notwendigkeit für die
Interpretation der Formatierungsvorschrift im sprintf(...). Das macht
schon ein klein wenig was aus.
Solange es jedoch passt, was Timing und Platz angeht, bleib schon
allein wegen der Lesbarkeit bei den sprintf(...) Derivaten. So sieht man
wenigstens immer gleich was erzielt werden sollte, ohne Ellen lange
Kommentare in den Source schreiben zu müssen.
Mit besten Grüßen aus Berin!
p.s. Für ATMEL gibt es angeblich eine zum Thema passende dtostrf(...) in
der avr-libc. Ich persönlich kenne die jedoch nicht, da ich mehr mit
PIC8/PIC16/PIC32 unterwegs bin.
Quelle:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html
Wolfsente schrieb:> Meistens kann man mit einen bisschen selber umrechnen ja auch die Floats> umgehen.
Dann musst du aber auch aus der avr-libc nicht gleich die teuerste
Version mit Gleitkommaunterstützung benutzen. Die ist ja aus gutem
Grunde nicht der Default, sondern die musst du explizit mit
einbinden.
Wolfsente schrieb:> Benutzt ihr sprintf aufm 8bit uC?
Ja natürlich.
Wolfsente schrieb:> Der Code verbraucht schon aufm Atmega644 mit der printf_flt schon 3254> bytes und sind 5%.
Das wird ja nur einmal benötigt.
Achim S. schrieb:> Vielen Dank, dass Du alle meine Punkte untermauerst. Wortwahl und> Satzbau suggerieren aber das Gegenteil. Vertue ich mich da?
Meiner Meinung nach ist von der Verwendung von printf in wenigen
(relativ klar definierten) Situationen abzuraten, d.h. in der Mehrheit
aller Fälle ist es angezeigt. Und selbst in diesen Situationen sehe ich
printf noch sinnvolles als Debugwerkzeug an.
Deinen Text lese ich umgekehrt, d.h. "per default nicht verwenden", und
dem widerspreche ich.
S. R. schrieb:> Deinen Text lese ich umgekehrt, d.h. "per default nicht verwenden"
Ich denke, dass er keineswegs umgekehrt gemeint war. Er hat drei
Gründe genannt, wann man es nicht verwenden sollte – wenn man
keinen der drei hat, sollte man es also verwenden …
Hm, ich bin noch nie in die Verlegenheit gekommen, sprintf() auf nem AVR
zu brauchen...ich glaub ich mach was falsch.
Aber ich wills mal so sagen: Wenn man den Speicher hat und einem
sprintf() genügt, warum sollte man es dann nicht nutzen?
Von freiem Speicher kann mich mir kein Bier kaufen... Wenn die
Rahmenbedingungen es erlauben ja. Basteln mit %100 und so kann man immer
noch, wenn es sein muss.
M. K. schrieb:> Hm, ich bin noch nie in die Verlegenheit gekommen, sprintf() auf nem AVR> zu brauchen...ich glaub ich mach was falsch.
;-) ... Nö, du machst wohl nix falsch.
Ich selber benutze printf und Konsorten garnicht. Ich brauch's nicht,
denn ich hab Ausgabekonvertierungen zur Genüge in meinem Portfolio.
Aber der TO ist schon lange gegangen.
W.S.
W.S. schrieb:> Ich brauch's nicht, denn ich hab Ausgabekonvertierungen> zur Genüge in meinem Portfolio.
magst Du uns kurz darlegen, was Deine Gründe und was Deine
Konvertierungen sind?
Vielfach ist die Ablehnung von printf/float einfach nur historisch
begründet.
Die AVRs waren ja lange Zeit recht spartanisch ausgerüstet. Z.B. vom
viel eingesetzen AT90S4433 hat es sehr lange gedauert bis zum
ATmega328P.
Und auch am AT89C52 mußte man lange Zeit externen Flash ranpappen, wenn
die 8kB nicht mehr reichten.
Achim S. schrieb:> was Deine Konvertierungen sind?
Sowas braucht W.S. einfach nicht. Echte Männer™ lassen sich die
Bytes binär aufs Terminal ausgeben und wissen danach, welche Zahlen
sich dahinter verstecken. :-)
>Echte Männer™ lassen sich die>Bytes binär aufs Terminal ausgeben
Echte Männer benutzen auch keinen Assembler.
Die tippen die HEX-Datei direkt ein. Inklusive Checksumme.
Ich habe viel Zeit damit vertrödelt, ungenutzten Speicher zu schonen...
[Kennt die Brillen-Werbung noch einer??]
Sohn (~40): >> wenn Du Dein Leben noch einmal leben könntest: würdest Du
alles nochmal genauso machen?
Vater (70+): >> Nicht ganz ... Ich würde von Anfang an printf nutzen
sprintf ist sprichwörtlich eine eierlegende Wollmilchsau!
Mich wundert’s deshalb auch nicht, dass das Teil so ein Trumm ist.
Allerdings gehöre ich auch nicht zur
Clicky-Bunty-schnell-einfüge-Fraktion.
Also sollte die Hauptfrage sein: Brauch ich das alles?
Die meisten werden ein paar, schon sehr oft verwendete, Routinen in
ihrem Funktionspool haben, weil die Problematik bekannt ist. Vor allem
die älteren unter uns, die früher noch die Bytes zählen mussten.
Georges Menie kannte ich noch nicht, wenn ich aber höre, dass der keine
Fließkommazahlen mag, kann ich mir gut vorstellen, wieso die Bibliothek
so schlank ist.
Die etwas schlankeren Alternativen snprintf, atoi und Konsorten sollte
man als bekannt voraussetzen. Selbst atof spart ein paar Bytes.
Jörg W. schrieb:> Echte Männer™
Nutzen Arduino!
Und da sind sprintf() und seine Brüder erreichbar.
Und wenns dann auch noch float Unterstützung braucht, ist das mit einem
kleinen Dreh auch drin. Kostet allerdings über 1k Flash extra.
Und nein!
Wenns das Gedöns fertig gibt, dann schreibe ich es nicht selber, wenn es
nicht unbedingt sein muss.
Sebastian S. schrieb:> Selbst atof spart ein paar Bytes.
Gemessen, oder einfach nur behauptet?
Ich wette, dass 50 % der Leute, die printf & Co. „aus Prinzip, weil
sie zu fett sind“ nicht nehmen, am Ende mehr Platz mit ihren
selbstgestrickten Konvertierungen vertüddeln, als sie sich mit
einem gut optimierten printf() eingehandelt hätten. ;-)
holger schrieb:> Echte Männer benutzen auch keinen Assembler.> Die tippen die HEX-Datei direkt ein. Inklusive Checksumme.
Wer macht das denn nicht?
Achim S. schrieb:> Ich habe viel Zeit damit vertrödelt, ungenutzten Speicher zu schonen...>> [Kennt die Brillen-Werbung noch einer??]>> Sohn (~40): >> wenn Du Dein Leben noch einmal leben könntest: würdest Du> alles nochmal genauso machen?>> Vater (70+): >> Nicht ganz ... Ich würde von Anfang an printf nutzen
Naja, ich finde ihr übertreibt aber auch ein wenig. Man macht sich
einmal ein paar Gedanken bzgl. Float und Strings und das kann man
ständig nutzen. Da sollte ein printf() auch nicht unbedingt das
Hindernis sein.
Karl M. schrieb:> ich nutze:> ELM - Embedded String Functions> http://elm-chan.org/fsw/strf/xprintf.html
sieht für mich aus, wie ein sprintf ohne float. Gibt es weitere
Unterschiede und was sind die Vorteile zu den typischen floatlosen
sprintf-Varianten der Compiler?
Jörg W. schrieb:> Ich wette, dass 50 % der Leute, die printf & Co. „aus Prinzip, weil> sie zu fett sind“ nicht nehmen, am Ende mehr Platz mit ihren> selbstgestrickten Konvertierungen vertüddeln, als sie sich mit> einem gut optimierten printf() eingehandelt hätten. ;-)
Nun, in diesem Punkte stimme ich dir zu.
Die von dir angesprochenen Leute können nicht mal ne primitive
Integer-Ausgabe schreiben, ohne ein mittleres Chaos anzurichten.
Aber eben diese Leute nehmen sowas wie printf nich deshalb, weil es
ihnen zu fett wäre, sondern weil sie es weder besser wissen noch besser
können. Das ist der Punkt. Unfähigkeit eben.
Ein kleinerer Teil könnte es wohl besser, hält sich aber für zu
"großartig", um es auch tatsächlich besser zu machen. Die Denke von
denen lautet "ich scher mich nicht drum, benutze nur Vorgefertigtes,
weil ich mich ja sonst selber in solche Niederungen begeben müßte,
igitt! - und wenn der µC zu klein oder zu lahm dafür ist, dann ist das
ein Problem vom Cheffe und nicht meines - für sowas bin ich mir zu
schade." Ist weit verbreitet. Such mal auf deimen PC in allen
ausführbaren Dateien nach Formatstings "%d" oder "%H". In manchen
Anwendungen findet man einige hundert derartiger Strings.
Nun, ich selber benutze printf und Konsorten eigentlich garnicht. Wozu
auch? Bei Delphi auf dem PC hat man sowas nicht nötig und auf nem µC
löse ich Textausgaben bereits beim Schreiben auf. Siehe conv.c bei der
Lernbetty. Immerhin ist jeder wenigstens einigermaßen sinnvoll
geschriebene Ausgabekonverter besser als jede printf Implementierung,
weil der String-Interpreter nicht erforderlich ist.
W.S.
W.S. schrieb:> Aber eben diese Leute nehmen sowas wie printf nich deshalb, weil es> ihnen zu fett wäre, sondern weil sie es weder besser wissen noch besser> können. Das ist der Punkt. Unfähigkeit eben.
Ich weiß, was gut für mich ist und ich habe die Alternative auch schon
selbst geschrieben und benutzt. Dennoch nutze ich printf, wenn nix
dagegen spricht. Im Gegenteil, ich habe irgendwo eine minimale
Implementation fürs Debugging herumliegen.
> Such mal auf deimen PC in allen ausführbaren Dateien nach Formatstings> "%d" oder "%H". In manchen Anwendungen findet man einige hundert> derartiger Strings.
Wenn du an einer Stelle printf benutzt, dann kannst du es auch gleich
überall benutzen. Zudem ist es die Standard-Schnittstelle von C
(natürlich nicht von Delphi) und für PCs durchaus geeignet.
Mir ist ein einfacher Formatstring (der sogar vom Compiler gegengeprüft
wird, zumindest bei gcc/clang) lieber, als ein Haufen Funktionsaufrufe,
die das zusammenpopeln. Selbst Einwickeln hält den Gestank nicht ab.