logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Kompilacja kodu z FPU na Cortex-M4 w GCC – ustawienia Makefile i toolchain Linaro

Freddie Chopin 15 Mar 2012 23:06 5375 24
REKLAMA
  • #1 10683077
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Próbuję ogarnąć używanie FPU z rdzenia Cortex-M4 w GCC.

    1. Mam toolchain linaro, multilib:
    >arm-none-eabi-gcc -print-multi-lib
    .;
    thumb;@mthumb
    fpu;@mfloat-abi=hard
    armv6-m;@mthumb@march=armv6s-m
    armv7-m;@mthumb@march=armv7-m
    armv7e-m;@mthumb@march=armv7e-m
    armv7-r/thumb;@mthumb@march=armv7-r
    armv7-r/thumb/fpu;@mthumb@mfloat-abi=hard@march=armv7-r@mfpu=vfpv3-d16
    armv7e-m/fpu;@mthumb@mfloat-abi=hard@march=armv7e-m@mfpu=fpv4-sp-d16
    armv7-r/thumb/softfp;@mthumb@mfloat-abi=softfp@march=armv7-r@mfpu=vfpv3-d16
    armv7e-m/softfp;@mthumb@mfloat-abi=softfp@march=armv7e-m@mfpu=fpv4-sp-d16


    2. W Makefile dodaję:
    -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
    do kompilatora i linkera

    3. W kodzie włączanie koprocesora
    Kod: text
    Zaloguj się, aby zobaczyć kod


    4. Jest jakiś prosty kod:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    No i teraz na czym polega problem:
    a. Przy optymalizacji wyłączonej kod jest umiarkowanie dziwny, ale ogólnie obleci:
    	volatile float i = 4.123456;
     8000254:	4b1b      	ldr	r3, [pc, #108]	; (80002c4 <main+0x84>)
     8000256:	607b      	str	r3, [r7, #4]
    
    [inContentAd]
    
    	i = sqrtf(i*i*i);
     8000258:	ed97 7a01 	vldr	s14, [r7, #4]
     800025c:	edd7 7a01 	vldr	s15, [r7, #4]
     8000260:	ee27 7a27 	vmul.f32	s14, s14, s15
     8000264:	edd7 7a01 	vldr	s15, [r7, #4]
     8000268:	ee27 7a27 	vmul.f32	s14, s14, s15
     800026c:	eef1 7ac7 	vsqrt.f32	s15, s14
     8000270:	eef4 7a67 	vcmp.f32	s15, s15
     8000274:	eef1 fa10 	vmrs	APSR_nzcv, fpscr
     8000278:	d005      	beq.n	8000286 <main+0x46>
     800027a:	eeb0 0a47 	vmov.f32	s0, s14
     800027e:	f000 f831 	bl	80002e4 <sqrtf>
     8000282:	eef0 7a40 	vmov.f32	s15, s0
     8000286:	ee17 3a90 	vmov	r3, s15
     800028a:	607b      	str	r3, [r7, #4]


    Jak widać wykorzystana jest instrukcja vsqrt. Głupie jest to warunkowe wywołanie normalnego sqrtf, które w sumie i tak nigdy nie jest wywoływane, tylko gdy jakieś argumenty są niezbyt poprawne - jeśli dobrze rozumiem to w przypadku podania zera.

    b. Przy włączeniu jakiejkolwiek optymalizacji zaczyna się robić dziwnie:
    np. -O1
    	volatile float i = 4.123456;
     800022a:	f24f 335a 	movw	r3, #62298	; 0xf35a
     800022e:	f2c4 0383 	movt	r3, #16515	; 0x4083
     8000232:	9301      	str	r3, [sp, #4]
    
    	i = sqrtf(i*i*i);
     8000234:	ed9d 0a01 	vldr	s0, [sp, #4]
     8000238:	ed9d 7a01 	vldr	s14, [sp, #4]
     800023c:	eddd 7a01 	vldr	s15, [sp, #4]
     8000240:	ee20 0a07 	vmul.f32	s0, s0, s14
     8000244:	ee20 0a27 	vmul.f32	s0, s0, s15
     8000248:	f000 f828 	bl	800029c <sqrtf>
     800024c:	ed8d 0a01 	vstr	s0, [sp, #4]

    (dla innych optymalizacji jest podobnie - wywoływane jest po prostu sqrtf)

    Problem zaczyna się przy analizie funkcji sqrtf, która niby jest hardfloat, ale po kilku instrukcjach wywołuje __ieee754_sqrtf, które już z hardfloat nie ma prawie nic wspólnego poza jednym mnożeniem i jednym dzieleniem (pomijam przpisanie z rejestrów float do zwykłych).

    Czy ktoś potrafi to wytłumaczyć i powiedzieć co można z tym zrobić? Czy jest to jakaś dziwaczna konfiguracja multilib, która jest bezsensowna?

    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o)
                                  out/main.o (sqrtf)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-ef_sqrt.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (__ieee754_sqrtf)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-s_lib_ver.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (__fdlib_version)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-s_matherr.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (matherr)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-sf_fpclassify.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (__fpclassifyf)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/armv7e-m/fpu\libgcc.a(_arm_addsubdf3.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (__aeabi_f2d)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/armv7e-m/fpu\libgcc.a(_arm_muldivdf3.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (__aeabi_ddiv)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/armv7e-m/fpu\libgcc.a(_arm_truncdfsf2.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (__aeabi_d2f)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-errno.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libm.a(lib_a-wf_sqrt.o) (__errno)
    c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-impure.o)
                                  c:/program files/linaro/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-errno.o) (_impure_ptr)


    4\/3!!
  • REKLAMA
  • #2 10683442
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    A zobacz jak będzie wyglądał assembler z flagą -fsingle-precision-constant
  • #3 10683667
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Bez żadnych zmian - nawet pół bitu się nie zmienia w kodzie wynikowym.

    Nie kumam tego totalnie... Konfiguracja multiliba wydaje mi się dobra, biblioteki są wybrane dobre, ale tak jakby te biblioteki były totalnie do niczego...

    4\/3!!
  • REKLAMA
  • #4 10683779
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    A mógłbyś wrzucić cały projekt ? Czy z jakichś względów niebardzo?
  • #5 10683987
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Jedyny "wzgląd", który może w tym przeszkadzać to fakt, że jest to generalnie sieczka na tym etapie <:

    No ale niech będzie -> http://dl.dropbox.com/u/1426569/stm32f4_blink_led.zip

    Przypuszczam że problemem mogą być agresywne optymizacje... Kod w postaci powyżej generuje bzdurny listing (nie używa instrkcji vsqrt.f32), natomiast jak tylko wywalę tą pętlę opóźniającą ze środka while(1) to nagle kod jest sensowny (poza tym wywołaniem sqrtf() jeśli wynik jest 0). Jeśli np dam obliczanie sqrtf() w pętli, to wynik też jest sensowny (z uwagą j.w.)... Dziwne trochę...

    Może po prostu funkcje biblioteczne nie dają rady w przypadku FPU i trzeba korzystać z funkcji z nagłówka arm_math.h?

    4\/3!!
  • Pomocny post
    #6 10684262
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    No to pozostało Ci jeszcze: -ffast-math.

    Opis brzmi groźnie:
    Cytat:
    This option is not turned on by any -O option besides -Ofast since it can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications.


    ale generuje taki kod bez optymalizacji:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    taki z 0s:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    i taki z O3:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Więc wygląda to w miarę sensownie. Linker nie dorzuca też floating pointa więc całość zamiast 5 kb zajmuje 600b
  • #8 10684337
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    w lss pierwiastek był pocięty na kawałki, post edytowałem :) Najpierw rozpoczynał mnożenie, w między czasie rozpoczynał sobie whila i dokończył pierwiastkowanie. W większości przypadków kod wygląda więc tak samo.
  • REKLAMA
  • Pomocny post
    #10 10684583
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    Nie widzę żadnych przeciwwskazań. Ta flaga optymalizatora nie powinna sprawiać jakichś większych problemów. Możesz sprawdzić, czy sinus cosinus i inne bajery generowane softwarowo będą wyglądały poprawnie. Jeżeli tak, to tędy droga.

    Btw flagę -fsingle-precision-constant i tak warto zostawić.
  • REKLAMA
  • #12 10687617
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    Czekam na wyniki. Najwyżej będziemy szukać dalej :)
    Niebawem powinna być przesyłka z CM4 więc będę mógł też sam sprawdzić.
  • #13 10695063
    Konto nie istnieje
    Konto nie istnieje  
  • #14 10695234
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    albertb napisał:

    - musimy w programie zrezygnować z użycia ERRNO do kontroli operacji zmiennoprzecinkowych


    Ale przecież opcja -fno-math-errno sprawia, że flaga ERRNO nie jest ustawiana dla tych funkcji matematycznych, które są wywoływane jedną instrukcją, tak jak na przykład pierwiastek, mnożenie dzielenie etc. Dla funkcji które wymagają litanii assemblerowej ERRNO i tak jest ustawiane. Miało by to znaczenie, jeśli funkcje w libm wykorzystywały by mnożenia sprzętowe, ale tak nie jest.

    unsafe-math-optimalizations - dla hw floating point nie ma to znaczenia, dla soft trzeba by sprawdzić jak napisałem wyżej czy się nic nie sypie. Jest to tylko sprawdzanie argumentów funkcji, można się martwić o to samemu.

    -ffinite-math-only - tym się nie ma co martwić bo ta flaga i tak jest ustawiana domyślnie.

    -fno-rounding-math - j/w

    -fno-signaling-nans - j/w

    -fno-signaling-nans - to ma znaczenie przy mnożeniu/dzieleniu liczb zespolonych, ale i tak mamy tylko finite-math więc trochę nie kapuje co ta flaga jeszcze dodatkowo robi :)


    Dla bezpieczeństwa można ustawić więc samo -fno-math-errno, ale nie sądzę, żeby -ffast-math cokolwiek mógł bardzo popsuć :)

    --
    Ciekawe co STM powie na pierwiastek z liczbą ujemną ?
    No i czy przypadkiem errno nie ma znaczenia tylko na OS ?
  • #15 10695307
    Konto nie istnieje
    Konto nie istnieje  
  • #16 10695356
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    albercie drogi, czy nawet i najdroższy, wszystko wziąłem z manuala gcc :) linka chyba nie muszę dawać bo sam go wkleiłeś. No dobra ale po kolei:

    albertb napisał:

    Być może. Ekspertem, jak pisałem nie jestem. Ale skąd się ta litania bierze? To przecież sekwencja pojedynczych instrukcji. Bez wglądu w źródełka libm (czyli tej litanii) lub potwierdzenia wiarygodnym linkiem bałbym się Twoje stwierdzenie stosować.


    ale tu chodzi o całą funkcję matematyczną. VSQRT zrobi Ci sprzętowy pierwiastek, ale nijak nie zrobisz już jedną instrukcją sinusa. Jest to napisane w manualu do gcc.

    albertb napisał:

    Głównie sprawdzanie argumentów. Ale nie jestem takim optymistą jak Ty, że to zadanie trywialne. Przy bibliotekach wykraczamy poza argumenty.


    Nawet jak wykroczymy z kontrolą błędów to i tak wszystko szlag trafi :)

    albertb napisał:

    gaskoin napisał:

    -ffinite-math-only - tym się nie ma co martwić bo ta flaga i tak jest ustawiana domyślnie.

    ??? - chyba źle doczytałeś.


    Tak, jest na odwrót :P zawsze coś powalę, ale raczej i tak nikt nie używa nieskończoności w uC.

    albertb napisał:

    gaskoin napisał:

    -fno-signaling-nans - to ma znaczenie przy mnożeniu/dzieleniu liczb zespolonych

    Skąd żeś coś takiego wziął?
    Ale fakt, tu jest standardowe ustawienie.


    Z manuala do gcc. Tak to jest jak się edytuje swój post w locie :) ta flaga służy do nie-wskazywania NaN (not a number) przy jakichś błędach. Jest standardowe ustawienie, bo -fsignaling-nans jest narazie eksperymentalne (też o tym pisze w manualu). To, do czego się odnosiłem to flaga -fcx-limited-range, którą zjadło za to w opisie posta.

    albertb napisał:

    gaskoin napisał:

    Ciekawe co STM powie na pierwiastek z liczbą ujemną ?
    No i czy przypadkiem errno nie ma znaczenia tylko na OS ?

    Z -ffast-math czy bez ?
    Ma takie znaczenie jakie jest zdefiniowane w używanym libm.


    Z i bez.

    albertb napisał:

    OS nie ma tu nic do rzeczy.


    A użyłeś kiedykolwiek flagi ERRNO ? :)
  • #17 10695435
    Konto nie istnieje
    Konto nie istnieje  
  • #18 10695570
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    albertb napisał:

    Fajnie że mnie tak lubisz ;-)
    Tylko naucz się jeszcze odróżniać kompilator od jego bibliotek.

    Wtedy będę mógł bardziej? Sprawiasz wrażenie, jakbyś bardzo chciał, aby nie było to rozwiązaniem :)

    A tak poważnie, to dla Twojej informacji - to ta opcja akurat ma związek z wywoływaniem właśnie funkcji bibliotecznych a sinus jest właśnie jedną z takich funkcji.

    albertb napisał:
    Funkcja sinus nie jest częścią składową kompilatora. Jest częścią standardowej biblioteki matematycznej. A tą możesz sobie zmienić pracując na tym samym kompilatorze.

    I w związku z tym do takowej nie możesz odnosić manuala gcc.


    Tylko szkoda, że manual gcc w przypadku tej flagi mówi wprost o bibliotece matematycznej.

    Cytat:
    Do not set ERRNO after calling math functions that are executed with a single instruction, e.g., sqrt. A program that relies on IEEE exceptions for math error handling may want to use this flag for speed while maintaining IEEE arithmetic compatibility.


    Ma to sens, ponieważ o ile funkcja ustawi Ci flagę, to sprzęt nie ma fizycznie możliwości aby to zrobić.

    Nie chcę się tu kłócić w nieskończoność, wolałbym to sprawdzić, co będę miał fizycznie możliwość zrobić w tym tygodniu. Chyba, że Freddie już to zrobił.
    Btw nie rozumiem trochę ataku z Twojej strony. Najpierw łagodnie, że nie jesteś ekspertam etc, a tu nagle walisz, że nie znam podstawowych różnic, że wszystko źle nie dobrze itd.
  • #19 10695655
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Nie bardzo mam pomysł jak to sprawdzić [; Podać do funkcji jedno-rozkazowych jakieś jednoznacznie błędne dane (pierwiastek z liczby ujemnej) i zobaczyć co się stanie?

    4\/3!!
  • #20 10695766
    Konto nie istnieje
    Konto nie istnieje  
  • #21 10695836
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    To niestety też tylko interpretacje.

    Mogę się z Tobą zgodzić co do tych wszystkich kontroli argumentów, zakresów itd. Ale używając sprzętu, nie możesz w żaden sposób takiej kontroli zapewnić. To może być albo zależne od samego liba, albo sam sobie musisz zapewnić taką kontrolę. Kontrola taka jest pewnie zapewniana przez wywołanie softwarowej obsługi i olanie FPU, czyli tak jak mówisz - lib jeszcze być może kuleje. Ale to tylko domysły wzięte z opisu opcji -fno-math-errno która jak jest napisane w manualu nie ustawia flagi po jednorozkazowych funkcjach.

    Co ciekawe dla instrukcji VSQRT w manualu CM4 jest "no restrictions" więc jestem ciekawy co on wypluje dla np -5.1234. Wartość bezwzględną, Hard fault, Wybuchnie, spłonie ? Kto odważny spróbuje? Ponoć zero zwróci taki pierwiastek.
  • #22 10697815
    Konto nie istnieje
    Konto nie istnieje  
  • #23 10698008
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    No to zawsze jest nagłówek arm_math.h, a w nim np ten inkryminowany pierwiastek:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Wg tego - http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439c/Chdbebfc.html - nie jest też tak źle. Przypuszczam że można sobie aktywować przerwanie od błędu matematycznego i po problemie z flagą errno. W ARMv7-M ARM znalazłem opis bitów statusowych, które spokojnie zastąpią flagę errno, szukam jeszcze czegoś o przerwaniu, ale pewnie to też da się odpalić.

    4\/3!!
  • #24 10698098
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    W PM0214 są opisane jakieś rejestry statusowe dla FPU i jakieś przykładowe handlingi. Też mi się wierzyć nie chce, żeby zostawili "gołe" działania i hulaj dusza. W takim razie może i ja poślę rakietę w niebo i przestanę rysować w paincie ? :P
  • #25 10698143
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    No są takie wyjątki dostępne w rejestrze FPSCR

    Cytat:
    Floating-point exceptions
    The FP extension records the following floating-point exceptions in the FPSCR cumulative bits, see
    Floating-point Status and Control Register, FPSCR on page A2-56:
    IOC Invalid Operation. The bit is set to 1 if the result of an operation has no mathematical value
    or cannot be represented. Cases include infinity * 0, +infinity + (–infinity), for example.
    These tests are made after flush-to-zero processing. For example, if flush-to-zero mode is
    selected, multiplying a denormalized number and an infinity is treated as 0 * infinity and
    causes an Invalid Operation floating-point exception.
    IOC is also set on any floating-point operation with one or more signaling NaNs as
    operands, except for negation and absolute value, as described in FP negation and absolute
    value on page A2-68.
    DZC Division by Zero. The bit is set to 1 if a divide operation has a zero divisor and a dividend
    that is not zero, an infinity or a NaN. These tests are made after flush-to-zero processing, so
    if flush-to-zero processing is selected, a denormalized dividend is treated as zero and
    prevents Division by Zero from occurring, and a denormalized divisor is treated as zero and
    causes Division by Zero to occur if the dividend is a normalized number.
    For the reciprocal and reciprocal square root estimate functions the dividend is assumed to
    be +1.0. This means that a zero or denormalized operand to these functions sets the DZC bit.
    OFC Overflow. The bit is set to 1 if the absolute value of the result of an operation, produced after
    rounding, is greater than the maximum positive normalized number for the destination
    precision.
    UFC Underflow. The bit is set to 1 if the absolute value of the result of an operation, produced
    before rounding, is less than the minimum positive normalized number for the destination
    precision, and the rounded result is inexact.
    The criteria for the Underflow exception to occur are different in Flush-to-zero mode. For
    details, see Flush-to-zero on page A2-62.
    IXC Inexact. The bit is set to 1 if the result of an operation is not equivalent to the value that
    would be produced if the operation were performed with unbounded precision and exponent
    range.
    The criteria for the Inexact exception to occur are different in Flush-to-zero mode. For
    details, see Flush-to-zero on page A2-62.
    IDC Input Denormal. The bit is set to 1 if a denormalized input operand is replaced in the
    computation by a zero, as described in Flush-to-zero on page A2-62.


    Nie mogę jednak nigdzie znaleźć informacji od czego jest to ostatnie przerwanie w STM32F4 - FPU global interrupt. Czy wystarczy je tylko włączyć w NVIC i już powyższe wyjątki generują przerwanie, czy coś innego?

    EDIT:
    w tym manualu który przywołałeś powyżej jest co trzeba:
    Cytat:
    4.6.7 Enabling and clearing FPU exception interruption
    Five exception flags (IDC, UFC, OFC, DZC, IOC) are ORed and connected to the interrupt
    controller.
    There is no individual mask and the enable/disable of the FPU interrupt is done at interrupt
    controller level.
    The IXC flag is not connected to the interrupt controller and cannot generate an interrupt as
    its occurrence is very high. If needed, it must be managed by polling.

    Czyli nawet jest sprzętowe przerwanie - lepsze to chyba niż errno <:

    4\/3!!

Podsumowanie tematu

✨ Dyskusja dotyczy użycia jednostki FPU w rdzeniu Cortex-M4 z wykorzystaniem kompilatora GCC. Użytkownik stara się skonfigurować toolchain Linaro oraz Makefile, aby poprawnie korzystać z FPU. Wskazano na problemy z generowaniem kodu, który nie wykorzystuje instrukcji sprzętowych, takich jak vsqrt.f32, oraz na możliwe agresywne optymalizacje, które wpływają na wyniki. Uczestnicy dyskusji sugerują użycie flag optymalizacyjnych, takich jak -ffast-math oraz -fsingle-precision-constant, a także rozważają korzystanie z funkcji z nagłówka arm_math.h dla lepszej obsługi operacji zmiennoprzecinkowych. Poruszono również kwestie związane z obsługą błędów matematycznych w kontekście FPU oraz rejestrów statusowych.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA