Forum: Mikrocontroller und Digitale Elektronik STM32 SPI HAL extrem langsam


von MAX M. (maxmax123)


Lesenswert?

Hallo mir ist soeben aufgefallen, dass die HAL_SPI_TransmitReceive() 
sehr lange dauert.
Da dies vermutlich ein bekanntes Problem ist, hier die frage ob jemand 
einen ersatz programiert hat der am HAL vorbeigeht? Oder giebts im Hal 
selbst performantere funktionen?

Eigentlich muss doch nur das Sende FIFO beschrieben und das empfangs 
FIFO gelesen werden. Wieso dauert das so lange mit 
HAL_SPI_TransmitReceive()?? Hat ST wieder mal den Bock abgeschossen?

von J. S. (jojos)


Lesenswert?

klar, selber macht man nie Fehler und wendet API immer intuitiv richtig 
an. Fehler macht nur STM, das ist sehr praktisch weil man gleich weiss 
wo man den Fehler suchen muss.

von uff basse (Gast)


Lesenswert?

MAX M. schrieb:
> Hat ST wieder mal den Bock abgeschossen?

Nein, das Problem sitzt vor dem Bildschirm und Tastatur.

Solange du keinen Code zeigst und Eckdaten zum SPI Transfer
kann dir hier keiner helfen.

von Harry L. (mysth)


Lesenswert?

MAX M. schrieb:
> Da dies vermutlich ein bekanntes Problem ist

Nein, ist es nicht.

MAX M. schrieb:
> hier die frage ob jemand
> einen ersatz programiert hat der am HAL vorbeigeht?

Wozu, wenn HAL funktioniert?

MAX M. schrieb:
> Oder giebts im Hal
> selbst performantere funktionen?

Sicher:
HAL_SPI_TransmitReceive_IT()
HAL_SPI_TransmitReceive_DMA()

MAX M. schrieb:
> Wieso dauert das so lange mit
> HAL_SPI_TransmitReceive()??

Die Glaskugel ist zur Politur.
Zeig deinen Code!

MAX M. schrieb:
> Hat ST wieder mal den Bock abgeschossen?

Komisch, daß Anfänger den Fehler überall suchen, nur nicht in ihrem 
eigenen Code.

von PittyJ (Gast)


Lesenswert?

Bei mir geht es mit 16 MBit/sec. Ich habe letztens erst Performance 
Messungen gemacht.
Wobei die Polling Version leicht schneller war als Interrupt oder DMA.
Ist dir das zu langsam,dann nimm einen FPGA.

von MAX M. (maxmax123)


Lesenswert?

Harry L. schrieb:
> Komisch, daß Anfänger den Fehler überall suchen, nur nicht in ihrem
> eigenen Code.

Nun beim aufruf einer gegebenen Funktion und wenn die dann lange dauert 
kann man nicht besonders viel falsch machen.

Anyway habe einen Verdacht:
1. Ist es so dass diese Funktion blockierend ist und lediglich einen SPI 
transfer durchfürt und der empfangswert dieses (einzelnen) Transfers in 
den recv array schreibt?

2. Oder ist es so dass alles zu sendende in den sende FIFO/Ringbuffer 
geschrieben wird und alles bereits (vorgängig, FIFO/Ringbuffer) 
empfangene in das recv array schreibt.

Gesucht ist natürlich eine Funktion die 2. macht.
(Ich hoffe mal die SPI controller haben ein FIFO oder Ringbuffer im 
Memory map, und es bedarf nicht eines DMA für diese Angelegenheit).

von Harry L. (mysth)


Lesenswert?

MAX M. schrieb:
> Ist es so dass diese Funktion blockierend ist und lediglich einen SPI
> transfer durchfürt und der empfangswert dieses (einzelnen) Transfers in
> den recv array schreibt?

Fast...
Er sendet und empfängt eine definierte Anzahl von Bytes und ist 
blockierend.
Mit dem Timeout bestimmt man, wann abgebrochen und ein Fehler 
signalisiert wird.

Wenn du einen FIFO willst -schreib dir einen!
Das ist nicht de Aufgabe von HAL.

Und vor allem: RTFM!!!

https://www.st.com/resource/en/user_manual/um1725-description-of-stm32f4-hal-and-lowlayer-drivers-stmicroelectronics.pdf

: Bearbeitet durch User
von PittyJ (Gast)


Lesenswert?

Hast du Mal auf dem Bus mit einem Scope geschaut, wie schnell die Daten 
fließen? Vielleicht ist ja nur das Timing falsch gesetzt.

Und was ist bei dir extrem langsam?

