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>
Haben Sie compiler-Warnungen aktiviert ? Hast du #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

Schreibe einen Kommentar