Hi
Ich bin neu in Microcontroller und verwende den STM32F303CCT6 mit
STM32CubeIDE. Mittels Ref Manual gehe ich verschiedene Kapitel (ADC,
Timer etc.) durch mit kleinen Beispielprojekten.
In Bezug auf ADC möchte ich gerne die interne Temperature sowie die
Referenzspannung mittels SWV und printf ausgeben, welche
Gleitkommazahlen sind:
Der genannte MCU besitzt eine FPU. Meine Fragen:
1. Wie aktiviere und benutze ich die FPU?
In den Einstellungen kann ich zwischen Hardware, Software und Mix HW/SW
wählen.
2. Sind das die einzigen Einstellungen, auf die ich achten muss?
3. Kann ich dann einfach mit float rechnen, ohne in der Performance
Abstriche zu machen?
Compiler-output sagt, u.a:
> -mfpu=fpv4-sp-d16 -mfloat-abi=hard
Die Einstellungen für den Compiler hast du gefunden. Damit sagst du dem
Compiler, dass er die FPU nutzen soll. Du musst die FPU aber vor der
Nutzung noch einschalten, mit
> SCB->CPACR = 0x00F00000;
Leider kann ich dir diese "magische" Zahl nicht erklären. Ich habe dazu
keine Doku gefunden.
Wenn du die FPU innerhalb von Interrupt-Handlern verwendest, musst du
der CPU außerdem sagen, dass sie ggf. deren Register auf dem Stack
sichern soll:
> SET_BIT(FPU->FPCCR, FPU_FPCCR_LSPEN_Msk + FPU_FPCCR_ASPEN_Msk);
Siehe http://stefanfrings.de/stm32/stm32f3.html> Kann ich dann einfach mit float rechnen, ohne in der> Performance Abstriche zu machen?
Ja, soweit die FPU es halt her gibt. Float Operationen sind auch mit FPU
nicht immer so schnell wie Integer Operationen. Ich würde sie daher nach
wie vor sparsam einsetzen.
Stefan ⛄ F. schrieb:> Leider kann ich dir diese "magische" Zahl nicht erklären. Ich habe dazu> keine Doku gefunden.
Einfach mal CPACR bei der Suchmaschine des geringsten Misstrauens
eingeben?
-> Vollzugriff auf Koprozessor 10 und 11 (warum auch immer die FPU auf 2
Koprozessoren aufgeteilt ist)
Im CMSIS finden sich auch die passenden Bitdefines.
Alex -. schrieb:> Ich habe diesen Link gefunden:> https://www.keil.com/support/docs/3716.htm
Siehst du, wenn man die richtigen Stichworte kennt, findet man auch was.
Passe aber auf, das Dokument bezieht sich auf den Cortex M7, der STM32F3
hat einen Cortex M4.
Stefan ⛄ F. schrieb:> Alex -. schrieb:>> Ich habe diesen Link gefunden:>> https://www.keil.com/support/docs/3716.htm>> Siehst du, wenn man die richtigen Stichworte kennt, findet man auch was.> Passe aber auf, das Dokument bezieht sich auf den Cortex M7, der STM32F3> hat einen Cortex M4.
Jap, das stimmt. Weshalb ich selbst in meiner SystemInit geschaut habe.
Zu deiner anderen Frage, wo man CPACR findet. Ist das nicht im Struct
SBC_Type in der core_cm4.h zu finden?
1
typedefstruct
2
{
3
...
4
__IOMuint32_tCPACR;/*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
Alex -. schrieb:> Zu deiner anderen Frage, wo man CPACR findet. Ist das nicht im Struct> SBC_Type in der core_cm4.h zu finden?
Das CPACR Register habe ich gefunden, aber keine Bit-Definitionen.
Offenbar verwendet sogar Keil deswegen ebenfalls "magische" Zahlen.
Das ist jetzt durchaus interessant, dass in dem Header die Bitdefs
fehlen.
Bis DFSR gibts die nur.
Da hat wohl ein Erstellscript bei ST oder ARM gezickt.
Ich hab aber mal mit grep geguckt wo meine Definition herkommt:
Aus einem Header vom Micrium OS.
Stefan ⛄ F. schrieb:> Leider kann ich dir diese "magische" Zahl nicht erklären. Ich habe dazu> keine Doku gefunden.
Im "Programming manual" (nicht Reference manual) stehen auch sämtliche
Bitdefinitionen dazu. Auch mit Beispiel, wie man das in ASM aktiviert.
Stefan ⛄ F. schrieb:> Alex -. schrieb:>> Zu deiner anderen Frage, wo man CPACR findet. Ist das nicht im Struct>> SBC_Type in der core_cm4.h zu finden?>> Das CPACR Register habe ich gefunden, aber keine Bit-Definitionen.> Offenbar verwendet sogar Keil deswegen ebenfalls "magische" Zahlen.
Ein typischer Stefan F.
Im von Dir sonst angepriesenen "Joseph Yiu, The Definitive Guide to ARM®
CORTEX®-M3 and CORTEX®-M4 Processors" in der dritten Edition von 2014
wird das doch im Kapitel
"13.2.3 CPACR register"
schön erklärt.
Insbesondere auch, dass man nicht zwangsläufig CP11 setzen muss.
Table 13.3. CP10 and CP11 Settings
Bits CP10 and CP11 Setting
00 Access denied. Any attempted access generate a Usage fault (type
NOCP – No Co-processor)
01 Privileged Access only. Unprivileged access generate a Usage fault
10 Reserved – result unpredictable
11 Full access
Vorschlag: Lies die von Dir angepriesene Literatur!
Planloser schrieb:> Ein typischer Stefan F.
Du mich auch.
> Vorschlag: Lies die von Dir angepriesene Literatur!
Glaube mir, das habe ich gemacht. Deswegen habe ich aber nicht das ganze
Buch auswendig im Kopf.
Deine Erklärung ist hilfreich, dein persönliche Angriff ist aber ohne
Würde. Du solltest wenigstens deinen richtigen Account verwenden, wenn
du dreist wirst.
test schrieb:> Im "Programming manual" (nicht Reference manual) stehen auch sämtliche> Bitdefinitionen dazu. Auch mit Beispiel, wie man das in ASM aktiviert.
Da steht nur CP10 und CP11 ohne weitere Erklärung, was das sein soll.
Stefan ⛄ F. schrieb:> Das CPACR Register habe ich gefunden, aber keine Bit-Definitionen.> Offenbar verwendet sogar Keil deswegen ebenfalls "magische" Zahlen.
Für die STM32 ist ja erstmal das Cortex-M4 programming manual PM0214
zuständig. Da steht 1:1 das gleiche drin wie im Cortex-M4 Devices™
Generic User Guide oder im ARM v7-M Architecture® Reference Manual. Das
letztere ist etwas ausführlicher, aber offiziell haben die vier Werte in
den Koprozessor-Bitfeldern also keinen Namen.
Jetzt müsste ST für ihre Header Files Namen erfinden. Ich glaube nicht,
dass uns das viel hilft. Deshalb schreibt man ja auch seine eigenen
Header aus dem Manual ab ;)
Planloser schrieb:> Insbesondere auch, dass man nicht zwangsläufig CP11 setzen muss.
bist du sicher? Der M4-Pseudo-Code zum Thema sieht so aus:
CheckVFPEnabled()// Check Coprocessor Access Control Register
7
// for permission to use CP10/11.
8
ifCPACR.cp10!=CPACR.cp11thenUNPREDICTABLE;
9
caseCPACR.cp10of
10
when‘00’
11
UFSR.NOCP=‘1’;
12
ExceptionTaken(UsageFault);
13
when‘01’
14
if!CurrentModeIsPrivileged()
15
UFSR.NOCP=‘1’;
16
ExceptionTaken(UsageFault);
17
when‘10’
18
UNPREDICTABLE;
19
// when ‘11’ // access permitted by CPACR
20
return;
Alex -. schrieb:> 3. Kann ich dann einfach mit float rechnen, ohne in der Performance> Abstriche zu machen?
Die FPU ist nur 32 Bit breit, also musst du float statt double benutzen,
double wird per Software gerechnet. Das ist dann etwas langsamer und
braucht eine lib, die man eigentlich nicht haben will. Die Gemeinheit
dabei ist, dass C per Default immer double benutzt. Auch wenn dein
"voltage" float ist, würde C mit double rechnen und bei der Zuweisung
nach float konvertieren.
Schuld ist die Konstante "3.3". Genau genommen müsste man 3.3f
schreiben, aber zum Glück kennt der GCC die Option
"-fsingle-precision-constant". Das gilt dann für alle Konstanten mit
Punkt oder E.
Richtig unangenehm wird es, wenn man float in lesbarer Form ausgeben
will. Man kann der printf() Familie kein float übergeben, es wird immer
zu double konvertiert. Schuld sind die default argument promotions
kombiniert mit stdarg.h.
Meistens will man auf einem uC auch kein vollständiges printf() haben,
eine reine Integer-Version ist doch merklich kleiner. Dafür habe ich
verschiedene Funktionen, die z.B. Spannung oder Temperatur als float
bekommen, passend umrechnen und ein Integer-printf() für die eigentliche
Ausgabe benutzen. Bei der Gelegenheit kann man auch den Wertebereich
prüfen und ggf. sowas wie ">99.9" statt 1.234E23 ausgeben.
Planloser schrieb:> Insbesondere auch, dass man nicht zwangsläufig CP11 setzen muss.
Hi all,
vielen Dank für eure Antworten. Ich glaube, ich habe die FPU aktiviert
(ohne etwas explizit dafür gemacht zu haben :) ).
@Stefan:
Um nochmal auf deinen Beitrag von vorhin zurückzukommen, weil der mir
ein wenig Kopfzerbrechen bereitet hat:
Stefan ⛄ F. schrieb:> Wenn du die FPU innerhalb von Interrupt-Handlern verwendest, musst du> der CPU außerdem sagen, dass sie ggf. deren Register auf dem Stack> sichern soll:>>> SET_BIT(FPU->FPCCR, FPU_FPCCR_LSPEN_Msk + FPU_FPCCR_ASPEN_Msk);
Ich weiß nicht, ob du das bereits weißt, oder ich deinen Beitrag (deine
Seite) vielleicht einfach nur missverstanden habe.
Ich habe aber gerade Dokument PM0214 von ST angesehen, Kapitel 4.6.2
(FPCCR).
Reset value is 0xC0000000 = 0b 1100 0000 0000 0000 0000 0000 0000 0000
Die obersten zwei Bits sind ASPEN und LSPEN, und sind nach Reset bereits
gesetzt.
Lazy stacking ist also bereits von Reset an aktiviert.
Alex -. schrieb:> Lazy stacking ist also bereits von Reset an aktiviert.
Das habe ich nicht bemerkt. Danke für den Hinweis, ich habe den Text
entsprechend aktualisiert.
Stefan ⛄ F. schrieb:>> SCB->CPACR = 0x00F00000;>> Leider kann ich dir diese "magische" Zahl nicht erklären. Ich habe dazu> keine Doku gefunden.
Die Doku findet man bei ARM im Prozessorhandbuch. Das ist quasi die
"goldene Referenz". Kann das Handbuch allgemein sehr empfehlen. Da haben
sich bei mir schon häufiger Dinge geklärt, die ST und Konsorten in ihren
Manuals teils unzulänglich oder ganz falsch beschrieben hatten.
https://developer.arm.com/documentation/100166/0001/Floating-Point-Unit/FPU-programmers-model/Enabling-the-FPU