Sourcen der SPI Initialisierung wäre wichtig. Aber der scheint geheim zu 
sein.

Schade, wilde Vermutungen und keine Fakten. So kommst du hier nicht 
weiter.

von MAX M. (maxmax123)


Lesenswert?

Harry L. schrieb:
> Das ist nicht de Aufgabe von HAL.

Da ist Aufgabe der HW. Nun wir haben 2022 und es kann doch nicht sein, 
dass ein moderner kommunikationskontroller selbst keinen empfangsbuffer 
hat für mehr als einen transfer. Also entweder HW FIFO gemapt auf eine 
addr im MM oder direkt vom SPI controller gemapter Empfangsringbuffer im 
MM.
Nun muss man anscheinend wenn man diese Grundfunktionalität haben möchte 
einen DMA controller einsetzen der dies übernimmt. Die ganze problematik 
mit Cache und DMA bekommt man gratis dazu - nur um einen vernünftigen 
SPI controller zu haben. (ein 2*512*32bit FIFO wären 32k SRAM Zellen, 
welche im 40nm Prozess nicht besonders ins Gewicht fallen würden)

Harry L. schrieb:
> Er sendet und empfängt eine definierte Anzahl von Bytes und ist
> blockierend.

Danke das ist genau der Grund für die tiefe Performance

von Harry L. (mysth)


Lesenswert?

MAX M. schrieb:
> Da ist Aufgabe der HW. Nun wir haben 2022 und es kann doch nicht sein,
> dass ein moderner kommunikationskontroller selbst keinen empfangsbuffer
> hat für mehr als einen transfer. Also entweder HW FIFO gemapt auf eine
> addr im MM oder direkt vom SPI controller gemapter Empfangsringbuffer im
> MM.

Du hast offenbar vollkommen falsche Vorstellungen von Microcontrollern 
dieser Klasse.

MAX M. schrieb:
> Nun muss man anscheinend wenn man diese Grundfunktionalität haben möchte
> einen DMA controller einsetzen der dies übernimmt. Die ganze problematik
> mit Cache und DMA bekommt man gratis dazu

Keine Ahnung, welche "Probleme" du da herbei fabulierst, aber sowas ist 
tägliches Brot von Firmware-Entwicklern, und HAL macht es einem da 
wirklich sehr, sehr einfach.

MAX M. schrieb:
> Die ganze problematik
> mit Cache und DMA bekommt man gratis dazu

Die STM32F4xx haben gar keinen Cache.


MAX M. schrieb:
> Danke das ist genau der Grund für die tiefe Performance

Mit Sicherheit nicht!
Der Grund ist dann in dem Code drum herum zu suchen - also genau 
genommen vor dem Monitor.

: Bearbeitet durch User
von Kevin M. (arduinolover)


Lesenswert?

Sag doch mal was für dich langsam ist. Ein F4 macht locker mehrere 
10MBit/s. Du kannst das Ding vermutlich einfach nicht richtig benutzen. 
Außerdem solltest du dich mal schlau machen wie "alt" der F4 eigentlich 
schon ist. Der ist auch noch kein 40nm Prozess.

Im übrigen ist DMA bei längeren Transfers bei solchen Controllern 
Standard. Die haben nicht umsonst mehrere davon. Außerdem ist der DMA 
viel flexibler als eine fixe FIFO.

von J. S. (jojos)


Lesenswert?

Der H7 hat einen FIFO und ist um Längen komplizierter. Daür schafft der 
dann >100 MHz mit DMA.

von MAX M. (maxmax123)


Lesenswert?

Harry L. schrieb:
> Keine Ahnung, welche "Probleme" du da herbei fabulierst,

Nun wenn du den D-Cache für deine DMA Bufferregion in der MPU nicht 
deaktivierst oder du vergisst cache maintenance funktionen einzusetzen. 
Wird dir der DMA ordentlich in die Hosen gehen.
Meines wissens geht das mit HAL DMA nicht. Falls sich das HAL um den 
Cache kümmert und es einfach so geht nehme ich alles zurück bitte um ein 
Bsp. Beweis.

von Harry L. (mysth)


Lesenswert?

Liest du eigentlich was wir hier schreiben?

Harry L. schrieb:
> MAX M. schrieb:
>> Die ganze problematik
>> mit Cache und DMA bekommt man gratis dazu
>
> Die STM32F4xx haben gar keinen Cache.

Und das ist das allerwichtigste:

Harry L. schrieb:
> Und vor allem: RTFM!!!
>
> 
https://www.st.com/resource/en/user_manual/um1725-description-of-stm32f4-hal-and-lowlayer-drivers-stmicroelectronics.pdf

von MAX M. (maxmax123)


Lesenswert?

Harry L. schrieb:
>> Die STM32F4xx haben gar keinen Cache

Ja schön und gut der STM32H7xx hat aber. Und das ist auch gut so (550MHz 
anstelle ca. 70). Anyway bei DMA muss man aufpassen. Wobei durch den 
performancegewinn kann man den Interrupt odentlich klinngeln lassen. 
Cache mit ISR ist besser als kein Cache mit DMA. Die CPU wird halt etwas 
generft sein.

Harry L. schrieb:
> Liest du eigentlich was wir hier schreiben?

Ja sorry hatte anscheinend etwas zu hohe Erwartungen (komme eher aus der 
FPGA welt wo solche buffer direkt Einstellbar sind und ich entsprechend 
immer verwende).
Anyway da ich noch etwas CPU ressourcen überig habe werde ich wohl den 
SPI einfachheitshalber mit Interrupts machen. Anyway kann ich den SPI 
interrupt deaktivieren? (Der SPI Transfer funktionsaufruf wird selbst in 
einer timer ISR sein und es kann ausgeschlossen werden dass der Transfer 
nicht abgeschlossen ist/ mehr als ein transfer empfangen wird zwischen 
den timer ISR - Daher Interrupt bezüglich SPI unnötig).

von MAX M. (maxmax123)


Lesenswert?

J. S. schrieb:
> Der H7 hat einen FIFO und ist um Längen komplizierter. Daür schafft der
> dann >100 MHz mit DMA.

Ahh geht doch. Sorry ganz übersehen. Genial, genau das suche ich. Wie 
kann ich das mit den HAL Funktionen nutzen?

von MAX M. (maxmax123)


Lesenswert?

Kevin M. schrieb:
> Sag doch mal was für dich langsam ist. Ein F4 macht locker mehrere
> 10MBit/s. Du kannst das Ding vermutlich einfach nicht richtig benutzen.
> Außerdem solltest du dich mal schlau machen wie "alt" der F4 eigentlich
> schon ist. Der ist auch noch kein 40nm Prozess.

Ich hab einen H7 - verstehe nicht weshalb ihr alle mit F4 kommt. Hab nie 
was von F4 erwähnt.

von Kevin M. (arduinolover)


Lesenswert?

MAX M. schrieb:
> Wie kann ich das mit den HAL Funktionen nutzen?

Schreib doch einfach selbst Code, wer so fortgeschrittene Anforderungen 
hat sollte nicht auf HAL angewiesen sein.

von Harry L. (mysth)


Lesenswert?

Sorry, aber, wer sich so hartnäckig dem Auffinden und Lesen von 
Handbüchern verweigert, dürfte imho mit einem H7 maximal überfordert 
sein.

Dabei ist die HAL-Doku inzw. wirklich recht ordentlich. (war Anfangs 
etwas dürftig)

Klingt doch alles sehr nach Wolken-Kuckuksheim.

: Bearbeitet durch User
von MAX M. (maxmax123)


Lesenswert?

Harry L. schrieb:
> Sorry, aber, wer sich so hartnäckig dem Auffinden und Lesen von
> Handbüchern verweigert

Habe nun das entsprechende HAL Datenblatt zum H7 angeschaut. 
https://www.st.com/resource/en/user_manual/um2217-description-of-stm32h7-hal-and-lowlayer-drivers-stmicroelectronics.pdf

Auf Seite 1556:

HAL SPI Extension Driver
84.1 SPIEx Firmware driver API description
The following section lists the various functions of the SPIEx library.
84.1.1 IO operation functions
This subsection provides a set of extended functions to manage the SPI 
data transfers.
1. SPIEx function:
– HAL_SPIEx_FlushRxFifo()
– HAL_SPIEx_FlushRxFifo()
– HAL_SPIEx_EnableLockConfiguration()
– HAL_SPIEx_ConfigureUnderrun()

Sind die neuen Funktionen beschrieben. Leider habe ich keine 
HAL_SPIEx_RW_FIFO() gefunden. Das FIFO ist auch relativ klein und 
scheint eigentlich dafür gedacht zu sein schnellere SPI clks zu 
ermöglichen. Das FIFO in meinem Sinne zu nutzen sehe ich zumindes 
aktuell mit dem HAL nicht möglich.

von Harry L. (mysth)


Lesenswert?

MAX M. schrieb:
> Auf Seite 1556:

Eine Seite zu lesen reicht bei Weitem nicht aus...

ProfiTip: 2 oder 3 Seiten reichen auch nicht.

von J. S. (jojos)


Lesenswert?


von LPC1768 (Gast)


Lesenswert?

> 2 oder 3 Seiten reichen auch nicht.

Bei einem LPC1768 reicht das schon fuer SPI mit 50 Mbit/s.
Da geht das alles recht einfach.
Aber der hat ja und braucht auch keine HAL.

von PittyJ (Gast)


Lesenswert?

Ich habe auch einen H7, und der macht 16MBit. Wie schon geschrieben.

Das Modell hast du erst sehr spät gepostet. Warum eigentlich? Warum 
schaffst du es nicht, den Sourcecode und die Hal-Initialisirung zu 
posten.

Auch meine Frage, was du als langsam empfindest, wurde nicht 
beantwortet.

Du gibst uns keine Möglichkeiten, dir konkret zu helfen. Du will nur 
jammern und auf STM pöbeln, weil du es selbst einfach nicht drauf hast. 
Und nun suchst du einen Sündenbock.

von Kevin M. (arduinolover)


Lesenswert?

PittyJ schrieb:
> Ich habe auch einen H7, und der macht 16MBit. Wie schon geschrieben.

Dann kannst du ihn eindeutig nicht bedienen. Ich nutze aktuell einen H7 
um Messwerte mit 50kHz aufzunehmen, mehrere auch teilweise aufwendigere 
Berechnungen damit zu machen und diese anschließend über SPI den PC zu 
senden. Da gehen deutliche mehr als 16MBit/s und der ist noch lange 
nicht am Ende.

: Bearbeitet durch User
von MAX M. (maxmax123)


Lesenswert?

J. S. schrieb:
> Der FIFO wird beim H7 in HAL_SPI_Transmit genutzt.
>
> 
https://github.com/STMicroelectronics/STM32CubeH7/blob/0c3a06c18bd2a87b006a84f997f2b0b56d97a113/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c#L941

Danke. Diese funktion scheint auch nicht blockierend (zumindest nicht 
wenn der SPI idle ist; im 8/16 bit modus sogar FIFO genügend Platz). Ich 
müsste aber auch empfangen.
Kann man vor dem Aufruf der HAL_SPI_Transmit die rx register auslesen? 
Ober werden diese gar nicht gefüllt? Also ziel: die eigentlich gem. 
dieser Funktion nicht vorhandenen Empfangsdaten des vorgängigen SPI 
Transfers zu sichern.

von MAX M. (maxmax123)


Lesenswert?

Kevin M. schrieb:
> Da gehen deutliche mehr als 16MBit/s und der ist noch lange
> nicht am Ende.

Wenn er das Datenblatt lesen würde wüsste er dass 150Mbit/s (nur 
Empfang) mit einigen der SPIs im slave modus Möglich sind und 133Mbit/s 
im Master. Aber PittyJ trollt halt lieber rum und hat als einer der 
wenigen hier noch nicht begriffen, das es hier nicht um die bitrate geht 
sondern darum dass der funktionsaufruf so viel cpu zeit benötigt (wegen 
der Blockage).

: Bearbeitet durch User
von J. S. (jojos)


Lesenswert?

MAX M. schrieb:
> Ich
> müsste aber auch empfangen.

Dafür ist dann HAL_SPI_TransmitReceive(). Daten von einem vorherigen 
Aufruf kann es nicht geben, das Empfangen ist ja synchron zum Senden.
Es gibt auch einige AppNotes von ST, das SPI Device im H7 ist sehr 
komplex und dazu kann man ja viele Betriebsarten mischen.
Wenn es langsam ist weil es viele Daten sind, dann sollte man natürlich 
die _IT oder _DMA Varianten wählen. 150 MBit/s nutzen ja nix wenn die 
Software alle paar Byte erstmal wieder Daten nachschieben muss.

von Rudolph (Gast)


Lesenswert?

Es gibt auch noch:
LL_SPI_TransmitData8()
LL_SPI_ReceiveData8()

Die machen praktisch nichts anderes als Daten auf den SPI zu werfen, 
selbst die Flags muss man auswerten ( LL_SPI_IsActiveFlag_TXP() / 
LL_SPI_IsActiveFlag_RXWNE() für den H7) wenn man das in einer Schleife 
laufen lassen möchte um blockierend mal ein paar Bytes über den SPI zu 
verschicken ohne lange Pausen zwischen den Bytes.

Den Source-Code von den Funktionen kann man sich ja ansehen.

von Harry L. (mysth)


Lesenswert?

