Hallo, ich habe auf einem STM32 der mit 72 MHz läuft ein Programm das alle 500µs eine Funktion für eine Prozesssteuerung ausführt (Eingabe - Berechnung - Ausgabe). Das sind dann 36000 verfügbare Takte zur Ausführung der Steuerungsfunktion. Sie braucht davon ca. 25000. Jetzt würde ich gerne pro Ausführung einen Datenblock aus 512 Bytes aus Logdaten generieren und diesen auf eine SD-Karte speichern (sequentiell an eine Datei anhängen o.ä.). Diese würde per Hardware-SPI (18 MHz max) angebunden werden. 2kHz * 512 Bytes ~= 1MByte/Sec sollte möglich sein. Zur Übertragung eines 512Bytes Datenblock würden 4096 SPI-Takte = 16384 CPU-Takte benötigt. Für die Ansteuerung würde ich die Elm-Chan FatFs Library nehmen. Leider passt das SD-Karten-Schreiben so nicht hinein, denn 16384+25000 > 36000. Allerdings wäre es per DMA möglich, den Datenblock automatisch zum SPI rauszuschieben. Nur wie integriere ich das in die FatFs Library? Die ruft eine "disk_write" Funktion auf zum Schreiben auf die Karte und erwartet dass der Vorgang nach dessen Rückkehr fertig ist. Ich müsste FatFs dazu bringen... * Den Schreibvorgang zu starten * DMA-Transfer zu starten * die CPU freizumachen für die Prozess-Steuerungs-Funktion (Rückkehr aus f_write ohne dass disk_write fertig ist??) und nach Abschluss des Blocktransfers das Schreiben abzuschließen. Aber wie? Gibt es vieleicht eine Fat/SD-Library die das kann? In kurz: Wie gleichzeitig eine Berechnung und eine SD-Ansteuerung umsetzen, wenn nicht genug CPU-Zeit da ist um auf die Übertragung zu warten, aber per DMA parallel geschrieben werden könnte?
Rechne mit 10k Schreibzyklen vor dem Defekt der Karte. Wenn immer auf einen Sektor geschrieben würde, wäre die Karte nach 5sek hin. Zum Glück verteilst du die Auslastung auf mehrere Sektoren. Aber auf wie viele?
A. S. schrieb: > Rechne mit 10k Schreibzyklen vor dem Defekt der Karte. So wenige? Da haben ja manche Mikrocontroller mehr Flash-Zyklen. Nicht eher 10M? > Wenn immer auf einen Sektor geschrieben würde, wäre die Karte nach 5sek > hin. Darum gehts natürlich nicht. Bei der gegebenen Rate ist eine 32GByte Karte nach >9h voll. Wenn ich 10000x eine Karte 9h lang vollschreiben kann (=> insgesamt >10 Jahre Betriebszeit), ist das vollkommen ausreichend. > Zum Glück verteilst du die Auslastung auf mehrere Sektoren. Aber auf wie > viele? Das macht die Karte doch automatisch (Wear-Leveling).
>Das macht die Karte doch automatisch (Wear-Leveling).
Das wird dir auch den Strich durch die Rechnung machen alle 500µs
einen Sektor zu schreiben.
Programmierer schrieb: > Das macht die Karte doch automatisch (Wear-Leveling). Früher hatten manche SD-Karten-Controller nur ein Wear-Leveling für die Sektoren, auf denen die FAT lag, weil da am meisten geschrieben wurde. (bzw: Für die ersten X Megabyte ein besseres Wear-Leveling als für den Rest) Nachdem die Spezifikation FAT als Dateisystem vorgeschrieben hatte, war das garnicht so dumm.. Deswegen wäre hier interresant: A. S. schrieb: > Wenn immer auf einen Sektor geschrieben würde, wäre die Karte nach 5sek > hin. Welcher Sektor?
Spannend ist auch, das die ne 16GB Karte nach ca. 4,5 Stunden voll wäre und wie sieht das eigentlich mit der max. Dateigröße von 2GB aus? Du müsstest also nach ca. 30min eine neue Datei anfangen... :-o
Schreibt die FatFs wirklich nur einen Block? Sollten doch 4 Blöcke sein. Der Datenblock, FAT, Kopie der Fat, Dateigröße im Verzeichniss.
dummy schrieb: > Das wird dir auch den Strich durch die Rechnung machen alle 500µs > einen Sektor zu schreiben. Warum? Dauert die Suche nach Blöcken so lange? Ich habe ca 16KB RAM frei, könnte man das durch Puffern ausgleichen? Εrnst B✶ schrieb: > Früher hatten manche SD-Karten-Controller d.h. ich nehme einfach eine neue Karte? Εrnst B✶ schrieb: > Welcher Sektor? Wie gesagt möchte ich sequentiell eine Datei immer länger werden lassen (Log halt), d.h. es ist kein einzelner Sektor, sondern die ganze Karte. Michael R. schrieb: > Spannend ist auch, das die ne 16GB Karte nach ca. 4,5 Stunden voll wäre Also nehme ich eine 32GB Ka
> es ist kein einzelner Sektor
Solange du Rohdaten ohne Filesystem schreibst: Ja.
Wenn die FatFs jedes mal ein Update auf das Verzeichnisse macht, sieht
es ganz anders aus.
Nachdem Android meinen Post zerstückelt hat hier die Fortsetzung: Michael R. schrieb: > wie sieht das eigentlich mit der max. Dateigröße von 2GB aus? Du > müsstest also nach ca. 30min eine neue Datei anfangen... :-o Das ist akzeptabel. Verwunderter Leser schrieb: > Schreibt die FatFs wirklich nur einen Block? Sollten doch 4 Blöcke sein. > Der Datenblock, FAT, Kopie der Fat, Dateigröße im Verzeichniss. Gute Frage. Werden wirklich bei jedem einzelnen Schreibvorgang alle 4 Blöcke geschrieben? Verwunderter Leser schrieb: > Solange du Rohdaten ohne Filesystem schreibst: Ja. Wie gesagt ist das nicht der Plan. Verwunderter Leser schrieb: > Wenn die FatFs jedes mal ein Update auf das Verzeichnisse macht, sieht > es ganz anders aus. Wenn das Schreiben von Daten auf eine SD-Karte so problematisch ist, wieso werden die dann überhaupt verwendet? Könnte ich nicht einfach jede Datei zu Anfang auf 2 GB setzen und mit 0en füllen, und dann im Betrieb mit Daten auffüllen? Dann müssen die Metadaten im Betrieb gar nicht aktualisiert werden... Andere verwenden ja auch SD-Karten zum loggen. Wie sieht das jetzt mit FatFS & DMA aus? Kann man das so hinbekommen?
Programmierer schrieb: > In kurz: Wie gleichzeitig eine Berechnung und eine SD-Ansteuerung > umsetzen, wenn nicht genug CPU-Zeit da ist um auf die Übertragung zu > warten, aber per DMA parallel geschrieben werden könnte? Wenn du den Ganzen overhead mit Fat weglässt, dann kannst du immer 512 einfach auf die SD-Karte schreiben. Das Auslesen am PC ist dann schwieriger, dafür ist ist dein µC Programm einfacher. Du brauchst nur SD-Card-Init und write Sektor. Oder du musst die Lib ein wenig umschreiben, um das um zusetzten. Dazu machst du am besten ganz zu Beginn deines Programms eine Datei auf, da am Anfang mehrere Sektoren gelesen werden müssen. Dann brauchst du 2x 512 Byte Puffer. Einer kann mit Daten befüllt werden und Einer kann auf die Karte geschrieben werden. Dann musst du die "write" Funktion so umschreiben, dass 512 Byte in einen der Puffer geschrieben werden (oder besser die Funktion kann direkt mit den 512 Byte arbeiten). Dann startest du den Vorgang mit DMA und aktivierst einen Interrupt der ausgeführt wird sobald die 512 Byte geschrieben wurden. In dem Interrupt wechselst du die Puffer (musst du dir mit einem Flag merken).
>Wenn das Schreiben von Daten auf eine SD-Karte so problematisch ist, >wieso werden die dann überhaupt verwendet? Sie sind gross und billig. Der Anwendungszweck ist doch eher Audiodaten abzuspielen und Fotos zu speichern. Da macht es nichts aus wenn die Karte beim speichern mal 300ms Pause macht. Für Echtzeitanwendungen wurden die nicht konstruiert.
@Programmierer (Gast) >36000. Allerdings wäre es per DMA möglich, den Datenblock automatisch >zum SPI rauszuschieben. Nur wie integriere ich das in die FatFs Library? Das ist mit einigem Aufwand verbunden. >Die ruft eine "disk_write" Funktion auf zum Schreiben auf die Karte und >erwartet dass der Vorgang nach dessen Rückkehr fertig ist. Ja. > Ich müsste >FatFs dazu bringen... >* Den Schreibvorgang zu starten >* DMA-Transfer zu starten >* die CPU freizumachen für die Prozess-Steuerungs-Funktion (Rückkehr aus >f_write ohne dass disk_write fertig ist??) >und nach Abschluss des Blocktransfers das Schreiben abzuschließen. Aber >wie? Gibt es vieleicht eine Fat/SD-Library die das kann? Keine Ahnung. Ein Forumsteilnehmer hat das mal probiert, die Lösung erscheint mir aber nicht sonderlich solide. Beitrag "sd-Karte Elm Chan DMA" Beitrag "SD-Card mit DMA beschreiben"
Falk Brunner schrieb: > Ein Forumsteilnehmer hat das mal probiert, die Lösung erscheint mir aber > nicht sonderlich solide. Die Lösung ist in Bezug auf den DMA-Teil solide und tragfähig. Der Linktable-Teil müsste überarbeitet werden, weil ich die Verwendung von Linktable bei Elm Chan nicht wirklich nachvollziehen konnte. Bei Linktable legt Fat zuerst eine Datei bestimmter Größe an. Anschließend werden die in der Linktable aufgelisteten Sektoren dieser Datei mit Daten gefüllt. Die Daten können dann ohne den Fat-Überbau geschrieben werden.
>Die Lösung ist in Bezug auf den DMA-Teil solide und tragfähig.
Das mag sein, aber auch das verhindert das Wearlevelling nicht.
Wenn die Karte Busy ist ist sie Busy. Da bringt
DMA fast keinen Vorteil. Seine Echtzeitanforderungen
kann er nur mit einem riesigen RAM Buffer einigermassen einhalten.
Pro Millisekunde Busy sind das bei ihm ein Kilobyte RAM.
Und von meinen Karten weiss ich das die gerne so von 40ms bis
300ms Busy sind beim Wearlevelling. Und das zu nicht vorhersehbaren
Zeiten. Die Folgen kann man sich ja ausrechnen.
holger schrieb: > Wenn die Karte Busy ist ist sie Busy. Da bringt > DMA fast keinen Vorteil. Der gemessene Vorteil ist 1,2MByte/sec bei DMA gegenüber knapp 0,5MByte/sec mit normalem Spi. Weiterer Vorteil von DMA ist , dass die CPU nicht belastet wird und während des Schreibens andere Aufgaben erledigen kann. Die Busy-Zeiten sind relativ kurz und spielen bei der Übertragung von 512 Byte-Blöcken nur eine sehr untergeordnete Rolle.
Eduard Scheske schrieb: > Dann musst du die "write" Funktion so umschreiben, dass 512 Byte in > einen der Puffer geschrieben werden (oder besser die Funktion kann > direkt mit den 512 Byte arbeiten). > Dann startest du den Vorgang mit DMA und aktivierst einen Interrupt der > ausgeführt wird sobald die 512 Byte geschrieben wurden. > In dem Interrupt wechselst du die Puffer (musst du dir mit einem Flag > merken). Das heißt also man gaukelt FatFS vor die Daten seien schon geschrieben obwohl sie es nicht sind, und reicht das nach? Raffiniert. dummy schrieb: > Da macht > es nichts aus wenn die Karte beim speichern mal 300ms Pause > macht. Wäre bei mir auch nicht so schlimm wenn der Log ein paar Lücken hat, wenn das nicht zu oft auftritt (max 1x pro 5sek oder so). > Für Echtzeitanwendungen wurden die nicht konstruiert. Welches Speichermedium ist das denn? SSD und Bänder? Mir kam folgende Idee: die FatFS Library nicht modifizieren, aber ein (einfaches) Multithreading verwenden und in der disk_read/disk_write Funktion den DMA-Transfer starten, den "Thread anhalten" (rausspringen), und dadurch die CPU für die Prozess-Steuer-Funktion freimachen. Wenn der Transfer fertig ist zurückspringen und somit die FatFS Funktion fortsetzen. Das hat den Vorteil die FatFS Library nicht anfassen zu müssen, und dass das mit allen Funktionen funktioniert und man so beliebige Abläufe auf der Karte unterbrechbar ausführen kann. Was haltet ihr davon?
Programmierer schrieb: >> Für Echtzeitanwendungen wurden die nicht konstruiert. > Welches Speichermedium ist das denn? SSD und Bänder? Die Sd-Karte wurde schon für Echtzeitanwendungen konstruiert, nur nicht mit dem SPI-Modus. SDIO ist mit 4parallelen Datenleitungen wesentlich schneller. Der Sinn des ganzen DMA-Aufwandes für einen Cortex-M3 stellt sich dann in Frage, wenn ein Cortex-M4 die Hardware für SDIO preiswert bereitstellt. Bei 30€ für ein komplettes STM32F429-board lohnen sich Entwicklungen für einen M3 eigentlich nicht mehr, wenn das bestenfalls erzielbare Ergebnis in Bezug auf die Datenrate bei weitem nicht die Möglichkeiten eines M4 erreichen kann.
>Die Sd-Karte wurde schon für Echtzeitanwendungen konstruiert, nur nicht >mit dem SPI-Modus. SDIO ist mit 4parallelen Datenleitungen wesentlich >schneller. Das WearLevelling interessiert es einen Scheissdreck von welcher Schnittstelle die Daten kommen. Das haut einfach rein.
Grundschüler schrieb: > SDIO ist mit 4parallelen Datenleitungen wesentlich schneller. Die Geschwindigkeit ist mit 1MByte/ s ziemlich harmlos. Es geht um die Latenz beim Bank switching und so. Grundschüler schrieb: > Der Sinn des ganzen DMA-Aufwandes für einen Cortex-M3 Wer redet von M3? Es geht um einen STM32F373, Cortex-M4F, der hat kein SDIO. Den brauchen wir wegen dem SDADC. SDADC & SDIO in einem STM32 gibt's nicht. Und ein zweites Board mit STM32F4 daneben passt nicht ins Gehäuse, außerdem ist die Platine mit F3 und Peripherie schon fertig entwickelt. dummy schrieb: > Das haut > einfach rein. Was macht das denn da solange?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.