Hallo, ich hab hier grad ein kleines Problem mit einem Ressourcenkonflikt am SPI-Bus. Ich verwende eine Transflash-Karte im SPI-Modus und noch einige andere SPI-Teilnehmer. Das ganze funktioniert so auch, allerdings ist die Karte "zu langsam" -- ich muss regelmäßig die anderen Teilnehmer abfragen. Jetzt hab ich mal gesucht inwieweit ich einen block write unterbrechen kann -- soweit ich gesehen habe geht das nicht. Und partial write wird nicht von allen Karten unterstützt, ist also auch keine wirkliche Option. Oder hab ich da was übersehen? Danke für alle Hinweise.
Also ich würde eher sagen, dein Geschreibsel auf die Karte ist zu langsam. Wie lange dauert es denn um die 512 Byte zu übertragen und in welchem Intervall musst du die anderen Teil abfragen? Den Schreibzugriff wirst du nicht unterbrechen können, da die Karte beim Deaktivieren von CS AFAIK jegliche Komm abbricht und danach wieder mit einem normalen Command gestartet werden muss. Ansonsten halt das SD-Protokoll implementieren oder Software-SPI verwenden falls du keine zweite SPI-Schnittstelle hast.
Also, ich hab mir mittlerweile meine Frage mehr oder weniger selbst beantwortet gekriegt... Die Karte bricht jeden block write ab sobald CS wieder auf high geht. Also ist unterbrechen nicht. Ansonsten: meine Karte braucht ca. 6ms um einen Block zu schreiben. Langsam ist die Karte sicher nicht, aber ich kann meinen SPI-Bus leider nicht schneller wie ~3.5MHz machen aufgrund vom Design -- mehr schafft der Controller nicht. Da ich einen Sensor mit 160Hz abfragen muss (und das zeitkritisch ist) habe ich also 6.25ms Zeit für einen Schreibzugriff. Da die Karte auch mal etwas länger braucht wie 6ms hab ich dann ein Problem. Und partial writes kann die Karte laut CSD nicht (und ich will mich auch nicht auf dieses Feature verlassen).
Bau dir ein Software FIFO im Uc ein. 160 Hz Daten sind ja wohl gar kein Problem mit ein klein bisschen FIFO.
Hi! 6ms für 512 Byte? Das kann ich garnicht recht glauben. 3,5MHz und CLK/2 x 4096 Bit sind 2,34ms für die Übertragung nochn paar Takte fürs Init und wir sagen 3ms. Nun musst du nur noch auf die Response warten (dauernd takten) das dauert bestimmt keine 3ms bis fertig. Ich habe jetzt leider meinen Schlepptop nicht da sonst würde ich mal nachsehen wie schnell das so im allgemeinen geht. Aber >6ms für ein 1/2K, wo soll man denn diese Karte einsetzen? Ich denke eher dein Prog ist nicht optimal. Versuche doch mal die Geschwindigkeit deiner Ausgabe zu trimmen. Viel Erfolg, Uwe
Ich habe eine 64MB Nokia Mini SD Karte die schafft selbst auf einem ARM7 nur 30kB/s. Bei 7.5MHz SPI Takt. Und meine Routinen sind sicher nicht schlecht optimiert ;) Eine 256MB extrememory MMC bringt es mit dem gleichen Programm auf satte 470kB/s. Nicht zu vergessen eine 128MB takems SD die auf 8kB/s runtergeht wenn man zu häufig auf einen Sektor prügelt. Da bremst wohl das eingebaute Defect-Management. Alles im SPI Modus natürlich. Im USB 2.0 Kartenleser schafft die Nokia auch nur gerade mal so 1MB/s beim schreiben. MMC und SD Karten sind schon merkwürdige Dinger ;)
@Fly: wie soll das funktionieren? Ich hab genug Platz um Daten zwischenzuspeichern, aber wenn ich mit 160Hz pollen muss und ein einfaches block write an die SD-Karte länger dauert wie die freie Zeit zwischen zwei polls hab ich keine Chance. Jedenfalls nicht wenn das alles am selben SPI-Bus hängt -- und mein Controller hat nur einen. @Uwe: das warten auf die Response dauert teilweise wirklich lange. Hab das schon mit dem Oszi ausgemessen. Ansonsten gibts an der Ausgabe leider nix groß zu trimmen, die pustet einfach die Daten der Reihe nach auf den SPI. Und später soll aus den 160Hz dann noch spürbar mehr werden, und das eben noch mit harten Echtzeitbedingungen. Wenn ich da die Karte nicht unterbrechen kann hab ich da keine Chance.
Was wäre, wenn man einen kleinen Atmel als Puffer für die Karte nutzen würde? Die zu schreibenden Daten rübergeschoben und der Puffer würde sich dann um den Rest kümmern. Den fehlenden zweiten SPI könnte man per Software emulieren, der Puffer-Atmel macht ja sonst nichts anderes.
Hi! Habe gerade mal in mein Prog geschaut, die beste Karte die ich habe braucht 312us zum Daten schreiben, die schlechteste 1,37 ms. OK da sind schon Unterschiede da, aber 3ms nur fürs schreiben? Obwohl wenn ich lese: >Nicht zu vergessen eine 128MB takems SD die auf 8kB/s runtergeht wenn man >zu häufig auf einen Sektor prügelt. >Da bremst wohl das eingebaute Defect-Management. könnte das sogar stimmen. Am besten mal eine andere Karte testen, oder den SPI-Bus extern umschalten, oder den Sensor in SW auslesen. Jedenfalls eine böse Geschichte. Viel Erfolg, Uwe
Hi! Ohne jetzt alles im Detail gelesen und das SD Datenblatt im Kopf zu haben, wie wäre es denn mit einer Verkleinerung der Blocklänge? Kann man bei SD Karten nicht die Lese- und Schreibblocklänge auf unter 512Byte einstellen? Dann wäre es doch möglich die Zugriffe zu verkürzen. Gruß, Ralf
>Eine 256MB extrememory MMC bringt es mit dem gleichen >Programm auf satte 470kB/s. Wie kann man denn die Geschwindigkeit messen? Wolfgang
10ms Timerinterrupt im Programm und zusätzlich mit dem Mehrkanalspeicherosci zur Kontrolle messen ob es auch stimmt. Gemessen an der CS Leitung von der MMC/SD. Der Timerinterrupt bremst die Übertragung dabei natürlich ein wenig !
Polle den Sensor mit einem Sotware-SPI. Während das stattfindet, kann die SD-Karte warten. Solange du das CS nicht auf high ziehst und damit den Transfer abbrichst, sollten der Karte irgendwelche Unterbrechungen egal sein.
@Uwe >>schon Unterschiede da, aber 3ms nur fürs schreiben? Obwohl wenn ich >>lese: >>Nicht zu vergessen eine 128MB takems SD die auf 8kB/s runtergeht wenn man >>zu >>häufig auf einen Sektor prügelt. >>Da bremst wohl das eingebaute Defect-Management. >>könnte das sogar stimmen. Am besten mal eine andere Karte testen, oder Wieso könnte ? 128MB SD takems. FAT16. Werte gemessen mit einem ATMega32 16MHz / 8 MHz SPI Speed 4 Sektoren pro Cluster ohne FAT Buffer 8 kB/s 32 Sektoren pro Cluster ohne FAT Buffer 50 kB/s 4 Sektoren pro Cluster MIT FAT Buffer 290 kB/s 32 Sektoren pro Cluster MIT FAT Buffer 327 kB/s Der "geprügelte" Sektor ist ein/mehrere Sektor/en in der FAT. Die Karte kann durchaus Höchstleistungen bringen. Die Frage ist nur "WIE" ;) Holger
Ich habe jetzt mit dem Oszi an CS bzw. CLK gemessen und bin zu folgenden Ergebnissen gekommen: (MSP430 läuft mit 8 MHz; CLK mit 4MHz) 1 Byte benötigt rechnerisch sowie auch messtechnisch 2µs, aber jetzt kommt der Hammer: die Zeit zwischen 2 Bytes beträgt 13µs, sodass für einen Sektor mit 512 Bytes ca. 8ms gebraucht werden, was einem Datendurchsatz von 64 kB/s entsprechen würde. > 4 Sektoren pro Cluster MIT FAT Buffer 290 kB/s > 32 Sektoren pro Cluster MIT FAT Buffer 327 kB/s Was müsste ich tun, um auf ähnliche Werte zu kommen? Es handelt sich um eine 128MB SD-Karte, welche mit FAT32 formatiert ist, wobei das FAT- System nur genutzt wird, um eine Datei bestimmter Größe zu erzeugen. Der µC schreibt direkt in einen festgelegten Sektor. (wie hier im Forum unter "SD Karte--Sektor für Dateianfang festlegen /64367 " beschrieben) Wolfgang
>>(MSP430 läuft mit 8 MHz; CLK mit 4MHz) Oh, ein Exot ;) >>1 Byte benötigt rechnerisch sowie auch messtechnisch 2µs, >>aber jetzt kommt der Hammer: die Zeit zwischen 2 Bytes beträgt 13µs, >>sodass für einen Sektor mit 512 Bytes ca. 8ms gebraucht werden, was >>einem Datendurchsatz von 64 kB/s entsprechen würde. >>> 4 Sektoren pro Cluster MIT FAT Buffer 290 kB/s >>> 32 Sektoren pro Cluster MIT FAT Buffer 327 kB/s >>Was müsste ich tun, um auf ähnliche Werte zu kommen? Sorry für den Witz oben :( Gut hier ein paar Tips: Ich benutze einen ATMega mit 8MHz SPI Speed. Theoretisch also 1MB/s. Praktisch komme ich beim rohen Sektor schreiben auf 360-440 kB/s. Ohne die SPI Routinen zu optimieren. Je nach Karte. Meine langsame Nokia habe ich da aber noch nicht getestet. Das beinhaltet das senden des Commandos, warten auf die Response, senden eines Blocks und abholen der CRC. Sagen wir mal halbieren der SPI Speed halbiert auch die Übertragungsgeschwindigkeit. Theoretisch bei 4MHz also mit meinen Werten 180-220 kB/s. Das ist bei dir drin. Wie ? Vermeide Unterprogramme in der Block Loop ! Also da wo der meiste Durchsatz gemacht wird. Bei mir sieht das so aus (bei dir wohl ähnlich): for(i=0; i<BYTE_PER_SEC; i++) { SPI_WRITE(*buf++); // shift out next byte SPI_WAIT(); // wait for end of transmission } SPI_WRITE(*buf++); und SPI_WAIT(); sind bei mir MACROS und keine Unterroutinen. Das spart haufenweise Zeit weil kein Call, Parameterübergabe, und Return ausgeführt werden muss. Holger
Ich habe selbst mal einen Datenlogger programmiert der immer komplette 512 Blöcke auf die SD-Karte schreibt dieser Vorgang wird von einer Interuptroutine unterbrochen die Messdaten aufnimmt. Das hat die Karte eigentlich nie gestört. Datenverluste oder Abstürze der Karte sind nie aufgetreten. SPI Takte habe ich zwischen 400KHz und 12MHz gefahren und hat immer alles gefunzt. Allerdings will ich nicht ganz ausschliessen das es zwischen verschiedenen Kartenherstellern leichte Abweichungen geben kann, die dann zu Problemen führen---aber eigentlich eher unwahrscheinlich. Gruss Laurentius
Hi! @Holger >4 Sektoren pro Cluster ohne FAT Buffer 8 kB/s Moment mal, das ist ja schreiben mit Fatunterstützung. Wolfgang dauert das Schreiben eines Sektors ja zulange, also 512 Byte. Von Fat oder so war keine Rede. Man kann ja auch etliche Sektoren füllen ohne die Fat zu berichtigen, das hat nachher auch noch Zeit. Da haben wir dann allerdings den "geprügelten" Sektor dabei und das könnte dann natürlich dauern. @ Wolfgang >aber jetzt kommt der Hammer: die Zeit zwischen 2 Bytes beträgt 13µs, Das meinte ich mit "Versuche doch mal die Geschwindigkeit deiner Ausgabe zu trimmen." Du hast doch wohl hoffentlich die 512 Byte im Ram stehen? Bei der Ausgabe immer nur das "SPI-fertig-Flag abfragen und dann sofort das nächste Byte übergeben sollte keine 13µs dauern, höchstens(Mist kein Datenblatt da)2/3 Takte oder so. Nagel mich jetzt bitte nicht auf die Bits und Register fest.(nimms als Pap) Data: lds temp, x+ warte: sbic SPI_Statusregister,Sendenfertig_Flag rjmp warte out SPDR,temp rjmp Data Länger darf deine Ausgabe nicht sein. Viel Erfolg, Uwe
@Uwe >>Wie ? Vermeide Unterprogramme in der Block Loop ! Also da wo >>der meiste Durchsatz gemacht wird. Auch ohne den MSP430 zu kennen stimme ich dir zu das er irgendwo Rechenzeit verbrennt. Die beiden Zeilen oben sind als Tip doch gar nicht schlecht ! Oder ? >>beim rohen Sektor schreiben auf 360-440 kB/s. Die Zeile oben bedeutet schreiben OHNE FAT. Holger
Hi! @Holger >>4 Sektoren pro Cluster ohne FAT Buffer 8 kB/s >Die Zeile oben bedeutet schreiben OHNE FAT. Was denn nun? normales Blockschreiben ohne Fat oder Fat Buffer? Wenn ohne Fat, lasse bitte die Cluster weg denn die gehören zur Fat. Oder meintest du ohne Fatberichtigung? Für Holger eigentlich egal, nur mich hätte interessiert wie langsam deine Karte schreibt, nicht wie langsam dein Progr. ist. >Die beiden Zeilen oben sind als Tip doch gar nicht schlecht ! Oder ? Ja, das ist genau das was Holger umsetzen muss.(hatte ich glatt überlesen und MSP430 war auch wie weggeblasen) @laurentius Das mag sein, aber du hast wärend der Unterbrechungen bestimmt CS nicht abgeschaltet. Holger hat aber am selben Bus einen Sensor den er lesen will. ... habe ich jedenfalls so verstanden. @Holger Und du kümmerst dich mal um fullspeed am SPI Bus, dann klappts auch mitm Messen. Viel Erfolg, Uwe
Naja ich habe eine Funktion geschrieben die Datenaustausch mit der Karte handelt. Immer wenn ich die anspringe wird CS auf Low gezogen. Das heisst wenn ein Interrupt ansteht wird in die Interruptroutine gesprungen...und abgearbeitet und CS bleibt Low. Bei Rücksprung macht das Hauptprogramm dann dort weiter und sendet oder Empfängt weiter Daten von dr Karte. Das wichtigste ist das man den ersten leeren Fat-Eintrag auffindet bevor man das Hauptprogramm startet. Da das bei grossen Karten die bereits einiges an Daten enthalten schon etwas länger dauern kann. Bei schnellen Messungen kann es sonst schonmal schnell passieren das einem der Speicher überläuft. Also zuerst ersten freien FATEintrag suchen->dann Messdaten abspeichern-> Bei stark fragmentierten Karten kann es natürlich auch später zu verzögerungen kommen die Probleme machen. Gruss LAurentius
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.