www.mikrocontroller.net

Forum: Compiler & IDEs Probleme bei atan2() mit volatile


Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich nutze die CodeSourcery Toolchain mit dem STM32F103.

Wenn ich folgendes versuche klappt es wunderbar
u16 x[2]; // oder auch mit double
x[0] = 12; 
double z; 
z = 12; 
double  y = atan2 (z, x); 

Wenn ich allerdings bei der Variable volatile verwende funktioniert das 
compilieren nicht.
volatile u16 x[2]; 
x[0] = 12; 
double z; 
z = 12; 
double  y = atan2 (z, x[0]); 

Auch ein kopieren der volatile Variable in eine andere hilft nicht
volatile u16 x[2]; 
x[0] = 12; 
double zz = x[0]; 
double z; 
z = 12; 
double  y = atan2 (z, zz);

Ich bekomme jedesmal den Fehler:
sensor.c:(.text+0x8e): undefined reference to `atan2'
collect2: ld returned 1 exit status
cs-make.exe: *** [main.elf] Error 1

Hat jemand eine Idee was das sein könnte?
Danke!

lg,
Thorsten

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist keine Compilermeldung, sondern eine vom Linker.

Hast du die Mathebibliothek eingebunden?

Autor: Daniel (root) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probier mal von der Konsole erst "gcc -c dein_code.c -Wall" auszuführen.
Wenn dein_code.o herauskommt, dann ist Compiler fertig mit seinem Job.
Bei dir fehlt "-lmath" Option, die man zwar dem Compiler mitgibt, der
aber diese Option an den Linker weitergibt.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel (root) schrieb:

> Bei dir fehlt "-lmath" Option, die man zwar dem Compiler mitgibt, der
> aber diese Option an den Linker weitergibt.

Normalerweise heißt die Option -lm, auch wenn der Header <math.h>
heißt.

Ohne das volatile kann der Compiler erkennen, dass das Argument der
Funktion konstant ist, sodass er die Operation bereits zur Compile-
zeit auflösen kann.  Dadurch kommt es dort nicht zum genannten
Linkerfehler.

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch:
> Ohne das volatile kann der Compiler erkennen,
> dass das Argument der Funktion konstant ist,
> sodass er die Operation bereits zur Compile-
> zeit auflösen kann.

Was meinst du damit? Dass der Compiler das auflöst zu
double y = atan2 (12, 12);
und dann weiß, dass das Ergebnis von atan2 bei zwei gleichen Argumenten 
Pi/4 ist?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ist es. Genauso, wie der 5*4 durch 20 ersetzt, rechnet der auch 
Funktionen aus (wenn möglich), und ersetzt die durch das Ergebnis.

Oliver

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie soll er das machen ohne den Code der Funktion? Oder ist atan2 eine 
builtin Funktion, so wie printf (wo dadurch die Parameter überprüft 
werden können).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zumindest der gcc kennt die Funktionen der Standard-Library und arbeitet 
auch mit diesem Wissen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Oder ist atan2 eine builtin Funktion, so wie printf (wo dadurch die
> Parameter überprüft werden können).

Ja. So gut wie alle Funktionen aus der math.h sind im gcc als 
built-in-Funktionen vorhanden. Hier eine Liste:

http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Other-...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut zu wissen :-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon K. schrieb:
> Wie soll er das machen ohne den Code der Funktion? Oder ist atan2 eine
> builtin Funktion, ...

Ob builtin oder nicht ist egal: wenn die Funktion vom C-Standard
definiert ist, darf der Compiler sie (wenn er im "hosted environment"
arbeitet, was er standardmäßig tut) durch internes Wissen ersetzen.

Damit wird beispielsweise auch strlen("foo!") äquivalent zu
sizeof("foo!") - 1, und beides wiederum äquivalent zur Konstanten 4.

-ffreestanding schaltet diese Optimierungen ab (und ist daher im
Allgemeinen keine wirklich gute Idee, selbst bei einer Controller-
Applikation, die eigentlich tatsächlich "freestanding" ist).

Autor: ratho (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Schon mal vielen Dank für die Info warum es sich so verhält.

Könnte mir noch jemand helfen wo ich -lm in dem makefile einbauen muss?
Ich habe es schon an den unterschiedlichsten Stellen versucht - aber 
immer ohne Erfolg.

Danke!

lg,
Thorsten

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würds in LDFLAGS reingeben

Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ja hier hab ich es zuerst auch versucht - allerdings bekomme ich dann 
immer die Meldung cannot find -lm, oder unrecognized option oder eben 
undefined reference.
Ich vermute mal ich habe es an der falschen Stelle ...

Wo müsste es denn genau hin?
LDFLAGS = -Wl,--gc-sections,-Map=$(MAIN_MAP),-cref -T lanchon-stm32.ld $(INCLUDE_DIRS) $(LIBRARY_DIRS)

Nochmal Danke!

lg,
Thorsten

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ratho schrieb:

> ja hier hab ich es zuerst auch versucht - allerdings bekomme ich dann
> immer die Meldung cannot find -lm

Dann fehlt dir ebendiese Bibliothek ganz offensichtlich in deiner
Toolchain.

Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
aber den Compiler muss die doch auch finden, oder? Sonst würde es ja 
ohne volatile auch nicht gehen.
Oder sehe ich das falsch?

lg,
Thorsten

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ratho schrieb:

> aber den Compiler muss die doch auch finden, oder?

Nein, er kennt sie nur vom Namen her und weiß, was sie macht.  Daher
kann er sie, wenn sie mit konstanten Argumenten aufgerufen wird,
durch die sich ergebende Konstante ersetzen.

Sowie diese Optimierung aber nicht mehr möglich ist, baut er dann
tatsächlich einen Aufruf für die Funktion in den Code ein, wobei er
das Finden der Funktion in einer Bibliothek dem Linker überlässt.

> Sonst würde es ja
> ohne volatile auch nicht gehen.

Doch.

> Oder sehe ich das falsch?

Ja.

Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

OK. Hat jemand die Toolchain von CodeSourcery
http://www.codesourcery.com/sgpp/lite/arm
mit der Umgebung von Lanchon 
http://www.st.com/mcu/forums-cat-6304-23.html
im Einsatz und kann mir helfen wie ich math.h rein bekomme.

Danke!

lg,
Thorsten

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ratho schrieb:
> ... kann mir helfen wie ich math.h rein bekomme.

Die hast du ja (hoffentlich) schon.  Was dir fehlt ist eine libm.a.

Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

libm.a habe ich auch und zwar in folgenden Ordnern:
C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib
C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib\armv6-m
C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib\thumb
C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib\thumb2

aber irgendwie wird die libm.a nicht gefunden ...
Zumindest meint das der Linker wenn ich den Parameter -lm hinzufüge

lg,
Thorsten

Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe gerade noch etwas festgestellt. Wenn ich z.b. den atan(x) nehme und 
nicht den atan2(x,y) dann funktioniert es.

Jetzt wird es für mich noch seltsamer ...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ratho schrieb:

> libm.a habe ich auch und zwar in folgenden Ordnern:
> C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib
> C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib\armv6-m
> C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib\thumb
> C:\Programme\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib\thumb2

Dann starte den GCC-Aufruf fürs Linken (also den, der am Ende ein -lm
stehen hat) mal mit der Option -v.  Dann sagt er dir, in welchen
Verzeichnissen er alles danach sucht.

Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

also bei LIBRARY_PATH= wird eines der Verzeichnise angegeben - wenn auch 
sehr komisch mit /../../ um in den Ordnern zu springen

lg,
Thorsten

Autor: ratho (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube ich habs gefunden :-)
Zusätzlich zur Toolchain verwende ich ja auch die Files von Lanchon. 
Hier gibt es eine Datei lanchon-stm32-rom.ld in der wird in Zeile 22 
anscheinend definiert was alles eingebunden wird
GROUP(libgcc.a libc.a libcs3.a libcs3unhosted.a libcs3-lanchon-stm32.a)

Ergänze ich hier die libm.a funktioniert das kompilieren und linken ohne 
Fehler.

lg,
Thorsten

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.