Probleme bei atan2() mit volatile

Gast #1501465
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
Gast #1501497
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.
Moderator Persönliche Seite #1501516
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.
Gast #1501758
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?
Moderator Persönliche Seite #1501891
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).
Gast #1501992
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
Angehängte Dateien:
Gast #1502024
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
Moderator Persönliche Seite #1502558
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.
Gast #1502907
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
Moderator Persönliche Seite #1502964
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.
Gast #1504406
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren