sqrt-Funktion auf stm32 arm funktioniert nicht
Ich verwende ein stm32f4-chip (cortex-m4 mit FPU und
sqrt( 9.7 * 9.7 ) gibt 94.17..
verwende ich den arm-none-eabi-gcc-compiler und keine Fehler erhalten Sie auf kompilieren.
mein makefile ist wirklich lange, weil die gleiche Datei verwendet wird, für stm32f4 und sam4-chips. Ich weiß noch nicht mal die relevanten Teile posten. Jede Hilfe ist willkommen.
EDIT : einige flag-config aus makefile
C_FLAGS = -mcpu=cortex-m4 -mthumb
C_FLAGS += -std=gnu89 -g -ggdb3 -fverbose-asm
C_FLAGS += --param max-inline-insns-single=500
C_FLAGS += -fsingle-precision-constant
C_FLAGS += -mfpu=fpv4-sp-d16
C_FLAGS += -mfloat-abi=hard
C_WARNINGS = -Wall
C_WARNINGS += -Wdouble-promotion
Dies ist meine genaue-code:
float x, y, z, mag;
x = ((float) (((int32_t) x_adc) + 0x8000)) * scale - offset;
y = ((float) (((int32_t) y_adc) + 0x8000)) * scale - offset;
z = ((float) (((int32_t) z_adc) + 0x8000)) * scale - offset;
mag = sqrt(x*x + y*y + z*z);
DEBUG("XYZ = %.2f, %.2f, %.2f = %.2f\n", x, y, z, mag );
Den DEBUG-makro, um ein debug-log auf der usb_cdc-Schnittstelle und LCD-Bildschirm. Ich hatte auch schon überschreiben Wdouble-promotion und bin jetzt immer eine doppelte Förderung-Warnung auf die DEBUG-Zeile (welche Anrufe snprintf mit __VA_ARGS__
). Ich nehme an, dies ist nicht relevant.
Ich habe die Optimierung auf 0 (noch immer gleichen Ergebnis mit sqrt), dies ist der .lss:
mag = sqrt(x*x + y*y + z*z);
8019a36: ed97 7a05 vldr s14, [r7, #20]
8019a3a: edd7 7a05 vldr s15, [r7, #20]
8019a3e: ee27 7a27 vmul.f32 s14, s14, s15
8019a42: edd7 6a04 vldr s13, [r7, #16]
8019a46: edd7 7a04 vldr s15, [r7, #16]
8019a4a: ee66 7aa7 vmul.f32 s15, s13, s15
8019a4e: ee37 7a27 vadd.f32 s14, s14, s15
8019a52: edd7 6a03 vldr s13, [r7, #12]
8019a56: edd7 7a03 vldr s15, [r7, #12]
8019a5a: ee66 7aa7 vmul.f32 s15, s13, s15
8019a5e: ee77 7a27 vadd.f32 s15, s14, s15
8019a62: ee17 0a90 vmov r0, s15
8019a66: f7e6 fcf3 bl 8000450 <__aeabi_f2d>
8019a6a: 4602 mov r2, r0
8019a6c: 460b mov r3, r1
8019a6e: ec43 2b10 vmov d0, r2, r3
8019a72: f007 fe9f bl 80217b4 <sqrt>
8019a76: ec53 2b10 vmov r2, r3, d0
8019a7a: 4610 mov r0, r2
8019a7c: 4619 mov r1, r3
8019a7e: f7e6 fffd bl 8000a7c <__aeabi_d2f>
8019a82: 4603 mov r3, r0
8019a84: 60bb str r3, [r7, #8]
if( 1 ) {
DEBUG("XYZ = %.2f, %.2f, %.2f = %.2f\n", x, y, z, mag );
8019a86: 6978 ldr r0, [r7, #20]
8019a88: f7e6 fce2 bl 8000450 <__aeabi_f2d>
8019a8c: 4682 mov sl, r0
8019a8e: 468b mov fp, r1
8019a90: 6938 ldr r0, [r7, #16]
8019a92: f7e6 fcdd bl 8000450 <__aeabi_f2d>
8019a96: 4680 mov r8, r0
8019a98: 4689 mov r9, r1
8019a9a: 68f8 ldr r0, [r7, #12]
8019a9c: f7e6 fcd8 bl 8000450 <__aeabi_f2d>
8019aa0: 4604 mov r4, r0
8019aa2: 460d mov r5, r1
8019aa4: 68b8 ldr r0, [r7, #8]
8019aa6: f7e6 fcd3 bl 8000450 <__aeabi_f2d>
8019aaa: 4602 mov r2, r0
8019aac: 460b mov r3, r1
8019aae: e9cd ab00 strd sl, fp, [sp]
8019ab2: e9cd 8902 strd r8, r9, [sp, #8]
8019ab6: e9cd 4504 strd r4, r5, [sp, #16]
8019aba: e9cd 2306 strd r2, r3, [sp, #24]
8019abe: f243 707c movw r0, #14204 ; 0x377c
8019ac2: f6c0 0002 movt r0, #2050 ; 0x802
8019ac6: f240 4176 movw r1, #1142 ; 0x476
8019aca: f643 0218 movw r2, #14360 ; 0x3818
8019ace: f6c0 0202 movt r2, #2050 ; 0x802
8019ad2: f643 430c movw r3, #15372 ; 0x3c0c
8019ad6: f6c0 0302 movt r3, #2050 ; 0x802
8019ada: f7ed fee9 bl 80078b0 <debug_log>
Dies ist mit -O2
x = ((float) (((int32_t) x_adc) + 0x8000)) * scale - offset;
8010c3e: eeb0 9a48 vmov.f32 s18, s16
8010c42: ee10 9aa9 vnmls.f32 s18, s1, s19
y = ((float) (((int32_t) y_adc) + 0x8000)) * scale - offset;
z = ((float) (((int32_t) z_adc) + 0x8000)) * scale - offset;
8010c46: eef8 1ac1 vcvt.f32.s32 s3, s2
mag = sqrt(x*x + y*y + z*z);
8010c4a: ee28 2aa8 vmul.f32 s4, s17, s17
y_adc = ((int16_t) (buffer[2] & 0xff)) + (((int16_t) (buffer[3] & 0xff))<<8);
z_adc = ((int16_t) (buffer[4] & 0xff)) + (((int16_t) (buffer[5] & 0xff))<<8);
x = ((float) (((int32_t) x_adc) + 0x8000)) * scale - offset;
y = ((float) (((int32_t) y_adc) + 0x8000)) * scale - offset;
z = ((float) (((int32_t) z_adc) + 0x8000)) * scale - offset;
8010c4e: ee11 8aa9 vnmls.f32 s16, s3, s19
mag = sqrt(x*x + y*y + z*z);
8010c52: ee09 2a09 vmla.f32 s4, s18, s18
8010c56: ee08 2a08 vmla.f32 s4, s16, s16
8010c5a: ee12 0a10 vmov r0, s4
8010c5e: f7ef fbf7 bl 8000450 <__aeabi_f2d>
8010c62: ec41 0b10 vmov d0, r0, r1
8010c66: f007 f8f9 bl 8017e5c <sqrt>
if( 1 ) {
DEBUG("XYZ = %.2f, %.2f, %.2f = %.2f\n", x, y, z, mag );
8010c6a: ee19 0a10 vmov r0, s18
z_adc = ((int16_t) (buffer[4] & 0xff)) + (((int16_t) (buffer[5] & 0xff))<<8);
x = ((float) (((int32_t) x_adc) + 0x8000)) * scale - offset;
y = ((float) (((int32_t) y_adc) + 0x8000)) * scale - offset;
z = ((float) (((int32_t) z_adc) + 0x8000)) * scale - offset;
mag = sqrt(x*x + y*y + z*z);
8010c6e: ec55 4b10 vmov r4, r5, d0
if( 1 ) {
DEBUG("XYZ = %.2f, %.2f, %.2f = %.2f\n", x, y, z, mag );
8010c72: f7ef fbed bl 8000450 <__aeabi_f2d>
8010c76: e9cd 0100 strd r0, r1, [sp]
8010c7a: ee18 0a90 vmov r0, s17
8010c7e: f7ef fbe7 bl 8000450 <__aeabi_f2d>
8010c82: e9cd 0102 strd r0, r1, [sp, #8]
8010c86: ee18 0a10 vmov r0, s16
8010c8a: f7ef fbe1 bl 8000450 <__aeabi_f2d>
8010c8e: e9cd 0104 strd r0, r1, [sp, #16]
z_adc = ((int16_t) (buffer[4] & 0xff)) + (((int16_t) (buffer[5] & 0xff))<<8);
x = ((float) (((int32_t) x_adc) + 0x8000)) * scale - offset;
y = ((float) (((int32_t) y_adc) + 0x8000)) * scale - offset;
z = ((float) (((int32_t) z_adc) + 0x8000)) * scale - offset;
mag = sqrt(x*x + y*y + z*z);
8010c92: 4629 mov r1, r5
8010c94: 4620 mov r0, r4
8010c96: f7ef fef1 bl 8000a7c <__aeabi_d2f>
if( 1 ) {
DEBUG("XYZ = %.2f, %.2f, %.2f = %.2f\n", x, y, z, mag );
8010c9a: f7ef fbd9 bl 8000450 <__aeabi_f2d>
8010c9e: 4a0e ldr r2, [pc, #56] ; (8010cd8 <LIS331DLH_ReadAc+0x134>)
8010ca0: 4b0e ldr r3, [pc, #56] ; (8010cdc <LIS331DLH_ReadAc+0x138>)
8010ca2: e9cd 0106 strd r0, r1, [sp, #24]
8010ca6: 4808 ldr r0, [pc, #32] ; (8010cc8 <LIS331DLH_ReadAc+0x124>)
8010ca8: f240 4176 movw r1, #1142 ; 0x476
8010cac: f7f4 fb76 bl 800539c <debug_log>
8010cb0: e78b b.n 8010bca <LIS331DLH_ReadAc+0x26>
#include <math.h>
?Soft-FP, hart FP?
Beachten Sie, dass Ihr code verwendet imlicitly
double
Werte und die Funktion aufrufen. Cortex M4F unterstützt nur float
im hardware - aber sollte unterstützen double
die software.Haben Sie versucht
sqrtf(9.7f * 9.7f)
aka die float-Variante?Wenn das Ihre genauen code (bitte posten sowie Demontage), dann ist es wahrscheinlich die tatsächliche Wurzel erfolgt zur compile-Zeit und die Antwort zurückgegeben wird und/oder was auch immer Sie füttern, um es zu drucken. Was werden Sie füttern, es zu drucken und haben Sie festgelegt, ob das auch behoben Laufzeit oder compile-Zeit. Das problem (wahrscheinlich) nichts zu tun mit sqrt() oder sqrtf()...
InformationsquelleAutor swinman | 2013-12-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
all das hängt davon ab, wie Sie es verwenden. Sie müssen fügen Sie eine Menge mehr Informationen/code. ein einfacher Testfall, der Demontage, einfacher Testfall, wie Sie bei der Bestimmung der Ergebnis, etc.
geschrieben, es gibt keinen Grund für eine Mathematik-Bibliothek ist eine compile-Zeit-Berechnung (auf dem host-Entwicklung/Maschine).
Gebäude für x86 zu zeigen, dass Gebäude für arm nicht gibt, eine andere vor-berechnete Antwort.
wechseln Sie in den single precision
und wir bekommen die single-precision compile-Zeit berechnet Antwort
mit clang/llvm statt gcc:
so dass Sie brauchen, um zu wiederholen, sehen Sie, wenn Sie anrufen, mathematische Funktionen, wenn ja, was sind Sie Fütterung sqrt, haben Sie eigentlich den link in der rechten Zeug, dann würde ich einfach drucken Sie das Ergebnis in hex. dann debug die andere Hälfte, ist es die richtige 9.7 F-Wert und je auf die Druck-Funktion ist es schafft die richtigen ascii?
Wie konvertiere ich (single precision) float-hex-Fragen Sie?
überprüfen, ist der compiler mit r0 auf dem Weg in die und aus:
durch Rücksendung der bits in r0, die als float-bits nicht ändern, die definition der bits wird eine Ausgeburt der compiler oder Programmierer Fantasie sowieso, bits sind nur bits, unterliegt jede Auslegung.
InformationsquelleAutor old_timer