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


von ratho (Gast)


Lesenswert?

Hi,
ich nutze die CodeSourcery Toolchain mit dem STM32F103.

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

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

Auch ein kopieren der volatile Variable in eine andere hilft nicht
1
volatile u16 x[2]; 
2
x[0] = 12; 
3
double zz = x[0]; 
4
double z; 
5
z = 12; 
6
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

von Karl H. (kbuchegg)


Lesenswert?

Das ist keine Compilermeldung, sondern eine vom Linker.

Hast du die Mathebibliothek eingebunden?

von Daniel (root) (Gast)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von tuppes (Gast)


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
1
double y = atan2 (12, 12);
und dann weiß, dass das Ergebnis von atan2 bei zwei gleichen Argumenten 
Pi/4 ist?

von Oliver (Gast)


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

von Simon K. (simon) Benutzerseite


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

von Karl H. (kbuchegg)


Lesenswert?

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

von Rolf Magnus (Gast)


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-Builtins.html#Other-Builtins

von Simon K. (simon) Benutzerseite


Lesenswert?

gut zu wissen :-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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

von ratho (Gast)


Angehängte Dateien:

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

von Karl H. (kbuchegg)


Lesenswert?

Ich würds in LDFLAGS reingeben

von ratho (Gast)


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?
1
LDFLAGS = -Wl,--gc-sections,-Map=$(MAIN_MAP),-cref -T lanchon-stm32.ld $(INCLUDE_DIRS) $(LIBRARY_DIRS)

Nochmal Danke!

lg,
Thorsten

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von ratho (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von ratho (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von ratho (Gast)


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

von ratho (Gast)


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 ...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von ratho (Gast)


Lesenswert?

Hi,

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

lg,
Thorsten

von ratho (Gast)


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
1
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

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.