Forum: Mikrocontroller und Digitale Elektronik STM32F7: Koprozessor Auslöser für HardFault?


von lars (Gast)


Lesenswert?

An einer bestimmten Stelle meines Codes wird reproduzierbar ein 
HardFault geworfen, mit folgendem Stack:
1
Debug proto.elf [Embedded C/C++ Application]   
2
  proto.elf    
3
    Thread #1 57005 (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)    
4
      HAL_Delay() at stm32f7xx_hal.c:382 0x2005e8     
5
      my_abort() at util.c:224 0x20fd2e      
6
      HardFault_Handler() at stm32f7xx_it.c:131 0x20f65a      
7
      <signal handler called>() at 0xfffffff1 
8
      my_handler() at proto.c:501 0x0       
9
      EXTI1_IRQHandler() at stm32f7xx_it.c:291 0xa16  
10
      <signal handler called>() at 0xfffffff1 
11
      follow_path() at ff.c:2,850 0x208658    
12
      f_stat() at ff.c:4,356 0x20982c 
13
      my_function() at proto.c:2,080 0x20ce92
14
      my_scheduler() at proto.c:890 0x4ec       
15
      PendSV_Handler() at stm32f7xx_it.c:218 0xb76    
16
      <signal handler called>() at 0xfffffff9 
17
      main() at main.c:212 0x20e6b8   
18
    /opt/atollic/ARMTools/bin/arm-atollic-eabi-gdb (7.10.1.20160923)        
19
    SEGGER J-LINK

In my_function wird f_stat aufgerufen, während gerade ein IR mit höherer 
Priorität getriggert wird. Die my_handler Routine macht nur Arithmetik 
und GPIO und benutzt FatFs nicht. Ich verwende kein RTOS.

Im HardFault-Handler sehe ich, dass
1
SCB->HFSR = 0x40000000      -> "Forced"
2
SCB->CFSR = 0x80000         -> "Missing coprocessor"

Was kann diesen Koprozessor-Fehler verursachen? Mein Code verwendet 
wissentlich keinen Koprozessor. Welcher Kopro ist denn überhaupt 
gemeint? Kann die Ursache bei FatFs (nicht reentrant) liegen?

von Fred R. (Firma: www.ramser-elektro.at/shop) (fred_ram)


Lesenswert?


von lars (Gast)


Lesenswert?

Fred R. schrieb:
> Das Appnote kenntst du?

Nein, kannte ich nicht, aber ich verwende keine FPU und habe auch keine 
float/double im Code.

von Jim M. (turboj)


Lesenswert?

Die FPU ist als Coprozessor realisiert und bei Reset aus. Man muss die 
früh im Code manuell einschalten.


Der Compiler geht (bei Verwendung ensprechender Optionen) davon aus dass 
die FPU permanent AN ist und generiert entsprechende Instruktionen. 
Schau Dir doch mal das Disassembly von my_handler() an.

von lars (Gast)


Lesenswert?

Ich finde die genaue Position von my_handler im Disassemblat nicht, aber 
ich sehe weder .F32/.F64 noch VADD/VSUB/... im Code.

Im TrueStudio ist
1
Floating Point       Hardware
2
FPU                  FPv5-SP-D16

eingestellt.

Die Sache mit my_handler ist ja auch, dass die Funktion vorher schon 
tausendfach ohne Probleme durchlaufen wurde (allerdings hat sie auch 
verschiedene Zweige).

von lars (Gast)


Lesenswert?

Wenn ich auf im TrueStudio auf Software/None wechsle, erhalte ich beim 
Linken trotz Clean Fehlermeldungen wie:

/opt/atollic/ARMTools/bin/../lib/gcc/arm-atollic-eabi/6.3.1/../../../../ 
arm-atollic-eabi/bin/ld:  error: aproto.elf uses VFP register arguments, 
Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.o does not

von pegel (Gast)


Lesenswert?

lars schrieb:
> Im TrueStudio ist
> Floating Point       Hardware
> FPU                  FPv5-SP-D16

Schalte das aus, dann passt es mit dem anderen wieder zusammen.

von pegel (Gast)


Lesenswert?

Entschuldigung, hatte glatt den Satz überlesen, hast du ja schon 
gemacht.

Ich hatte nur die Fehlermeldung gelesen, die mir recht bekannt vorkam.

von pegel (Gast)


Lesenswert?

Aber Moment, die STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.o wird auch neu 
compiliert. Da muss etwas mir dem clean nicht in Ordnung sein.

Sieh nach dem clean in das Verzeichnis. Sind die .o alle noch da, stimmt 
etwas nicht. Zur Not, lösche sie von Hand.

von lars (Gast)


Lesenswert?

pegel schrieb:
> Aber Moment, die STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.o wird auch neu
> compiliert. Da muss etwas mir dem clean nicht in Ordnung sein.

Der Clean macht alle .o Dateien weg, insb. auch 
STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.o!

Vielleicht wäre es einfacher, den Code so zu lassen und die FPU 
einzuschalten? Im Programming Manual habe ich eine Assembler-Sequenz 
dafür gefunden, die im Wesentlichen
1
CPACR |= 0xf << 20;

macht. Allerdings steht da auch etwas von "pipeline reset", wie mache in 
den in C? Und wo finde ich das CPACR-Register? In core_cm7.h ist CPACR 
definiert, aber nur als struct, ohne Instanzierungen.

von Nop (Gast)


Lesenswert?

lars schrieb:
>  Allerdings steht da auch etwas von "pipeline reset", wie mache in
> den in C?

__ISB() sollte in CMSIS definiert sein.

von lars (Gast)


Lesenswert?

Danke für den Hinweis.

Ich glaube, ich habe den Übeltäter gefunden (Suffix war nur .64, nicht 
.F64):
1
   12458:       fff1 04bd       vsri.64 d16, d29, #15

Wahrscheinlich ist es besser, auf die FPU zu verzichten, wenn dies die 
einzige Verwendung ist? Was muß man im TrueStudio einstellen, damit es 
keinen Link-Fehler gibt?

von lars (Gast)


Lesenswert?

Ah, hab's gefunden. Compiler, Assembler und Linker habe separate 
Einstellungen für die FPU. Wenn ich alle ändere, dann klappt's auch mit 
dem Linken.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.