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.
Elm Chan sagt dazu folgendes: http://elm-chan.org/fsw/ff/img/rwtest.png http://elm-chan.org/fsw/ff/img/rwtest2.png
@ 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
Folglich empfiehlt es sich, einen Ringpuffer von ca. 10 kB anzulegen.
@ 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?
Yeah - on the other hand, I don't understand my own brain, but try to use it none the less.
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.
bei timetick 10 ms wäre das dann dieser code:
1 | res=f_mount(0, &fs); |
2 | res = f_open( &fsrc , Dateiname , FA_CREATE_NEW | FA_WRITE); |
3 | Timer=0; |
4 | res = f_write(&fsrc, bufferx, (10240), &br); |
5 | tmp=Timer; |
6 | f_close(&fsrc); |
7 | lgw(2,1,"Dauer ms: "); |
8 | li(10240*100/tmp); |
leluno schrieb: > res=f_mount(0, &fs); > res = f_open( &fsrc , Dateiname , FA_CREATE_NEW | FA_WRITE); > Timer=0; > res = f_write(&fsrc, bufferx, (10240), &br); > tmp=Timer; > f_close(&fsrc); > lgw(2,1,"Dauer ms: "); > li(10240*100/tmp); ergibt 341.333 bytes/sec, wäre gerade noch ausreichend
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.
:
Bearbeitet durch User
1 | else { /* Multiple sector (max 4096bytes) write */ |
2 | if (CardType & CT_SDC) send_cmd(ACMD23, count); /* Predefine number of sectors */ |
3 | if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ |
4 | do { |
5 | if (!xmit_datablock(buff, 0xFC)) break; |
6 | buff += 512; |
7 | } while (--count); |
8 | if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */ |
9 | count = 1; |
10 | }
|
11 | }
|
12 | deselect(); |
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.
:
Bearbeitet durch User
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!
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.