MAX M. schrieb:
> J. S. schrieb:
>> Der FIFO wird beim H7 in HAL_SPI_Transmit genutzt.
>>
>>
> 
https://github.com/STMicroelectronics/STM32CubeH7/blob/0c3a06c18bd2a87b006a84f997f2b0b56d97a113/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c#L941
>
> Danke. Diese funktion scheint auch nicht blockierend (zumindest nicht
> wenn der SPI idle ist; im 8/16 bit modus sogar FIFO genügend Platz). Ich
> müsste aber auch empfangen.
Du hast das UM noch immer nicht gelesen, sonst wüsstest du bereits, 
das diese Funktionen ohne "_IT" und "_DMA" blockierend arbeiten.

> Kann man vor dem Aufruf der HAL_SPI_Transmit die rx register auslesen?
> Ober werden diese gar nicht gefüllt? Also ziel: die eigentlich gem.
> dieser Funktion nicht vorhandenen Empfangsdaten des vorgängigen SPI
> Transfers zu sichern.
Aha, du willst also HAL nutzen, aber den Umgang damit nicht lernen und 
trotzdem komplett an HAL vorbei programmieren - na toll!

So wird das garantiert nix - keine Arme keine Kekse

von MAX M. (maxmax123)


Lesenswert?

Harry L. schrieb:
> sonst wüsstest du bereits

weis ich auch danke, ich beziehe mich auf den spezialfall der 
sendefunktion die nicht den kompletten transfer abwartet sofern der 
aktuelle transfer starten kann.
Das die blockierend sind habe ich als Ursache meines Problems seit ca 
post 5-10 erkannt.

Harry L. schrieb:
> Aha, du willst also HAL nutzen, aber den Umgang damit nicht lernen und
> trotzdem komplett an HAL vorbei programmieren - na toll!

Ja ist murks, wäre mir auch lieber das HAL würde funktionen 
bereitstellen welche die FIFO (über welche der H7 auch verfügt) in 
meinem Sinne nutzen würden. Diese sind jedoch nicht vorhanden.
Sauberer wärs natürlich mit _IT oder _DMA, anyway wie bereits 
beschrieben habe ich für beide Gründe weshalb ich die ungerne verwende.

von Harry L. (mysth)


Lesenswert?

MAX M. schrieb:
> Ja ist murks, wäre mir auch lieber das HAL würde funktionen
> bereitstellen welche die FIFO (über welche der H7 auch verfügt) in
> meinem Sinne nutzen würden. Diese sind jedoch nicht vorhanden.

Da irrst du!
Du hast nur nicht verstanden, wie das funktioniert und willst die 
korrekten Funktionen aus ideologischen Gründen nicht nutzen.

MAX M. schrieb:
> Sauberer wärs natürlich mit _IT oder _DMA, anyway wie bereits
> beschrieben habe ich für beide Gründe weshalb ich die ungerne verwende.

So funktioniert das aber nun mal....

von PittyJ (Gast)


Lesenswert?

Kevin M. schrieb:
> PittyJ schrieb:
>> Ich habe auch einen H7, und der macht 16MBit. Wie schon geschrieben.
>
> Dann kannst du ihn eindeutig nicht bedienen. Ich nutze aktuell einen H7
> um Messwerte mit 50kHz aufzunehmen, mehrere auch teilweise aufwendigere
> Berechnungen damit zu machen und diese anschließend über SPI den PC zu
> senden. Da gehen deutliche mehr als 16MBit/s und der ist noch lange
> nicht am Ende.

Doch, ich kann ihn bedienen. Nur meine Slave, ein Radarsensor, stieg 
dann aus. Das waren die Limits meines Slaves.
Der SPI-Teiler war 8, könnte man noch 3 Stufen runter setzen.

Diese 16MBit sind real gemessen mit einem Slave und nicht nur Theorie.

von PittyJ (Gast)


Lesenswert?

Was ich nicht verstehe: Der Sourcecode der Hal liegt doch mit dabei, der 
ist nicht geheim. Da habe ich auch schön öfter reingeschaut. Der Code 
sogar mit Kommentaren versehen.

Warum schafft es der Max nicht, sich das auch einmal anzuschauen? Dann 
könnte er vielleicht seine Blockade finden?

von Kevin M. (arduinolover)


Lesenswert?

PittyJ schrieb:
> Warum schafft es der Max nicht, sich das auch einmal anzuschauen? Dann
> könnte er vielleicht seine Blockade finden?

Das macht man heutzutage nicht mehr, man schreibt lieber in Foren. Da 
gibt es Leute die einen dir Arbeit abnehmen.

PittyJ schrieb:
> Diese 16MBit sind real gemessen mit einem Slave und nicht nur Theorie.

Ja schön 100Mbit sind auch keine Theorie.

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.