Liebe Gemeinde, ich habe vor einen SD/USB Datenlogger zu bauen, bzw. schon einiges gebaut, allerdings gerade auf eine Grenze gestoßen, bei der ich nicht einschätzen kann, ob es an meinem Programm oder an der generellen Idee scheitert. Zunächst zum System: ATmega1284P, 16 MHz. Ich habe einen kontinuierlichen Datenstrom bestehend aus 10 Bytes, die in 500 µs Zeitabstand kommen. Das sind ca. 20 kBytes/s, für eine SD-Karte oder USB-Stick also kein Problem. SD-Kartenlesegerät ist über SPI mit voller Bandbreite von f/2, also 8 MHz angeschlossen. Ich habe das FatFs-Modul implementiert und festgestellt, dass es anscheinend die Daten in der Funktion f_write puffert bis 512 Bytes voll sind, dann werden diese geschrieben. Das Schreiben ist in FATFS über Polling implementiert (loop_until_bit_is_set(SPSR,SPIF)), somit verbleibt das Hauptprogramm wenn ein Block geschrieben wird ca 50 ms in der Funktion f_write und ich verliere die Daten aus dem Datenstrom. Ich könnte diese zwar puffern, deren Verarbeitung benötigt aber auch eine gewisse Zeit, so dass insgesamt ich mir nicht sicher bin, ob der Puffer überhaupt geleert werden kann, wenn zur Datenverarbeitung zusätzlich das Schreiben auf die Karte dazukommt. Auch der Programmumbau wäre eine Heidenarbeit. Deshalb bin ich hier und habe auch ein Paar Fragen zusammengestellt: 1) gibt es einen low level Unterbau von FATFS, der nicht mit Polling, sonder über SPI-Interrupte funktioniert? So dass die Daten unabhängig vom Hauptprogramm durch die SPI ISR rausgeschoben werden? 2) gibt es überhaupt eine Möglichkeit seriellen Datenstrom direkt vom µC in eine SD-Karte (FAT32-Datei) zu schreiben, so dass für das Schreiben einer Sequenz von 10 Bytes weniger als 250-500 µs benötigt wird? Beim Petit FAT File System Module, welches soweit ich es einschätzen kann wirklich einzelne Bytes schreibt, steht 0,38kBytes/s für ein Byte, also deutlich langsamer als von mir benötigt. 3) Nach Stöbern im Forum habe ich Verweise auf OpenLog und VDrive2 gefunden. OpenLog ist etwas zu langsam, bei VDrive2 steht eine maximale Baudrate von 3.000.000. Wäre VDrive2 (Farnell 23,26) das Richtige für mein Vorhaben? Soweit ich es verstanden habe schreibt man nur Textbefehle über SPI (was sehr schnell geht und ohne weiteres über SPI-Interrupt implementiert werden kann), z.B. WRF·<dword> data, mit <dword>=Anzahl an data Bytes gefolgt von purem Datenstrom, und das war's. Natürlich davor Datei/Verzeichnis anlegen usw. Grüße Tycho
@ Tycho B. (asellus) >Zunächst zum System: ATmega1284P, 16 MHz. Ich habe einen >kontinuierlichen Datenstrom bestehend aus 10 Bytes, die in 500 µs >Zeitabstand kommen. Das sind ca. 20 kBytes/s, für eine SD-Karte oder >USB-Stick also kein Problem. Ja. >SD-Kartenlesegerät ist über SPI mit voller Bandbreite von f/2, also 8 >MHz angeschlossen. Ich habe das FatFs-Modul implementiert und >festgestellt, dass es anscheinend die Daten in der Funktion f_write >puffert bis 512 Bytes voll sind, dann werden diese geschrieben. Ja, siehe Doku. > Das >Schreiben ist in FATFS über Polling implementiert >(loop_until_bit_is_set(SPSR,SPIF)), somit verbleibt das Hauptprogramm >wenn ein Block geschrieben wird ca 50 ms in der Funktion f_write Glaub ich nicht. Sooo lange dauert das nicht. Ausserdem sollte man beachten, wie man Schreibzugiffe verbessern kann. http://elm-chan.org/fsw/ff/en/lseek.html Das Zauberwort heißt Preallocation und CLMT. > und ich >verliere die Daten aus dem Datenstrom. Ich könnte diese zwar puffern, >deren Verarbeitung benötigt aber auch eine gewisse Zeit, so dass >insgesamt ich mir nicht sicher bin, ob der Puffer überhaupt geleert >werden kann, wenn zur Datenverarbeitung zusätzlich das Schreiben auf die >Karte dazukommt. Auch der Programmumbau wäre eine Heidenarbeit. Muss aber sein. Wäre mit dem richtigen Design (tm) nicht passiert. Dein Datenstrom muss per Interrupt verarbeitet und in einen FIFO geschrieben werden. Dann klappt das auch mit FATFS und der SD-Karte. Been there, done this. >1) gibt es einen low level Unterbau von FATFS, der nicht mit Polling, >sonder über SPI-Interrupte funktioniert? Nein. > So dass die Daten unabhängig >vom Hauptprogramm durch die SPI ISR rausgeschoben werden? Nein. >2) gibt es überhaupt eine Möglichkeit seriellen Datenstrom direkt vom µC >in eine SD-Karte (FAT32-Datei) zu schreiben, so dass für das Schreiben >einer Sequenz von 10 Bytes weniger als 250-500 µs benötigt wird? Nicht wirklich. Es gibt ein paar Stunts hier im Forum, wo es extrem verzahnt wird (Messung und SD-karte schreiben), das willst du aber nicht wirklich. Und nötig ist es auch nicht. > Beim >Petit FAT File System Module, welches soweit ich es einschätzen kann >wirklich einzelne Bytes schreibt, steht 0,38kBytes/s für ein Byte, also >deutlich langsamer als von mir benötigt. Vergiss das, das ist deutlich schlechter, eben weil der Zwischenpuffer fehlt. Ich hab vor einiger Zeit einen DMX-Rekorder gebaut, der sendet/empfängt 250kBit/s per UART-Interrupt und schreibt die Daten in einen FIFO. In der Hauptschleife wird FATFS und die vorgelagerte Verarbeitung (Statemachine) alle 10ms per Timer aufgerufen. Damit kann man problemlos die 22kB/s schreiben oder auch lesen, CPU-Last im Mittel bei 30% (AVR @16MHz).
Falk Brunner schrieb: > Glaub ich nicht. Sooo lange dauert das nicht. Ausserdem sollte man > beachten, wie man Schreibzugiffe verbessern kann. Jetzt bekomme ich mit preallocation
1 | res=disk_initialize(0); |
2 | res = f_mount(&FatFs, "", 0); |
3 | res = f_open(&Fil, "datei.txt", FA_CREATE_ALWAYS | FA_WRITE ); |
4 | res = f_lseek(&Fil, 10000); |
5 | res = f_lseek(&Fil, 0); |
6 | |
7 | ...
|
8 | |
9 | OSZILOSCOPE_LINE_HIGH(); |
10 | res=f_write(&Fil, tempbuffer, 8192, &bw); |
11 | OSZILOSCOPE_LINE_LOW(); |
eine Dauer von ca. 280 ms. Das sind 29 kByte/s, ich komme also an deine 31 kByte/s ran (du meintest doch kBit/s?) Scheint mir sehr langsam zu sein, allerdings kann es auch an der Karte liegen. Werde noch mit CLMT rumspielen, aber das ist eher um f_lseek zu beschleunigen? Falk Brunner schrieb: > CPU-Last im Mittel bei > 30% (AVR @16MHz) Ich muss ein von extern kommendes SENT-Protokoll dekodieren (Block aus 9 Nibbles alle 300 µs kommend, darf keinen einzigen verlieren), habe auch eine statemachine, absoluten timer (16 MHz) mit 48 bit Länge, Tasteneingaben (entprellt), UART Datenbus (250k), der Befehle empfängt und Daten weitersendet (2 x FIFO) und zwei CRC-Auswertungen. Meine CPU-Last liegt ohne FATFS bei ca. 50%. Die von mir benötigten 20kByte/s sind aber mehr als 50% von maximal 29 kByte/s, ich glaube also, dass der Puffer überläuft.
Tycho B. schrieb: > 1) gibt es einen low level Unterbau von FATFS, der nicht mit Polling, > sonder über SPI-Interrupte funktioniert? So dass die Daten unabhängig > vom Hauptprogramm durch die SPI ISR rausgeschoben werden? Andere Controller können SPI oder MCI per DMA ansteuern. Hat ein AVR natürlich nicht, jedenfalls kein herkömmlicher. (Xmega schon) > 2) gibt es überhaupt eine Möglichkeit seriellen Datenstrom direkt vom µC > in eine SD-Karte (FAT32-Datei) zu schreiben, so dass für das Schreiben > einer Sequenz von 10 Bytes weniger als 250-500 µs benötigt wird? Beim > Petit FAT File System Module, welches soweit ich es einschätzen kann > wirklich einzelne Bytes schreibt, steht 0,38kBytes/s für ein Byte, also > deutlich langsamer als von mir benötigt. SD_Karten erreichen ihre volle Geschwindigkeit erst per MCI, also dem nativen MMC-Interface, das mit 4 Bit Datenbreite betrieben werden kann. Schade, das gibts bei AVR auch nicht. Nimm mal einen geeigneteren Controller, dann erledigen sich viele Probleme quasi von alleine. So ein SAM3S wäre angemessen. fchk
@ Tycho B. (asellus) >Jetzt bekomme ich mit preallocation >res=f_write(&Fil, tempbuffer, 8192, &bw); >OSZILOSCOPE_LINE_LOW(); >eine Dauer von ca. 280 ms. Das sind 29 kByte/s, ich komme also an deine >31 kByte/s ran (du meintest doch kBit/s?) 280ms für 8kB? Eher nicht. Wie misst du das? Mit dem Oszi und einem IO-Pin? Ich hab damals selbst unter ungünstigen Bedingungen 170kB/s (KiloBytes/s) gemessen. Die 22kB/s waren problemlos drin. > Scheint mir sehr langsam zu >sein, allerdings kann es auch an der Karte liegen. Werde noch mit CLMT >rumspielen, aber das ist eher um f_lseek zu beschleunigen? Beides. >Die von mir benötigten 20kByte/s sind aber mehr als 50% von maximal 29 >kByte/s, ich glaube also, dass der Puffer überläuft. Da klemmt es irgendwo anders.
Falk Brunner schrieb: > Wie misst du das? Mit dem Oszi und einem > IO-Pin? ja Falk Brunner schrieb: > Da klemmt es irgendwo anders. Mit einer an Sicherheit grenzender Wahrscheinlichkeit. :) Habe mit einer anderen Karte probiert, 20 ms => 400 kByte/s, lag also an der Karte. Die langsame Karte: 2GB SD-C02G microSD, die schnelle: SanDisk 512 MB (AX0502YW) Eventuell habe ich die Einstellungen in der ffconf.h vermurkst. Jedoch liefert auch die FATFS-Seite verschiedene Performancewerte für unterschiedliche Karten. Ich denke mal der Entwickler wusste schon was er macht, als er die Benchmarks aufgenommen hat. Eine kartenabhängige Anwendung ist sehr ungünstig bis nicht akzeptabel. Jetzt ärgere ich mich, dass ich dem Punkt nicht mehr Beachtung geschenkt habe, dachte, dass die schlechten Performancewerte Ausnahmen sind. Jetzt Nicht schrieb: > Was soll ein seek() ? steht in http://elm-chan.org/fsw/ff/en/lseek.html in den Kommentaren des mittleren Codeblocks. Der cluster allocation delay wird vermieden.
> Jetzt Nicht schrieb: >> Was soll ein seek() ? >steht in http://elm-chan.org/fsw/ff/en/lseek.html in >den Kommentaren des mittleren Codeblocks. Der cluster >allocation delay wird vermieden. Sollte man sowieso vermeiden. Einfacher ist es auf dem PC ein (1) File zu schreiben. Und nachher dieses File zu ueberschreiben.
Tycho B. schrieb: > Jetzt ärgere ich mich, dass ich dem Punkt nicht mehr Beachtung geschenkt > habe, dachte, dass die schlechten Performancewerte Ausnahmen sind. Ich sehe keine schlechten Performance Werte bei Deinen Karten. Ich habe schon Karten gesehen, die beim Schreiben gefühlt 1 Sekunde abtauchen, das war aber eine Karte aus dem Supermarkt. Übrigens werden die Wartezeiten länger je öfter auf die Karte geschrieben wurde, Stichwort Wear-leveling. Wenn man richtig schnell auf SD-Karten schreiben muss, braucht man multi-Block Writes und einen großen (ich verwende 16kB) Puffer. Die dafür benötigte Infrastruktur ist aber nicht trivial, ich habe das als Cache unterhalb des Dateisystems (also in disk_write) implementiert.
@Jetzt Nicht (jetztnicht) >>steht in http://elm-chan.org/fsw/ff/en/lseek.html in >>den Kommentaren des mittleren Codeblocks. Der cluster >>allocation delay wird vermieden. >Sollte man sowieso vermeiden. Einfacher ist es auf dem PC ein (1) File >zu schreiben. Und nachher dieses File zu ueberschreiben. Unsinn. Wenn man mal die verlinkte Seite LESEN und so Gott will auch VERSTEHEN würde, dann KÄME man auf die Idee, dass mit den dort dargestellten Verfahren das Ganze deutlich flexibler handhabbar ist.
@Jim Meba (turboj) >Wenn man richtig schnell auf SD-Karten schreiben muss, braucht man >multi-Block Writes und einen großen (ich verwende 16kB) Puffer. Die >dafür benötigte Infrastruktur ist aber nicht trivial, ich habe das als >Cache unterhalb des Dateisystems (also in disk_write) implementiert. FATFS kann das auch schon von Haus aus, allerdings muss man es dann mit großen Datenblöcken füttern, wofür natürlich wieder viel RAM benötigt wird. Also dicker ARM irgendwas oder ein AVR mit externem SRAM oder was ähnliches. Aber für die vom OP angepeilten 20kB/s reicht der kleine 512 Byte Puffer im FATFS locker. Damit schafft man bei 8 Mbit SPI Speed ~170kB/s beim Lesen wie Schreiben. Beitrag "Re: SD-Karte Speichergeschwindigkeit" Das waren aber reine Tests mit 32kB Blöcken beim Aufruf von f_write().
:
Bearbeitet durch User
Jim Meba schrieb: > Ich sehe keine schlechten Performance Werte bei Deinen Karten. Ist relativ. 40 kByte/s ist für die Anwendung einfach zu langsam. Auch der Speicher des µC ist begrenzt, 16k habe ich nicht. Deswegen habe ich auch nach Erfahrungen zu VDrive2 / Alternativen gefragt. Jim Meba schrieb: > Wenn man richtig schnell auf SD-Karten schreiben muss Da muss man doch eh SPI verlassen, und parallel schreiben, deswegen VDrive2.
Falk Brunner schrieb: > Aber für die vom OP angepeilten 20kB/s reicht der kleine 512 > Byte Puffer im FATFS locker. Damit schafft man bei 8 Mbit SPI Speed > ~170kB/s beim Lesen wie Schreiben. Hast du es mit mehreren unterschiedlichen Karten versucht? Wie bereits geschrieben, ich kriege mit einer Karte 400 kB/s, mit der anderen 30 kB/s. (nicht am kontinuierlichen Datenstrom gemessen, sondern mit Oszi-Pin, und einmaliger Block von 8192 Bytes)
@ Tycho B. (asellus) >> Aber für die vom OP angepeilten 20kB/s reicht der kleine 512 >> Byte Puffer im FATFS locker. Damit schafft man bei 8 Mbit SPI Speed >> ~170kB/s beim Lesen wie Schreiben. >Hast du es mit mehreren unterschiedlichen Karten versucht? Ja. > Wie bereits >geschrieben, ich kriege mit einer Karte 400 kB/s, mit der anderen 30 >kB/s. Dann hat die eine Karte einen erheblichen Defekt.
Ich habe die Lib von @Falk mal angepasst. Was derzeit noch fehlt ist formatierung MIT nicht 512 bytes, Also karten MIT mehr als 4 GB und multi block Unterstützung sowie Transaktion safe fat. Implementiert ist fat32+ Also files mit>4gb sind kein Problem. Wenn die Karte kein einzelnen block löschen kann, wie bei schnellen karten üblich, Dann können derzeit keine daten gelöscht werden. Achso, nur 8.3 Namen werden verwendet und für ein fat32 system formatiert Mit fat16 oder fat12 braucht es eine besondere Formatierung. Limit sind 2T. Wenn du willst kann ich eine pre alpha Version hochladen. Auch wenn es mit interrupt funktionieren würde ist es derzeit ohne und es ist gedacht dass ein Scheduler die Datensammlung im Interrupt erledigt und in ein fifo rein schreibt. Karten funktionieren alle, mbr ist implementiert, Kein GPT und derzeit auch nur die erste partition. Optionaler basic interpreter ist auch dabei, Ist aber derzeit nur pre alpha.
chris schrieb: > Ist aber derzeit nur pre alpha. Hallo chris, danke für das Angebot. Verstehe ich das richtig, dass deine Anpassung zu keinem Zeitpunkt das Hauptprogramm für länger als 500µs unterbricht? Oder muss ich die kontinuierlich kommenden Daten puffern, um ein Zeitfenster für die Übertragung zu verschafen? Das war schon der Vorschlag von Falk.
> Hast du es mit mehreren unterschiedlichen Karten versucht? Wie bereits > geschrieben, ich kriege mit einer Karte 400 kB/s, mit der anderen 30 > kB/s. Elms FatFS liegt bei mir so mit unterschiedlichen Karten bei 200kB/s. Aber man kann sich nicht drauf verlassen. Es kommt immer mal vor das eine Karte zwischendurch mal meint etwas anderes machen zu muessen und dann dauert es ploetzlich sehr viel laenger. Man braucht also einen Buffer wo man notfalls fuer 1s die Daten speichern. Olaf
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.