Hallo zusammen,
ich möchte Daten von einem µC auf eine SD-Karte speichern.
Die Roh-Daten sind 100 16Bit Variablen, die in einem 10ms Raster
gespeichert werden sollen.
Wie groß ist der Overhead, wenn ich FAT16 verwende?
Welchen Datendurchsatz bzw. welche Taktrate benötige ich dafür auf der
SPI?
Über Informationen von Erfahren SD-Karten-Programmierer würde ich mich
sehr freuen!
Liebe Grüße
Thomas
thomas schrieb:> Die Roh-Daten sind 100 16Bit Variablen, die in einem 10ms Raster> gespeichert werden sollen.
Also 200 Byte, 100 mal pro Sekunde. Das macht 20 kByte pro Sekunde.
Das ist eine Datenrate, die eine SD-Karte recht problemlos schaffen
sollte, auch ein 1-Bit-SPI-Ansteuerung. Die sollte natürlich nicht an
die 20 kByte pro Sekunde angepasst sein, sondern entsprechend schneller,
was halt Dein µC so sinnvoll an der SPI-Schnittstelle zustandebekommt.
20 kByte/sec sind 72 MByte pro Stunde, damit hält Deine SD-Karte maximal
27 Stunden lang (denn bedingt durch FAT16 sind mehr als 2 GB nicht
möglich, bei Mehrbedarf müsstest Du dann eine SDHC-Karte und FAT32
verwenden).
Danke für die schnelle Antwort!
Dass die SPI vom Microcontroller nicht an die 20kByte pro Sekunde
angepasst werden sollte, ist mir klar - sind ja auch nur die
Rohdaten...da kommt ja noch der Overhead des Dateisystems (FAT16 vs.
FAT32) und der von den Kommandos, etc. der SD-Karte dazu. Doch wie groß
ist der ungefähr?
Bezüglich der Taktrate der SPI mache ich mir zwar keine Sorgen, ich
möchte aber wissen, wie schnell diese mindestens sein sollte.
LG
@ thomas (Gast)
>Rohdaten...da kommt ja noch der Overhead des Dateisystems (FAT16 vs.>FAT32) und der von den Kommandos, etc. der SD-Karte dazu. Doch wie groß>ist der ungefähr?
Ich hab vor eineiger Zeit mit dem AVR@16 MHz und dem FATFs von ElmCHAN
bis zu 500kB/s Schreibgeschwindigkeit erreicht (reiner Schreibtest ohne
sonstige Funktion). In der realen Applikation habe ich 22kB/s
geschrieben, das lief auch problemlos. Nebenbei wurde noch DMX512 mit
voller Bandbreite empfangen.
@ runtastic (Gast)
>Elm Chan sagt dazu folgendes:
Ich glaube aber, dass diese Test mit einer älteren Version gemacht
wurden, die noch deutlich schlechteres Caching hatte. Denn bei meinen
Test waren die kleinen Blockgrößen nahezu genausoschnel wie die Großen!
thomas schrieb:> Hallo zusammen,>> ich möchte Daten von einem µC auf eine SD-Karte speichern.> Die Roh-Daten sind 100 16Bit Variablen, die in einem 10ms Raster> gespeichert werden sollen.
Verlasse Dich nicht auf das Zeitverhalten von SD-Karten! Der interne
Controller kann sich zu einer für Dich nicht vorhersehbaren Zeit eine
Auszeit von mehreren 100ms für interne Verwaltungsgeschichten, Wear
Levelling, etc nehmen.
fchk
@ der alte Hanns (Gast)
>Folglich empfiehlt es sich, einen Ringpuffer von ca. 10 kB anzulegen.
Stimmt, ich hab bei mir ~50kB, externer SRAM. Ist leider real auch
nötig, weil es ab und an zu längeren Aussetzern kommt, das ist aber vom
SD-Kartentyp abhängig. :-(
Beitrag "SD-Karte mit sporadischen Schlafpausen?"
Die 10 kB bezogen sich auf die Anforderung von thomas.
Von dem einen Dutzend verschiedener Karten, die ich bislang hatte,
pausierte keine länger als 350 ms; bei meinen 95 kB/s ist's aber ein
Ärgernis, ich bräuchte ja ca. 33 kB Speicher.
Danke für die vielen Antworten - das hilft mir schon viel weiter.
Frank K. schrieb:> Verlasse Dich nicht auf das Zeitverhalten von SD-Karten! Der interne> Controller kann sich zu einer für Dich nicht vorhersehbaren Zeit eine> Auszeit von mehreren 100ms für interne Verwaltungsgeschichten, Wear> Levelling, etc nehmen.
Das RTOS auf dem µC, an den ich die SD-Karte anschließen möchte, läuft
schon. Das Zeitfenster von 10ms kann ich relativ genau einhalten.
Wie sieht es denn nun mit dem Overhead für das Schreiben bei FAT16/32
aus? Hat noch keiner Erfahrungen damit gemacht oder lässt sich das nicht
so allgemein sagen?
@ thomas (Gast)
>Wie sieht es denn nun mit dem Overhead für das Schreiben bei FAT16/32>aus? Hat noch keiner Erfahrungen damit gemacht oder lässt sich das nicht>so allgemein sagen?
Darum kümmert sich die FAT-Lib deines Vertrauens. Aber grob geschätzt
ist das nicht soooo viel, wenn man bedenkt, dass man mit 500kB/s
schreiben kann, der Bus aber maximal ~1,1 MB/s übertragen kann, bezogen
auf mein Projekt. Beim Lesen kam ich auf ~800kB/s. Not bad!
Mit diesem Wissen würde ich NIEMALS wieder darüber nachdenken, eine
SD-Karte ohne FAT zu nutzen. Lohnt sich nicht.
thomas schrieb:> Frank K. schrieb:>> Verlasse Dich nicht auf das Zeitverhalten von SD-Karten! Der interne>> Controller kann sich zu einer für Dich nicht vorhersehbaren Zeit eine>> Auszeit von mehreren 100ms für interne Verwaltungsgeschichten, Wear>> Levelling, etc nehmen.
Das kann man nur sehr dick unterstreichen!
> Wie sieht es denn nun mit dem Overhead für das Schreiben bei FAT16/32> aus? Hat noch keiner Erfahrungen damit gemacht oder lässt sich das nicht> so allgemein sagen?
Das ist doch simpel: Pro Cluster geschriebener Daten ist ein Update der
FAT nötig. Wie häufig das passiert (passieren muß), hängt logischerweise
direkt von der Clustergröße ab. Zusätzlich muß spätestens in diesem
Moment die Suche nach dem nächsten freien Cluster erfolgen, was im worst
case ein Lesen fast der gesamten FAT erfordert.
Zusätzlich wird "irgendwann" auch immer mal wieder der
Verzeichniseintrag bezüglich der Dateigröße und der Zugriffszeit
aktualisiert. Das ist allerdings Implementierungsabhängig. Manche
Implementierungen schreiben schon bei einem Flush() andere erst bei
einem Close(), manche aber auch zwischendurch immer mal wieder.
Der Code ist doch quelloffen. Schau halt einfach nach, wie er sich
verhält. Vermutlich ist das sogar konfigurierbar, genauso wie die
Allozierungsstrategie.
Tja, ist schon Scheiße, wenn man copy&paste-Code verwendet, den man
nicht versteht, isn't it?
thomas schrieb:> Danke für die vielen Antworten - das hilft mir schon viel weiter.>> Frank K. schrieb:>> Verlasse Dich nicht auf das Zeitverhalten von SD-Karten! Der interne>> Controller kann sich zu einer für Dich nicht vorhersehbaren Zeit eine>> Auszeit von mehreren 100ms für interne Verwaltungsgeschichten, Wear>> Levelling, etc nehmen.>> Das RTOS auf dem µC, an den ich die SD-Karte anschließen möchte, läuft> schon. Das Zeitfenster von 10ms kann ich relativ genau einhalten.
Die Karte aber nicht. Die kann irgendwann mal die Schreibfunktion für
beispielsweise eine halbe Sekunde blockieren. In dieser halben Sekunde
läuft dann kein IO. Und wann die Karte das macht, und wie lange sie dann
mit sich selber beschäftigt ist, kannst Du nicht vorhersagen.
Harte Echtzeit geht anders. ZB mit einem nackten NAND-Flash. Das hat
keinen Controller, da hast Du alles in der Hand.
fchk
@ Frank K. (fchk)
>Die Karte aber nicht. Die kann irgendwann mal die Schreibfunktion für>beispielsweise eine halbe Sekunde blockieren.
Jain. Das hängt auch davon ab, wie die Zugriffsfunktion gemacht wird.
>In dieser halben Sekunde>läuft dann kein IO.
Nanana, es gibt immer noch Interrupts! Und Päemtive RTOSe. Klar muss man
dann beim SD-Zugriff etwas mehr Aufwand treiben (atomarer Zugriff auf
SPI etc.) aber das ist kein unlösbares Problem.
>Harte Echtzeit geht anders.
Sicher, indem man mal den Tunnelblick überwindet und elementare
Grundlagen anwendet.
> ZB mit einem nackten NAND-Flash. Das hat>keinen Controller, da hast Du alles in der Hand.
Ist bei SD-Karte kein bisschen anders!
der alte Hanns schrieb:> Yeah - on the other hand, I don't understand my own brain, but try to> use it none the less.
You can do it this way until it wents wrong. But it'll be too late to
choose a better strategy when you reached that point...
Allenfalls waere noch interessant gewesen, wieviele Daten geschrieben
werden muessen, ob das Flasch abziehbar sein muss, oder immer eingebaut
bleibt, usw.
Hui schrieb:> Allenfalls waere noch interessant gewesen, wieviele Daten geschrieben> werden muessen, ob das Flasch abziehbar sein muss, oder immer eingebaut> bleibt, usw.
Da die Karte fix eingebaut wird, habe ich mich jetzt dafür entschieden,
auf das Dateisystem zu verzichten.
Die Daten werde ich über die serielle Schnittstelle an den PC schicken.
Habe ich richtig verstanden, dass ich für die initalisierung der
SD-Karte im SPI-Modus folgendes machen muss:
- SPI-CLK auf 400kHz setzen
- 80-CLK-Cycles ausgeben
- CMD0 mit richtiger CRC senden
bis idle-bit 'clear'
- CMD55 (Next command will be application-specic)
- ACMD41 (Initialize the card)
- SPI-CLK auf maximum (<25MHz)
Um dann 512 byte Daten zu schreiben:
- CMD24 + 32-bit Block Address + CRC (wird nicht von der Karte geprüft)
- 0xFE senden (Startblock)
- 512 byte Daten senden
- MOSI auf HIGH (0xFF senden) bis MISO auf LOW
Bezüglich der Adresse: Darf ich gleich von der Adresse 0x00 weg
schreiben?
Danke und LG
Dieser thread endet leider mit einer unbeantworteten Fragestellung. Kann
man bei einer sd-Karte den ganzen Fat-Überbau weglassen und wie von
thomas dargestellt schnell sequentiell schreiben?
Falk Brunner schrieb:> Ich hab vor eineiger Zeit mit dem AVR@16 MHz und dem FATFs von ElmCHAN> bis zu 500kB/s Schreibgeschwindigkeit erreicht
Kannst du erklären wie du das hinbekommen hast? Etwa so wie thomas dies
im letzten Beitrag dargestellt hat?
Gibt es andere Speichermedien, die zum Zwischenspeichern großer
Datenmengen besser geeignet sind (ca.1Mbyte, <5sec)? Die ARM-boards
haben ja einen USB-Anschluss. Wenn man den zum Speichern von Daten
nutzt, wie hoch ist dann der Datendurchsatz.
@ leluno (Gast)
>Dieser thread endet leider mit einer unbeantworteten Fragestellung. Kann>man bei einer sd-Karte den ganzen Fat-Überbau weglassen und wie von>thomas dargestellt schnell sequentiell schreiben?
Das kann man. Aber es löst nicht das Problem, dass die SD-Karte ab und
an mal ein paar hundert ms Gedenkpause machen darf, weil sie neue
Sektoren löscht etc. Gute Karten verteilen die Gedenkpausen auf mehrere
kleine Pause, schlechtere Karten machen auch mal größere Pausen bis zu
1s!
>> Ich hab vor eineiger Zeit mit dem AVR@16 MHz und dem FATFs von ElmCHAN>> bis zu 500kB/s Schreibgeschwindigkeit erreicht>Kannst du erklären wie du das hinbekommen hast?
Einfach schreiben. Klingt komisch, ist aber so ;-)
>Etwa so wie thomas dies>im letzten Beitrag dargestellt hat?
Kann sein, die Low Level "Drecksarbeit" erledig für mich die FAT32 Lib
von ELM Chan. Ich rufe nur f_write() auf.
leluno schrieb:> ergibt 341.333 bytes/sec, wäre gerade noch ausreichend
und passt somit auch mit den Benchmark-Ergebnissen von elm chan überein.
Ich habe es auch mal selbst getestet, 2MB in 2kB Blöcken braucht 5.22
Sekunden -> 392kB/s. (PIC24 mit 32MHz und Transcend 2GB micro-SD card
TS2GUSD).
Wenn du es noch schneller haben willst und bspw. die 2MB/s oder mehr
nutzen willst, die eine SD-Karte schaffen sollte, so musst du dich vom
kostenlosen SPI-Interface lossagen und zum lizenzpflichtigen SDIO
wechseln. Einige ARM Mikrocontroller haben ein SDIO Interface integriert
und es gibt einige Beispiele in Verbindung mit FatFS, bspw.
http://mikrocontroller.bplaced.net/wordpress/?page_id=621
Die Kamera-Hersteller müssen ja auch irgendwie ihre 20MB/s Filme auf
eine SD-Karte ablegen können.
Ein andere Möglichkeit ist keine SD-Karte sondern ein fest installierter
NAND Speicher.
Das scheint die Stelle beim Elm-Chan-Code zu sein, wo eine DMA einsetzen
könnte: Es werden 512Datenbytes und 2CRCBytes gesendet. Der ARM wartet
dann auf die Bestätigung der Karte. Wenn man diese Bestätigung in einen
Interrupt legt, könnte der ARM in der Zwischenzeit etwas anderes machen,
Gibt es sowas schon fertig als code?
Frank M. schrieb:> SPI-Interface lossagen und zum lizenzpflichtigen SDIO
meine 8Gb-SD-Karte hat nur 8 Kontakte. Parallelen Datentransfer von
4bits scheint es nicht mehr zu geben.
Gibt es Nand-Speicher, die man noch selber löten kann
(Streifenraster+Lötpistole)?
leluno schrieb:> Frank M. schrieb:>> SPI-Interface lossagen und zum lizenzpflichtigen SDIO> meine 8Gb-SD-Karte hat nur 8 Kontakte. Parallelen Datentransfer von> 4bits scheint es nicht mehr zu geben.
Entweder du kaufst dir eine SD-Karte mit 4-bit Modus oder du schreibst
den vorhanden fertigen 4-bit Code von elm-chan für ARM der DMA verwendet
um, sodass er im 1-bit modus arbeitet. (siehe das lpc23xx Projekt im
samples ordner von FatFS). Das sollte machbar sein, zumal die SD-Karte
zu beginn im 1-bit Modus arbeitet und dann auf 4-Bit per Software
umgeschalten werden muss.
Natürlich kannst du dir auch überlegen ob du auch wirklich diese hohe
Datenrate brauchst und nicht vielleicht das Speichern effizienter
gestalten kannst bzw. sogar komprimieren kannst. Kommt ganz auf deine
Daten an.
Frank M. schrieb:
Danke für die Antwort. Ich habe mal eine 9Pin-Karte bestellt. Die
LPC23xx haben eine spezielle MCI-Schnittstelle. Den Elm-Code auf
4GPIO-Pins umzuschreiben dürfte schwierig werden. Das wäre dann eine Art
Software-4bit-spi. Bei 100Mhz Takt und DMA aber nicht völlig
hoffnungslos.
leluno schrieb:> Frank M. schrieb:>> Danke für die Antwort. Ich habe mal eine 9Pin-Karte bestellt. Die> LPC23xx haben eine spezielle MCI-Schnittstelle. Den Elm-Code auf> 4GPIO-Pins umzuschreiben dürfte schwierig werden. Das wäre dann eine Art> Software-4bit-spi. Bei 100Mhz Takt und DMA aber nicht völlig> hoffnungslos.
Also ich habe noch nie mit der MCI-Schnittstelle oder gar einem ARM
gearbeitet, aber reicht nicht einfach schon den Wide Modus nicht zu
aktivieren?
Im Datenblatt
http://www.nxp.com/documents/user_manual/UM10211.pdf
auf Seite 498 ist das MCIClock Register beschrieben. Dort kannst du auf
den Wide Bus umschalten, was im elm-chan code am Ende der
Initialisierung getan wird. Im Standard mode wird anscheinend nur DATA0
verwendet, also 1-Bit, anstatt 4-Bit.
Auf Seite 493 steht nochmal genaueres zu den zwei Bus Modi.
Es kann sein, dass noch ein paar andere Code Änderungen vorgenommen
werden müssen, aber ein 1-Bit MCI Interface muss nicht per Software
implementiert werden da es in Hardware vorliegt.
Die Idee ist gut. Ich war gedanklich schon beim 4bit-Modus, weil- wenn
der funktionieren würde, das praktisch einen parallelen Speicher
ersetzen würde. Danke für den Hinweis!