Forum: Compiler & IDEs Fliesskomma ARM7 GCC


von Hannes (Gast)


Lesenswert?

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

von Ingo (Gast)


Lesenswert?

Was passiert denn genau?



Ingo

von Hannes (Gast)


Lesenswert?

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   .

von trollalala (Gast)


Lesenswert?

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.

von Hannes (Gast)


Lesenswert?

Na gut, wenn Du meinst:

int main(void)
{
    char str[50];
    short  i=65;
    float f;

  *AT91C_PMC_PCER = 1<<AT91C_ID_PIOA; //Peripheral Clock Enable Register

  *AT91C_PIOA_PDR  = AT91C_PA12_MISO|AT91C_PA13_MOSI|
              AT91C_PA14_SPCK|AT91C_PA11_NPCS0|AT91C_PA31_NPCS1;     // 
enable pins as PIO


    SPI_Configure(AT91C_BASE_SPI, AT91C_ID_SPI, AT91C_SPI_MSTR | 
AT91C_SPI_PS );//| AT91C_SPI_DLYBCS);
    SPI_Enable(AT91C_BASE_SPI);



    DbguInit(Usart_115200);
    ADS_Init();

    for(;;)
    {
      i=65;//ADS_Read();
      f=i*1.23;

      sprintf (str, "Aktueller ADC-Wert: %d %f\r\n", i, f);
         DbguPStr(str);

    }
}

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

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.

von Hannes (Gast)


Lesenswert?

Hallo Martin,

habe nachgesehen. Überall libc.a

von (prx) A. K. (prx)


Lesenswert?

Implementiert das printf aus diesem libc.a denn Fliesskomma-Ausgabe? 
Oder muss man dafür eine separate Lib einbinden, wie bei avr-libc?

von Hannes (Gast)


Lesenswert?

Bei den AVR musst Du die printf-options (floating point options) im 
makefile einstellen.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

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)?

von Hannes (Gast)


Lesenswert?

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

von Hannes (Gast)


Lesenswert?

Hier nochmal die Dateien, hatte was vergessen

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Hannes schrieb:
> Hier nochmal die Dateien, hatte was vergessen

Bitte in ein zip-Archiv zusammenpacken und an einen Beitrag anhängen.

von Hannes (Gast)


Angehängte Dateien:

Lesenswert?

Guten Abend Martin,

anbei das zip-file.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

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.

von Hannes (Gast)


Lesenswert?

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

von Katzenstefan (Gast)


Lesenswert?

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.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

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")

von Katzenstefan (Gast)


Lesenswert?

was für alte SAM7-Beispiele?

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?


von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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

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
Noch kein Account? Hier anmelden.