Forum: Mikrocontroller und Digitale Elektronik STM32F4 SDIO DMA HAL problem


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Paul G. (paul_g210) Benutzerseite


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ich kämpfe seit einem Tag auf meinem STM32F407VE (Black Board)
einen einfachen SDIO DMA TX Transfer zu tätigen und zwar mit HAL
und CubeIDE und FsFat.

Ich habe mich strickt an diesen Weg gehalten (im PDF)

https://community.st.com/s/feed/0D50X00009bMM7JSAW

Bevor ich f_write ausführe setze ich den PIN PB15 auf HIGH und nach 
f_close
setzte ich PB15 wieder auf LOW und am Oszi messe ich wie lange f_write 
bis f_close gedauert hat um einschätzen zu können ob wirklich DMA 
verwendet wurde.

Ich messe immer ~140ms was mir irgendwie nicht koscher vorkommt. Ist der 
Transfer also doch nicht über DMA gelaufen? Sollte das nicht quasi 
instant passieren? Vielleicht verstehe ich das auch noch nicht ganz... 
Aber bei DMA würde ich jetzt nicht eine so große Verzögerung erwarten.


Nun habe ich folgende Probleme:

Nachdem ich die vier Funktionen in "bsp_driver_sd.c" und "sd_diskio.c"
angepasst habe verschwinden die Änderungen sofort wieder wenn ich "Code 
Generation" erneut ausführe. Also vermeide ich im Moment jede Änderung
im "Device Configuration" bis ich herausgefunden habe was der richtige 
Weg ist.

Außerdem verstehe ich den Sinn von FATFS->AdvancedSettings->Use DMA 
template nicht. Es gibt da wohl unter

STM32Cube_FW_F4_V1.25.0/Middlewares/Third_Party/FatFs/src/drivers
diverse Templates:
sd_diskio_dma_template_bspv1.c
sd_diskio_dma_template_bspv2.c
sd_diskio_dma_template.h

die ich dann wohl irgendwohin in mein Projekt kopieren/umbenennen muss 
und dann "Use DMA template" aktivieren... Ergo ich sehe überhaupt nicht 
mehr durch und weiß nicht mal ob ich überhaupt DMA nutze oder nur die 
ganz normale FatFs Routine...

Was ich ausschließen kann:
Fehlerhafte Übertragung, die Datei wird fehlerfrei auf die SD Karte 
geschrieben.

Das ist alles was ich ausführe:
1
f_mount(&fs, SDPath, 1);
2
f_open(&fp, name, FA_CREATE_ALWAYS | FA_WRITE);
3
HAL_GPIO_WritePin(OUT_GPIO_Port, OUT_Pin, GPIO_PIN_SET);
4
f_write(&fp, buffer, BUFFER_SIZE, &stored);
5
f_close(&fp);
6
HAL_GPIO_WritePin(OUT_GPIO_Port, OUT_Pin, GPIO_PIN_RESET);

Der TX buffer ist 64KB groß. Mein Board läuft mit:
HCLK 32MHz
SDIO CLKDIV 25

Hat jemand eine Idee was ich falsch mache oder ob die 140ms normal sind?

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
Paul G. schrieb:
> Ich messe immer ~140ms was mir irgendwie nicht koscher vorkommt. Ist der
> Transfer also doch nicht über DMA gelaufen?

Ich habe 1,8 MByte/s für das Board in Erinnerung, das wären knapp 30 ms 
für 64 kB. Aber du lässt den F407 ja mit angezogener Handbremse laufen, 
was schon in deinem anderen Thread keiner so richtig verstanden hat. Es 
ist ja nicht nur der DMA beteiligt, sondern auch die C Lib und das FAT 
mit seiner Verwaltung.
Das DMA verwendet wird sieht man doch an den Block Read/Write Funktionen 
mit _DMA suffix (in den BSP Dateien).

Paul G. schrieb:
> Nachdem ich die vier Funktionen in "bsp_driver_sd.c" und "sd_diskio.c"
> angepasst habe verschwinden die Änderungen sofort wieder wenn ich "Code
> Generation" erneut ausführe.

Tja, die Macht des Codegenerators... lässt der den Code evtl. in Ruhe 
wenn da die /* User code */ Kommentare eingebaut werden?

von Paul G. (paul_g210) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Johannes S. schrieb:
> Aber du lässt den F407 ja mit angezogener Handbremse laufen,
> was schon in deinem anderen Thread keiner so richtig verstanden hat.

