Hallo zusammen, eine kurze Frage an die, die es vielleicht direkt wissen oder schonmal gemessen haben: elm-chans FatFs Bibliothek: Datensenden vom uC auf die SD-KArte Wir gehen der Einfachheit halber davon aus das alles perfekt angebunden ist und funktioniert. Das ganze findet über einen normalen SPI statt: Frequenz aktuell 24 MHz. Das senden von Datenpaketen ohne irgendwelchen Overhead sollte jetzt ja: Daten(Bytes) 8 1/24 MHz = Dauer der Datenübertragung. also gehen wir von 500 Bytes aus, sind es ca 170 us reine Datenübertragungsdauer. Gemessen am Oszi dauert die ganze Routine als mit elm chan overhead ca 8 ms. Jetzt bin ich mir nicht sicher ob das normal ist, dass der Overhead der SD-Karte soviel Zeit in anspruch nehmen sollte, oder ob ich irgendetwas falsch eingestellt oder programmiert habe. SPI-clock habe ich am Oszi überprüft, der stimmt. Die Datenübertragung funktioniert auch vollkommen korrekt, lediglich die Dauer dieser Schreibvorgänge machen mich etwas stutzig, ich hätte es gerne schneller, gerne einen Faktor 10 :) Dankeschön schonmal für das lesen und ich freue mich auf jegliche sachdienlichen Hinweise. PS: Ich habe mir jetzt vergleichsthreads durchgelesen und bei elmchan nochmal im forum nachgelesen bzgl. speed. Also Fazit dort, wenn ich das richtig gelesen habe: Je größer die Dateien die man schreiben will, desto größer der Datenumsatz pro Sekunde. Also besser 100kB schreiben auf einmal anstelle von 100 Byte. Allerdings weiss keiner so recht wo man den Datenbuffer umstellen kann innerhalb des elmchan codes, er sthet dort glaube ich standartmässig auf 512 Byte. Wir senden 200 Bytes explizit, aber innerhalb der elmchan Routine im SPI-Aufruf stehen dann auch wieder 512 Bytes als Bytecounter drin, also sendet er nicht 200 Byte wie ich dachte, sondern 512. Und aufgefallen ist noch, wir haben leider aktuell nur 2 verschiedene SD Karten zum testen, eine 4 GB noname, dauer ca 8 ms unser Schreibzyklus, eine transcent 32 GB KArte, dort dauert es nur 3 ms, also schon ein Faktor 2, was alleine eine unterschiedliche SDKarte ausmacht, also vermutlcih mit internen SD-Kartenpuffern zu tun. Das nur als Ausblick, dankeschön nochmals und viele Grüße.
Naja, 8 Bytes sagen wenig aus. Teste mal mit einem Megabyte Random Daten. Bei 8 Bytes ist der Overhead durch Fileverwaltung, Buffer und öffnen der Datei schon gewaltig.
rg423g schrieb: > ca 8 ms. .... > dort dauert es nur 3 ms Lass die Karte zwischendurch mal etwas "Housekeeping" (Garbage Collection, vorsorgliches Löschen von freien Sektoren...) machen, dann kann diese Zeit noch bedeutend länger werden. Laut Standard darf das Busy bis zu 250ms lang dauern. > also sendet er nicht 200 Byte wie ich dachte, sondern 512 Stichwort: Sektorgröße BTW: beim Powerfail musst du die Versorgung der Karte laut Standard noch bis zu 500ms (streng empfohlen sogar noch länger) nach dem letzten Schreibbefehl puffern. So manch einer, der das nicht tut, wundert sich dann über korrupte Daten. Dagegen hilft dann eine "Sekunden-USV" aus Diode und Elko für die SD-Karte.
:
Bearbeitet durch Moderator
rg423g schrieb: > Jetzt bin ich mir nicht sicher ob das normal ist, dass der Overhead der > SD-Karte soviel Zeit in anspruch nehmen sollte Ja, das ist normal. Die tatsächlichen Flash-Blöcke sind viel größer, bis 4 MiB ("Allocation Unit") bei SDSC/SDHC. Wenn du nur so wenige Daten schreibst, muss so ein kompletter Block gelesen, die 512 Bytes modifiziert, und dann wieder zurückgeschrieben werden. Am Effizientesten ist es, wenn du immer 4 MiB auf Einmal schreibst, und zwar auf zuvor gelöschte Blöcke deren Anfang eben auch Vielfaches von 4 MiB ist. So gehen bis 10 MiB/s (bei Karten mit Speed Class 10). Wie man das bei der elm-chan Library erreicht weiß ich aber nicht - hab sowas mal selbst implementiert. Manche Karten (z.B. Toshiba und SanDisk) machen zwischendurch bis zu 2s Pause. Das muss man abfangen können. Gute Erfahrungen habe ich mit Samsung-Karten gemacht. SD-Karten garantieren übrigens bei SPI überhaupt keine Geschwindigkeit - nur bei Nutzung des SD bus ("SDIO") gilt die Geschwindigkeitsangabe. Lothar M. schrieb: > Dagegen hilft dann eine "Sekunden-USV" aus > Diode und Elko für die SD-Karte. Den µC muss man aber auch puffern, damit der die Schreiboperationen abschicken kann, um das Dateisystem in einem sauberen Zustand zu hinterlassen.
> Wir senden 200 Bytes explizit, aber innerhalb der elmchan Routine im > SPI-Aufruf stehen dann auch wieder 512 Bytes als Bytecounter drin, also > sendet er nicht 200 Byte wie ich dachte, sondern 512. Tja so ist das wenn du Leute immer fertige Libaries nutzen und sich nicht selber mit der Hardware beschaeftigen. .-) SD-Karten arbeiten nach aussen hin generell mit Bloecken von 512Byte. Lediglich zum lesen konnte man wohl auch mal kleinere Bloecke einstellen und da war es nicht sicher das sowas von allen Karten unterstuetzt wurde. Und das ist jetzt der Wissenstand von vor 10Jahren. :) Ich wuerde davon ausgehen das die Karten heute intern ausschliesslich mit sehr viel grosseren Bloecken arbeiten. Da wird es also schon die Geschwindigkeit veringern wenn man 512Byte grosse Bloecke verteilt ueber die Karte schreibt weil die Karte dann jedes mal erst viele Kilobyte liesst, loesscht und dann neu schreibt wenn man nur einen kleinen Block aendert. Und dann kann es dir noch passieren das die Karten beim schreiben Pausen einlegen wo sie sich mit internen Verwaltungsaufgaben beschaeftigen. Je nach Hersteller der Karte natuerlich unterschiedlich! Wenn du Wert auf Geschwindigkeit legst dann wirst du wohl einen grossen Buffer in deinem Controller benoetigen. Olaf
Olaf schrieb: > Je nach Hersteller der Karte natuerlich unterschiedlich! Da gibt es extreme Unterschiede, die Spitze der Spitze des Eisbergs hat rg423g ja schon entdeckt. Und das Hässlichste ist, dass manche Karten mit kleinen Datenmengen gar nicht gut zurechtkommen und einen Block totschreiben. Dann ist die Karte quasi zu 99,999% neu, aber beim letzten Schreiben auf den einen Block ging was schief (Consumer Karten mit dem lausigen TLC-Flash können so einen Block z.B. nur noch 100..500 mal beschreiben, dann ist der "ausgelutscht", wird als defekt markiert und nicht mehr verwendet). Lesenwert ist neben dem Standard z.B. das hier: https://media.kingston.com/pdfs/MKF_283.1_Flash_Memory_Guide_DE.pdf Dann kommt noch dazu, dass das Löschen eines Block auch die physikalisch daneben liegenden eine wenig "mitlöscht", was bei ungünstigem Wearleveling im schlechtesten Fall dazu führt, dass die Karte gar nicht mehr startet. Denn die Firmware der Karte selber liegt ja auch auf dem Flash und wird beim PowerUp ins RAM des Controllers geladen und dort ausgeführt. Fazit: Consumer-Karten sind gut darin, ein paar wenige Male mit großen Dateien beschrieben zu werden (Fotos, MP3s, Filme,...).
:
Bearbeitet durch Moderator
Dankeschön für die vielen und schnellen Antworten. Ich fass mal kurz zusammen: Nachgemessen am Oszi wielange denn der Overhead ist hat noch keiner. Eigentlich sollte man die SD-Karte nicht so benutzen wie wir es machen, nämlich mit kleinen Datenmengen dauerhaft beschreiben, weil es zu Busy zuständen an der SD-Karte kommen kann, die dann meinen Code dauerhaft anhalten könnten. Sinnvoll wäre es wohl intern einen Puffer für zB 250ms oder besser 500 ms bereitzustellen und dann immer diretk die volle Datenmenge periodisch in die SD-Karte zu schreiben. Das sollte eigentlich machbar sein, wobei unser uC RAM vlt max 4 kB als SD Puffer bereitstellen könnte, und extern haben wir grad keinerlei RAM dran, also wir könnten dann maximal Datenpakete von 4 kB zwischenspeichern, aber damit sollte es dann ähnlich schnell funktionieren nur eben nicht so häufig wie jetzt gerade. Motivation ist die dass wir alle 50 ms etwas messen und verarbeiten, die 50 ms müssen per timing stehen, daher wäre es schön gewesen innerhalb dieser Zeit auch einen Zugriff auf die SD-Karte gewährleisten zu können, aber das sollte ja eventuell schon wegen dem random BUSY manchmal nicht möglich sein, wenn ich das richtig verstanden habe. Also lieber weniger oft speichern dafür größere Mengen, dann habe ich statistisch weniger oft meine Messzeiten zerstört, richtig? Vielen Dank weiterhin.
rg423g schrieb: > Nachgemessen am Oszi wielange denn der Overhead ist hat noch keiner. Doch, ich habe da einige Messungen gemacht! rg423g schrieb: > Das sollte eigentlich machbar sein, wobei unser uC RAM vlt max 4 kB als > SD Puffer bereitstellen könnte Das ist sehr wenig. Könnt ihr keinen größeren Controller benutzen? Bei 4KiB-Blöcken hatte selbst meine "gute" Samsung-Karte regelmäßig Busy-Zeiten bis 60ms. Die Busy-Zeit variiert wie gesagt stark nach Modell und Blockgröße; daher sollte man unbedingt einen großzügigen Puffer bereit stellen und auch eine Überlauf-Erkennung implementieren.
> Ich fass mal kurz zusammen: > Nachgemessen am Oszi wielange denn der Overhead ist hat noch keiner. Doch, hab ich schon mal gemacht. Aber mit Karten die es nicht mehr gibt und meiner eigenen FAT Implementation. Oh..und noch ein Tip. Wenn du das nicht nur fuer dich selber brauchst sondern an Kunden verteilen willst, besorg dir erstmal einen moeglichst grossen Berg unterschiedlicher Karten zum testen. Am schlimmsten sind Karten mit eigener Intelligenz, also SD-Karten die auch noch gleichzeitig USB koennen oder WLAN integriert haben. Olaf
rg423g schrieb: > Also lieber weniger oft speichern dafür größere Mengen, dann habe ich > statistisch weniger oft meine Messzeiten zerstört, richtig? Ja, und vor allem: zeitlich und ablaufmäßig entkoppelt von den 50ms. > dann habe ich statistisch weniger oft meine Messzeiten zerstört, richtig? Warum machst du die Messung nicht "einfach" so, dass die wichtiger ist als das Speichern? Oder warum speicherst du zu den Daten nicht einen Zeitstempel mit, statt sich auf dieses "20-Messungen-pro-Sekunde" Raster zu verlassen?
:
Bearbeitet durch Moderator
Bombastische Antwortrate, danke nochmals und auch weiterhin für die guten Infos aus euren Erfahrungen. Ich schau grad durch, unsere MSP430 haben maximal 32 kB RAM, und davon benutzen wir natürlich schon einiges im normalen PRogrammablauf usw. also zu 400 kB komme ich mit dieser Platform niemals. Wir haben jetzt ja auch schon ein paar Systeme im Einsatz und davon "funktionieren" :) eigentlich alle sehr zuverlässig, ohne Pufferungen und so weiter, was natürlich nicht bedeutet dass es nicht vorkommt und wir es einfach übersehen bzw nichts ausmacht. Kurz zu Lothar: Das Speichern asynchron wäre natürlich gut kann ich auch einplanen, mein Problem gedankleich dabei ist: Im Code hat mein Messen natürlich höchste Priorität, aber sobald ein SD-Kartenspeicherzyklus kommt hängt der Code ja im SD-Code fest, der elmchan code sperrt sogar die IRQs innerhalb des low level SPI sendens. Also muss ich, insofern ich den elmchan benutzen will, dafür sorgen dass das speichern einfach schneller oder zu definierten Zeitpunkten auftritt. Ich bin jetzt leider nicht tief genug im SD_Code mit FAT System drin um mir zu überlegen wie man auf eine KArte schreibt ohne den normalen while(1)-code zu verlassen, das ist aber dann vielleicht auch eher was für rasp-pis als für kleinere uCs :) Weiterhin Danke und ich schau mal wie wir das lösen und halte euch auf dem laufenden.
rg423g schrieb: > Eigentlich sollte man die SD-Karte nicht so benutzen wie wir es machen, > nämlich mit kleinen Datenmengen dauerhaft beschreiben, weil es zu Busy > zuständen an der SD-Karte kommen kann, Glaub ich nicht so ganz. > die dann meinen Code dauerhaft > anhalten könnten. Dann hat dein Code ein Problem. > Sinnvoll wäre es wohl intern einen Puffer für zB 250ms oder besser 500 > ms bereitzustellen Ja, nennt sich FIFO. > und dann immer diretk die volle Datenmenge periodisch > in die SD-Karte zu schreiben. Nein. FATfs puffert selber schon einen Sektor, darüberhinaus muss man nicht unbedingt noch größere Datenmengen puffern bzw. als großen Block schreiben. Wohl aber die einigen hunder MS Wartezeit im Extremfall puffern. > Das sollte eigentlich machbar sein, wobei unser uC RAM vlt max 4 kB als > SD Puffer bereitstellen könnte, Das reicht aber nicht für 500ms, oder? Wie hoch ist deine Datenrate? > Motivation ist die dass wir alle 50 ms etwas messen und verarbeiten, die > 50 ms müssen per timing stehen, Kein Thema, das macht man mit einem Timer-Interrupt. > daher wäre es schön gewesen innerhalb > dieser Zeit auch einen Zugriff auf die SD-Karte gewährleisten zu können, Falsch! Die zeitkritische Datenerfassung macht man in einem Interrupt. Der hat Priorität und kann den normalen Programmablauf JEDERZEIT unterbrechen. Die Daten werden in einen FIFO geschrieben. Ein Funktion in der Hauptschleife, also außerhalb eines Interrupts, prüft periodisch, ob Daten zum Schreiben im FIFO stehen und schreibt die auf SD-Karte. Wenn dann Wartezeiten auftreten, spielt das keine Rolle, denn der Interrupt läuft ungestört weiter. > Also lieber weniger oft speichern dafür größere Mengen, dann habe ich > statistisch weniger oft meine Messzeiten zerstört, richtig? Falsch. Beitrag "Re: Geschwindigkeitsfrage AVR auf SD" Beitrag "Re: Atemega328p - schaffst du das?"
rg423g schrieb: > Im Code hat mein Messen natürlich höchste Priorität, aber sobald ein > SD-Kartenspeicherzyklus kommt hängt der Code ja im SD-Code fest, Dann stimmt dein Konzept nicht. Siehe mein vorheriger Beitrag. > der > elmchan code sperrt sogar die IRQs innerhalb des low level SPI sendens. Nur für Mikrosekunden! > Also muss ich, insofern ich den elmchan benutzen will, dafür sorgen dass > das speichern einfach schneller oder zu definierten Zeitpunkten > auftritt. Nein! > Ich bin jetzt leider nicht tief genug im SD_Code mit FAT System drin um > mir zu überlegen wie man auf eine KArte schreibt ohne den normalen > while(1)-code zu verlassen, das ist aber dann vielleicht auch eher was > für rasp-pis als für kleinere uCs :) Nö, das ist was für Leute, die Multitasking verstanden haben. > > Weiterhin Danke und ich schau mal wie wir das lösen und halte euch auf > dem laufenden.
rg423g schrieb: > der > elmchan code sperrt sogar die IRQs innerhalb des low level SPI sendens. Eigentlich sollte das nicht zeitkritisch sein. Du kannst das auch durch Interrupts unterbrechen lassen, musst aber natürlich aufpassen auf welche Daten du da zugreifen kannst. rg423g schrieb: > Ich schau grad durch, unsere MSP430 haben maximal 32 kB RAM, Bloß was bringt ein super-stromsparender MSP430 wenn der eine stromverschwendende SD-Karte benutzt...! Ein STM32F407 mit SDIO, DMA und 192 KiB SRAM kann eine SD-Karte mit 1 MiB/s befeuern und dabei noch viel CPU-Zeit frei haben - aber nicht mit der elm-chan-Bibliothek. Falk B. schrieb: > Falsch. Meinen ausführlichen Messungen zufolge: Richtig. Je mehr auf einmal, desto besser.
rg423g schrieb: > Wir senden 200 Bytes explizit, aber innerhalb der elmchan Routine im > SPI-Aufruf stehen dann auch wieder 512 Bytes als Bytecounter drin, also > sendet er nicht 200 Byte wie ich dachte, sondern 512. Eure Beobachtungen sind ... unvollständig. Hätte man mal das Hirn eingeschaltet (und die SD Spec gelesen) würde sofort auffallen das man bei 200 Bytes den Sektor vorher einlesen muss. D.h. man liest auch erstmal Daten von der Karte. Die 512 Bytes ergeben sich dabei als Sektor direkt von der SD(HC) Spec. Im ungüstigen Fall liegen die Daten quer über 2 512 Byte Sektoren verteilt, dann müsste FatFS zwei Sektoren lesen. Falle er den 1. Sektor im Cache hat, ist das dann aber immer noch ein Schreibzyklus unmittelbar gefolgt von einem Lesezyklus mit jeweils 512 Bytes. Oh, apropos FAT: Bei 32 GB Fat32 könnte die Suche nach dem "nächsten freien Cluster" im zweistelligen Sekundenbereich dauern, wenn die Fragmentierung nur fies genug ist. Außerdem schwankt selbst die reine Schreibzeit auf SD Sektoren noch stark, selbst wenn man das Low Level misst. Denn die Karten machen ja Wear Leveling.
Jim M. schrieb: > Oh, apropos FAT: Bei 32 GB Fat32 könnte die Suche nach dem "nächsten > freien Cluster" im zweistelligen Sekundenbereich dauern, wenn die > Fragmentierung nur fies genug ist. Es geht besser, kostet aber RAM. Allerdings längst nicht so viel, wie man glauben könnte. Es muss keine vollständige "Bitmap" der freien Sektoren im Speicher gehalten werden. Ein klug implementierter binärer Baum reduziert den Speicherbedarf auf log(n). Und er kann dynamisch aufgebaut und gepflegt werden. Aber selbst im worst case, also frisch "gemountetes" FS und somit leerer Baum und letzter Cluster ist einziger freier Cluster im FS, kostet die Sache nur das lineare Einlesen der kompletten FAT. Wenn das zweistellige Sekundenzeiten dauert, ist am Code oder der Hardware irgendwas dramatisch kaputt...
c-hater schrieb: > Wenn das zweistellige Sekundenzeiten dauert, ist am Code oder der > Hardware irgendwas dramatisch kaputt... Nö. Braucht nur "normalen" µC mit SPI. FAT bei 32GB ist 4MB groß, und man kann sie via SPI nicht schneller als mit 25 MHz einlesen. Blöderweise muss man jedes Wort auch noch mit dem µC auswerten - das schafft zumindest ein 8-Bit AVR nicht in 10 Sekunden. Chan FATFS kann AFAIK nicht gleichzeitig lesen und auswerten. Ein richtig flotter 32-Bitter mit 600MHz schafft das sicherlich in unter 10s, aber der hat dann auch SDIO. Diese µC finden hier im Forum aber selten Verwendung.
Jim M. schrieb: > Nö. Braucht nur "normalen" µC mit SPI. > > FAT bei 32GB ist 4MB groß, und man kann sie via SPI nicht schneller als > mit 25 MHz einlesen. Blöderweise muss man jedes Wort auch noch mit dem > µC auswerten - das schafft zumindest ein 8-Bit AVR nicht in 10 Sekunden. Rechnen wir: SPI-Vmax für einen AVR8 ist 10Mbit/s. D.h.: Er kann die 4MByte (=32Mbit) in 3.2s einlesen (protocol overhead sei mal außen vor). Und er hat während dieser Zeit schon reichlich freie Takte, um die Daten zu beschauen. Es kommt dann nämlich nur alle 16 Takte ein Byte rein. Nun ist ein Eintrag in einer FAT32 sogar 4 Bytes groß, also stehen 64 Takte zur Verfügung (abzüglich der Takte, die nötig sind, um die ersten drei Bytes zu buffern, bei intelligenter Programmierung in einer effizienten Sprache also genau drei Takte). In den verbleibenden 61 Takten kann man eine Menge Nützliches tun... > Chan FATFS kann AFAIK nicht gleichzeitig lesen und auswerten. Doch, mit entsprechenden "Adaptierungen" kann es das sehr wohl. Er ist nur nicht "von Hause aus" dafür gedacht...
Jim M. schrieb: > Ein richtig flotter 32-Bitter mit 600MHz schafft das sicherlich in unter > 10s, aber der hat dann auch SDIO. Diese µC finden hier im Forum aber > selten Verwendung. Der ziemlich beliebte STM32F407 kann das in 0.22s. Modernere STM32 bei denen der Bug mit dem Taktteiler behoben ist können das in 0.18. SDIO mit 4bit und DMA ist sowieso Pflicht. Man kann immer einen Sektor der FAT einlesen und während der nächste per DMA angeliefert wird wertet man den vorigen aus. Das ist aber eh alles unnötig. Man sollte sowieso immer nach freien 4MB-Blöcken suchen. Das kann "parallel"/abwechselnd zum Schreiben passieren, im Voraus ist gar nicht nötig.
Jim M. schrieb: > Oh, apropos FAT: Bei 32 GB Fat32 könnte die Suche nach dem "nächsten > freien Cluster" im zweistelligen Sekundenbereich dauern, wenn die > Fragmentierung nur fies genug ist. Auch dieses Problem wurde schon gelöst, nennt sich Preallocation. http://elm-chan.org/fsw/ff/doc/lseek.html > Außerdem schwankt selbst die reine Schreibzeit auf SD Sektoren noch > stark, selbst wenn man das Low Level misst. Denn die Karten machen ja > Wear Leveling. Richtig, darum braucht man einen ausreichend großen FIFO. Aber all das hintert am Ende niemanden daran, auch schnelle Echtzeitdaten dauerhaft auf SD-Karte zu schreiben.
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.