Hallo Forum,
ich benutze einen AT91SAM7S256 und möchte Integer- und Fließkommazahlen
ausgeben.
Integerzahlen machen kein Problem, von der Fließkommazahl wird aber nur
der Dezimalpunkt ausgegeben.
Mein Code sieht etwa so aus.
char str[50];
short i=65;
float f;
f=i*1.23;
sprintf (str, "Aktueller ADC-Wert: %d %f\r\n", i, f);
DbguPStr(str);
Ich glaube, es liegt am makefile. Habe in google etwas über mfloat-abi
gelesen, aber nicht verstanden, wo das hin soll.
Weiss da jemand Rat?
Danke
Hannes
Es wird von der float-Zahl wie gesagt nur der Dezimalpunkt angezeigt:
Aktueller ADC-Wert: 65 .
Aktueller ADC-Wert: 65 .
Aktueller ADC-Wert: 65 .
Aktueller ADC-Wert: 65 .
Aktueller ADC-Wert: 65 .
Hannes schrieb:> Mein Code sieht etwa so aus.
etwa ist ganz schlecht. Minimalbeispiel erzeugen und per copy&paste 1:1
hier einfügen. Sonst ist jede Hilfe sinnlos.
Im Map-File nachgesehen, ob sprintf tatsächlich aus der C-Librarxy
kommte (langer Pfad mit libc.a am Ende). Bei einigen Beispielen von
Atmel wird zumindest printf in Projektcode implementiert (stdio.c
w.r.e). Diese Implementierung spart zwar Speicher, beinhaltet zumindest
in den mir bekannten Fassungen aber keine Unterstützung zur Ausgabe von
Fließkommazahlen.
A. K. schrieb:> Implementiert das printf aus diesem libc.a denn Fliesskomma-Ausgabe?> Oder muss man dafür eine separate Lib einbinden, wie bei avr-libc?
Bei der üblicherweise in den freien Paketen enthaltenen Redhat newlib
ist Fließkommaunterstützung in der Standardkonfiguration aktiviert.
Bisher ist mit kein freies Toolchain-Packet begegnet, bei dem dies per
Konfiguration deaktiviert war - was nicht heisst, dass es so etwas nicht
irgendwo geben könnte. Packete von Mentor/Codesourcery und lauchpad/ARM
enthalten die Unterstützung (zumindest kürzlich noch mit einem
thumb2-Target ausprobiert).
Ansatz in der newlib Standardkonfiguration ist etwas anders als bei
avr-libc: standardisierte Funktionsnamen wie z.B printf bieten auch
Formatierung von Fließkomma - bei einmalig recht üppigen 30kByte
Programmspeicherbedarf. Braucht man Fließkomma nicht, verwendet man
Funktionen mit "i" im Namen, z.B. iprintf und spart damit ca. 20KByte
Speicherplatz. Bessere Erklärung in der newlib-Dokumentation und im
Zweifel im newlib-Quellcode. Dazu kommt nach, dass ausreichend Heap- und
Stack verfügbar sein muss.
Ah - falls Crossworks genutzt wird: dazu weiss ich nur (=Crossworks nie
selbst benutzt), dass Rowley eine eigene libc mitliefert. Dazu passt das
oben geschrieben wahrscheinlich nicht.
Zur ursprünglichen Problem: Welches GNU Packet wird genutzt? Falls
selbst gebaut: Konfigurationsoptionen von binutils, compiler und libc?
Im Zweifel hilft evtl. ein Update, es gab wenn richtig erinnert vor
nicht allzu langer Zeit ein Problem beim compiler und/oder libc mit der
Parameterübergabe an stdio-Funktionen bei falschem Stack-Alignment -
Details leider im Moment nicht erinnerlich. Genug Speicher frei (Stack,
Heap)? Richtige libc gelinkt (nicht per ld linken, sondern per gcc, dann
wird alles von alleine gut)? Beim gezeigten "in etwas" Code könnte die
Formatierung evtl. schon zu compilerzeit gemacht werden - ist dem so?
Sollte in intermediate Files und/oder disassembly ersichtlich sein.
Komplettes Miniprogramm zum Nachvollziehen (makefile, Linkerscript,
Quellcode inkl. Startup)?
Hallo Martin,
vielen Dank für die Antwort.
Ich verwende Eclipse mit YAGARTO BU-2.22 und GCC-4.71.
Da ich mit ARMs erst angefangen habe, kann ich Deinen Ausführungen
leider nur teilweise folgen.
Ich habe versucht, die libc direkt als #include aufzunehmen, leider
erfolglos.
Die Startup-Files usw. habe ich von Warwick A. Smith "ARM
Microcontroller Interfacing" übernommen (Elektor-Buch).
Im Anhang hab ich ein Mini-Programm mit allen Dateien gepackt.
Bin für jede Hilfe dankbar.
Hannes
Hardware oder Simulator gerade nicht zur Hand, daher nur ad-hoc: etwas
mehr Platz für Stack vorsehen, ist einen Versuch wert. Dazu in den
Linker-Script die Zahl hinter C_STACK_SIZE ändern von 512 z.B. auf 2048
oder 4096.
Geht irgendwie alles nicht...
Ich hab mir jetzt selbst eine Funktion zur Ausgabe von Fließkommazahlen
geschrieben.
Wenn jemand ein kleines Beispielprogramm hat für printf mit
float-Zahlen, wäre es schön, wenn er es hier kurz posten könnte.
Danke an alle
Hannes
Hallo Hannes,
da wird Dir kaum einer was posten - ich habe lange Zeit versucht, printf
mit float zu nutzen. Ohne Erfolg leider.
Auch intensivste Suche im Internet hat kein einziges funktionsfähiges
Beispiel zutage gefördert.
Ich denke, printf in Verbindung mit float ist in none-eabi-gcc gar nicht
vorgesehen.
Katzenstefan schrieb:> Ich denke, printf in Verbindung mit float ist in none-eabi-gcc gar nicht> vorgesehen.
Das wäre bitter und stimmt so auch nicht. Selbst vor nicht allzu langer
Zeit noch ein kleines Demoprogramm [1] veröffentlicht, mit dem auch
FP-Ausgabe getestet werden kann (double). Weitere nicht-veröffentlichte
Anwendungen für Dritte beinhalten ebenfalls FP-Ausgabe per (s)printf und
werden inzwischen auch meist mit arm-eabi-Toolchain übersetzt.
Allerdings im Moment nichts getestetes für AT91SAM7 zur Hand, was dem OP
unmittelbar helfen würde und derzeit auch kein Werkzeug in Reichweite,
um "schnell mal" zu schauen, ob die alten SAM7-Beispiele problemlos
laufen oder um Hannes' Code auszuprobieren.
[1]
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_cortex.html#stm32f4discovery
(Link mit "GNU specials")
Endlich ein wenig Zeit gefunden: Ein kleines Beispiel für AT91SAM7, mit
Ausgabe per stdio/newlib inkl. Fließkomma findet sich hier:
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/at91sam7_stdio_demo_20120825.zip
Allerdings nur mit dem Simulator von uVision4 getestet. Tests mit der
Hardware stehen noch aus. Verwendete GNU Toolchain ist aus dem Paket von
https://launchpad.net/gcc-arm-embedded (derzeit aktuelle Fassung
2012-Q2, MS-Win Fassung). Das Linkerscirpt düfte einige nicht unbedingt
erforderlichen Einträge enthalten, entspricht aber dem aus der
readme-Datei von GNU t.f.a.e mit nur minimalen Anpassungen für das
Beispiel.
Martin Thomas schrieb:> Verwendete GNU Toolchain ist aus dem Paket von> https://launchpad.net/gcc-arm-embedded
Wenn ich das recht verstehe, basiert das auf dem arm-embedded Branch von
GCC, nicht auf dem Hauptzweig der GCC-Entwicklung?
Zudem ist printf keine Sache des Compilers, sondern der libc — hier wohl
der newlib. Ob es dort Anpassungen gab ist so nicht ersichtlich.
Johann L. schrieb:> Martin Thomas schrieb:>> Verwendete GNU Toolchain ist aus dem Paket von>> https://launchpad.net/gcc-arm-embedded>> Wenn ich das recht verstehe, basiert das auf dem arm-embedded Branch von> GCC, nicht auf dem Hauptzweig der GCC-Entwicklung?
Das weiss ich nicht. Aber auf deren Seite gibt es ein Forum und Fragen
werden dort augenscheinlich schnell beantwortet.
Ich teste derzeit dieses vorcompilierte Paket, da es von ARM selbst
betreut und bereitgestellt wird und darin, im Gegensatz zum bisher
genutzten Paket von Codesourcery/Mentor Codebench, auch die
Laufzeitbibliotheken (libgcc, libc) für die Cortex M4 (z.B. STM32F4)
Hardware-FP-Unit enthalten sind. Musste aber auch bei anderen Paketen
Code anpassen, der mit älteren Fassungen von binutils, gcc und newlib
problemlos zu lauffähigem Machinencode übersetzt wurde. Ursache sind
aber nicht selten allzu simple Linker-Scripte. Ist halt bei ARM und gcc
üblich "eigene" Linkerscript zu verwenden. Die bei der Toolchain
mitgelieferten sind nicht immer einfach über Kommandozeilenparameter an
den Linker auf die Anwendung einzustellen. CS3 wäre eine Alternative
aber das ist Codesourcerys "Baby" und nicht Teil der GNU- bzw.
Redhat-Quellen.
> Zudem ist printf keine Sache des Compilers, sondern der libc — hier wohl> der newlib.
Ja, newlib. Angesichts von buildin-Funktionen und Optimierungen (printf
ohne Parameter -> libc puts), Abhängigkeiten von libgcc und evtl. auch
noch Abhängigkeiten zum Ausnahmebehandlungssystem (jüngst wg. Division
durch 0, vgl. DevkitARM forum und patch-Liste) würde ich aber "Sache des
Compilers"/Sache der libc nicht so klar trennen wollen. Manchmal werden
Fehler in den Einstellungen erst deutlich, wenn man eine Funktion aus
der libc nutzt, muss aber kein Fehler der libc sein.
> Ob es dort Anpassungen gab ist so nicht ersichtlich.
Die stellen auch ein Quellcodepaket bereit. Meinte irgendwo gelesen zu
haben, dass es "stock-newlib" ist.
Scheint leider eine von Codesourcery geerbte Marotte zu sein, einen
friss-oder-stirb Quellcodeklotz vorzuwerfen. In dieser Hinsicht sind
Yagarto und DevkitARM deutlich besser, denn man kann sich die von M.
Fischer bzw. D. Murphy verwendeten script und patches auf sf.net
anschauen.
Alles geschriebene bezieht sich jeweils auf die vorkompilierten Pakete
für Win32-Hosts.
Martin Thomas schrieb:> Johann L. schrieb:>> Martin Thomas schrieb:>>> Verwendete GNU Toolchain ist aus dem Paket von>>> https://launchpad.net/gcc-arm-embedded>>>> Wenn ich das recht verstehe, basiert das auf dem arm-embedded Branch von>> GCC, nicht auf dem Hauptzweig der GCC-Entwicklung?>> Das weiss ich nicht. Aber auf deren Seite gibt es ein Forum und Fragen> werden dort augenscheinlich schnell beantwortet.>> [...] Musste aber auch bei anderen Paketen Code anpassen, der mit> älteren Fassungen von binutils, gcc und newlib problemlos zu> lauffähigem Machinencode übersetzt wurde. Ursache sind aber> nicht selten allzu simple Linker-Scripte. Ist halt bei ARM und gcc> üblich "eigene" Linkerscript zu verwenden. Die bei der Toolchain> mitgelieferten sind nicht immer einfach über Kommandozeilenparameter an> den Linker auf die Anwendung einzustellen.
Es ist doch möglich ein eigenes Skipt anzugeben mit -T, siehe [1].
Für große embedded-Projekte sind hausbackene ld-Skripte wohl nicht
unüblich und eher die Regel als die Ausnahme.
>> Zudem ist printf keine Sache des Compilers, sondern der libc — hier wohl>> der newlib.>> Ja, newlib. Angesichts von buildin-Funktionen und Optimierungen (printf> ohne Parameter -> libc puts), Abhängigkeiten von libgcc und evtl. auch> noch Abhängigkeiten zum Ausnahmebehandlungssystem (jüngst wg. Division> durch 0, vgl. DevkitARM forum und patch-Liste) würde ich aber "Sache des> Compilers"/Sache der libc nicht so klar trennen wollen.
gcc versteht sich als optimierender C-Compiler, und als solcher geht er
davon aus, daß Funktionen, die im C-Standard beschrieben sind, auch
diese Bedeutung haben. Dementsprechend kann er Funktionen durch
effizientere Varianten ersetzen oder Aufrufe komplett weglassen und
inline expandieren wie zum Beispiel aufrufe von memcpy, mamclr, strlen
("123") durch 3 ersetzen, etc..
Falls man das nicht möchte, gibt es -ffreestanding, -fno-builtin,
-fno-builtin-memcpy, etc.
>> Ob es dort [newlib] Anpassungen gab ist so nicht ersichtlich.>> Die stellen auch ein Quellcodepaket bereit. Meinte irgendwo gelesen zu> haben, dass es "stock-newlib" ist.>> Scheint leider eine von Codesourcery geerbte Marotte zu sein, einen> friss-oder-stirb Quellcodeklotz vorzuwerfen. In dieser Hinsicht sind> Yagarto und DevkitARM deutlich besser, denn man kann sich die von M.> Fischer bzw. D. Murphy verwendeten script und patches auf sf.net> anschauen.
Mehr als die Quellen muss ja auch nicht zur Verfügung gestellt werde.
Patches sind natürlich angenehm für Entwickler weil man direktsieht wo
was geändert wurde. Aber es ist auch arbeitsintensiv, so einen Zoo von
Patches zu pflegen, die Patches müssen in der richtigen Reihenfolge
rein, müssen jeweils auf neue Versionen portiert werden, etc.
Was mir an den Patches nicht gefällt (zB Patches von Atmel für avr-gcc
in ihrer Toolchain) ist, daß das Wildwuchs ist. Der Xmega-Support ist
zB zersplittert in dutzende Patches, anstatt ein Xmega-Patch zur
Verfügung zu stellen. Und ChangeLogs gibt's schon gar keine. Gut, ich
benutze diesen Atmel-Fork nicht, aber es erwächst der Eindruck, eine
gscheite Versionsverwaltung würde denen gut tun. Daraus lassen sich
dann ja wieder Konflikt- und Hunk-freie Patches erzeugen.
[1] http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html