Die 32MHz waren ein Kompromiss aus maximaler Stromaufnahme und SDIO 
Geschwindigkeit. Und bei 32MHz war es mir erst ab CLKDIV >=~25 möglich 
den
SDIO zuverlässig zum laufen zu bekommen, alles unter 25 ist unmöglich 
mit dem Board...


Also werde ich mich mit den 140ms abfinden müssen :)

von Paul G. (paul_g210) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Ok, ich habe jetzt nur mal so zum Testen das Board mit HCLK 168 MHz 
laufen und dem kleinsten CLKDIV der möglich ohne das FatFs Fehlermeldung 
macht und das ist CLKDIV 4 bei mir und auf dem Oszi sehe ich nun auch 
30ms.
ABER ohne DMA aktiviert.

Und wenn ich DMA wieder aktiviere sehe ich immer noch 30ms...

Habe ich hier einen Denkfehler? Ich dachte die Zeit zwischen f_write und 
f_close würde ohne DMA CPU Zeit beanspruchen, deshalb dachte ich ohne 
DMA würde es länger dauern den PIN zu schalten als wenn ich DMA 
aktiviert hätte und die CPU nix zu tun hätte...

: Bearbeitet durch User
von Adam P. (adamap)


Bewertung
0 lesenswert
nicht lesenswert
Paul G. schrieb:
> Habe ich hier einen Denkfehler? Ich dachte die Zeit zwischen f_write und
> f_close würde ohne DMA CPU Zeit beanspruchen, deshalb dachte ich ohne
> DMA würde es länger dauern den PIN zu schalten als wenn ich DMA
> aktiviert hätte und die CPU nix zu tun hätte...

Ja und Nein.
DMA bedeutet nur, dass der µC einen Buffer (Speicherbereich) 
selbstständig raustackten kann, ohne das du per Software nach jedem Byte 
einen Interrupt bekommst und das nächste Byte laden müsstest.
Ansich sollte das schneller sein, aber ich weiß jetzt ja auch nicht wie 
du ohne DMA schreibst.

Der Vorteil bei DMA ist, dass in der Zeit, wo der Buffer per DMA 
geschrieben wird, dein µC andere Softwareteile ausführen kann.

: Bearbeitet durch User
von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
Es wird ja der DMA gestartet und dann gewartet bis er fertig ist, 
insofern hängt die Dauer von der Übertragungsgeschwindigket ab. Mit 
Polling und ohne DMA kann das Datenfifo aber leichter über/unterlaufen 
wenn es nicht schnell genug bedient wird.
Siehe die Warteschleife mit Timeout im BSP code der auf das Ready vom 
DMA wartet. Und wie schaltest du da den DMA ab? Da muss dann ja anderer 
Code reingesetzt werden.

: Bearbeitet durch User
von Paul G. (paul_g210) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Johannes S. schrieb:
> Und wie schaltest du da den DMA ab? Da muss dann ja anderer
> Code reingesetzt werden.

Ich nehme unter SDIO den TX und RX DMA Kanal wieder raus und versetzte 
die "bsp_driver_sd.c" und "sd_diskio.c" wieder in den Originalzustand.


Ich muss wohl nochmal alles genau durchdenken und ob ich überhaupt DMA 
brauche...

Das Thema hatte ich schon mal in diesem Beitrag angesprochen:
Beitrag "Re: STM32f407 (black) SDIO CLK Fragen"

Ich bin nun so weit gekommen das ich erfolgreich kontinuierlich Daten 
per SPI (Polling) einlese und abwechselnd in zwei Buffer schreibe und 
immer wenn einer voll ist schreibe ich den Buffer mit f_write auf die 
SD-Karte und fülle den zweiten Buffer weiter mit Daten und dann wieder 
umgekehrt...

Das "Problem" ist halt nur das f_write den SPI Einlesevorgang 
Unterbricht und ich hab dann eine Lücke in den Daten von 
x-Millisekunden. Vermutlich sind die x-Millisekunden auch gar nicht so 
schlimm, aber ich dachte halt wenn f_write über DMA geht das ich diese 
Lücke vermeiden kann... Das war wohl zu einfach gedacht :D

Ich schaue mir mal die Daten geplottet an ob die Datenlücken die 
Interpretation der Kurven nicht zu sehr beeinflusst  , vielleicht reicht 
das ja doch aus und ich muss euch nicht länger quälen ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.