Forum: Mikrocontroller und Digitale Elektronik USB Fullspeed und SD-Karte


von Achim E. (elcit)


Lesenswert?

Hallo,

ich habe zwar einiges zu dem Thema im Forum gefunden, allerdings nicht 
so den richtigen Ansatz um meinen Code zu optimieren.
Mir ist die Thematik mit den Busy Zeiten bewusst und ich verwende nun 
MultiBlockWrite mit entsprechendem Puffer. Allerdings kann ich den 
Puffer ja nicht beliebig groß machen und bei verschiedenen Tests konnte 
ich auch keine so großen Unterschiede messen ob nun 8k oder 32k Puffer.
Ich verwende im Moment die MSC Class aus der USB-Host-Device_Lib_V2.0 in 
Verbindung mit einem STM32F105, wobei die SD-Karte eine SanDisk 2GB ist.
Die Zeiten liegen so bei ca. 500-550kByte/s. Mein Ziel wäre natürlich in 
den Bereich von 1MByte/s zu kommen, was ja mit einem FullSpeed möglich 
sein sollte.
Mein Ansatz wäre nun zwei Puffer zu nehmen, allerdings blockiert mir die 
Busy Zeit der Karte wieder das einlesen von dem Puffer.
Wenn ich das Abfragen zwischen Übertragungen ignoriere bekomme ich kein 
stabiles Schreiben und somit auch keine wirkliche Lösung.
Komme somit auch nicht wirklich weiter.
Mal abgesehen von einer Karte mit möglichst geringer Busy Zeit,
welcher Ansatz würde denn am ehesten zum Ziel von max. Speed führen?


Gruß
Achim

von Andreas B. (andreasb)


Lesenswert?

Hallo Achim

Mehr als 700kBytes wirst du so nicht hinkriegen. (zumindest mit dem 
STM32F103, wird aber kein grossen Unterschied zum 105 sein, denke ich).
700 kBytes/s schaffst du wenn du die Daten nicht verarbeitest, sondern 
einfach nur empfängst...


Du kannst den Isochronen Modus verwenden, da kriegst du etwas in 
Richtung 1MByte/s.

Ob für dich aber eine Isochrone Übertragung sinnvoll ist sei mal 
dahingestellt.

Der Isochrone Modus ist eher für Audio / Video Übertragung, ohne 
Retransmission im Fehlerfall etc. und für gleich bleibende Datenraten.
Also eigentlich beides nicht für dich geeignet.




mfg Andreas

von Achim E. (elcit)


Lesenswert?

Hallo Andreas,

sorry hatte vergessen, das der Betrieb Bulk ist, da das USB Device sich 
als MassStorage Device anmelden muss.
Der STM32F103 hätte zwar ein SDIO im vergleich zum STM32F105, allerdings 
bin ich im Bezug auf die Busy Zeiten im Zweifel ob das schnellere 
Schreiben der 512 Byte Blöcke wirklich viel bringen würde.

Gruß
Achim

von Andreas B. (andreasb)


Lesenswert?

>viel bringen würde
Definiere viel;-)

Aber ich kann deine Frage nicht beantworten, ich kann dir nur sagen das 
ich maximal 700 kByte/s Spitze hin gekriegt habe, also zwischen 650 ~ 
700 kByte/s mit Bulk, auf einen Endpoint der die Daten nicht verarbeitet 
hat, und es lief auch sonst nichts auf dem Controller.

Mehr wirst du wahrscheinlich auch nicht schaffen.

1 MByte/s kannst du vergessen;-)

Aber teste es doch einfach: Du kannst ja das schreiben auf die SD Karte 
auskommentieren.

Dann misst du wie viel du schreiben kannst, am einfachsten mit dd 
if=/dev/zero of=/dev/deinDevice bs=512, einen grösseren Block.

Dann weisst du ob du am richtigen Ort versuchst zu optimieren...


mfg Andreas

von Potter (Gast)


Lesenswert?

Mit welchem Protokoll schreibst Du denn auf die Disk? SPI? Dann sind die 
500 kBytes (wenns denn wirklich soviele sind) sehr gut.

Es ist schon etwas her, dass ich mich damit befasst habe, aber damals 
waren (effektive) Übertragungsraten (im SPI-Mode) von 200-250 kBytes 
üblich.

von Achim Elgert (Gast)


Lesenswert?

Hallo Andreas,

danke für den Tipp. Werde ich mal messen.

Hast Du bei den 700kByte/s einen FIFO oder Buffer am USB verwendet?
Der STM32F105 hat ja einen internen FIFO, den ich mit 128Byte verwende.

Gruß
Achim

von Achim Elgert (Gast)


Lesenswert?

Hallo Potter,

ja ich verwende die SD-Karte im SPI.
Die Bytes schreibe ich mit ca. 2,3MByte/s, der Knackpunkt sind die Busy 
Zeiten nach jedem schreiben der Blöcke.

Gruß
Achim

von Andreas B. (andreasb)


Lesenswert?

Achim Elgert schrieb:
> Hast Du bei den 700kByte/s einen FIFO oder Buffer am USB verwendet?
> Der STM32F105 hat ja einen internen FIFO, den ich mit 128Byte verwende.

Ja, wir hatten den FIFO angeschaltet.

Ich bin mir nicht mehr ganz sicher, aber ich glaube 64Byte 
Empfangsbuffer und 64Byte Pakete habe ich gesendet.

Buffer war auf jeden Fall angeschaltet...



mfg Andreas

von Achim Elgert (Gast)


Lesenswert?

Hallo,

ich habe jetzt mal Messungen mit deaktiviertem Schreibbefehl gemacht.
Mit HD-Tune bekomme für sequentielles Schreiben ca. 950KByte/s.
Würde bedeuten der USB Transfer ist gar nicht so schlecht.
Meine ca. 600KByte/s werden also doch durch die Busy Times vom 
MultiblockWrite reduziert.

Wäre der Ansatz die Writeroutine in einen Interrupt, der zyklisch 
aufgerufen wird und durch den USB-Interrupt unterbrochen werden kann, 
eine sinnvolle Möglichkeit den Durchsatz zu erhöhen?

Im Moment verwende ich einen Single-Puffer mit 8K.
Würde diesen dann durch 2 x 4K ersetzen und im Ping-Pong jeweils die 
Adressen ändern.

Oder gibt es vielleicht eine bessere Möglichkeit?

Gruß
Achim

von Andreas B. (andreasb)


Lesenswert?

Hallo Achim

Wie hast du das getestet?

Du hast 250kByte mehr als ich;-)

Ist offtopic, aber würde mich doch noch interessieren...;-)


mfg Andreas

von Achim Elgert (Gast)


Lesenswert?

Hallo Andreas,

welchen USB Stack hast Du denn verwendet?
Muss dazu sagen das ich zum Teil Änderungen in dem Code von der
USB-Host-Device_Lib_V2.0 gemacht habe.
Der F103 hat auch keinen internen Fifo.

Gruß
Achim

von Andreas B. (andreasb)


Lesenswert?

Hallo Achim

Wir haben den Hardware Stack verwendet, auf Basis eines Beispieles von 
ST (also mit der ganze ST Lib die ja alles beinhaltet...).

Um die Performance zu testen habe ich das ganze über libusb angesteuert, 
also einfach ein Loop der Daten geschrieben hat, und ich habe die Zeit 
gemessen, um die Rate zu berechnen.

>Der F103 hat auch keinen internen Fifo.
Könnte der entscheidende Unterschied sein;-)

Du hast natürlich auch einen Treiber, ich habs mit einer User-Level 
Applikation gemacht...

Zu deinem Problem kann ich dir natürlich nicht wirklich weiterhelfen.

Ich versuche es trotzdem:

Was machst du jetzt genau? 8kBytes empfangen, 8kBytes schreiben, warten 
bis geschrieben und dann wider empfangen

ODER

8kBytes empfange, 8kBytes schreiben und parallel die nächsten 8kBytes 
empfangen?

am effektivsten ist natürlich wenn du das parallel (mehr oder weniger) 
abarbeiten kannst.

Hast du dir schon mal überlegt das ggf. eine schnellere SD Karte helfen 
könnte?;-)
Ich habe keine Ahnung wie das aussieht, aber für meine Spiegelreflex 
habe ich mir extra eine schnelle gekauft, weil mit der langsameren Karte 
hatte ich immer wider sowas wie ne Sanduhr aufem Display;-)


mfg Andreas

von Achim Elgert (Gast)


Lesenswert?

Hallo Andreas,

also im Moment mache ich folgendes.
Wenn eine relativ große Datei übertragen werden soll, wird ja immer ein 
Cluster mindestens 32kb oder 64kb geschrieben.
Bedeutet mein Puffer von 8k wird voll und dann als Multi-Block an die 
SD-Karte übertragen.

Dein Ansatz mit quasi parallel ist im Moment auch meine Idee, was ich 
geschrieben hatte, bezüglich zwei Puffer und die Schreibroutine als 
Interrupt zu steuern.

Schnellere Karte habe ich schon geschaut. Aber bisher sind mir nur die 
großen RW-Access Times aufgefallen. In dem Punkt habe ich bisher keine 
großen
Unterschiede festgestellt.

Ich werde jetzt erst einmal den jetzigen Stand noch etwas debuggen und 
dann mal an den Bereich Puffer <-> SD-Karte gehen.

Gruß
Achim

von 123 (Gast)


Lesenswert?

Moin,

1. die Busy zeiten der SD - Karte wirst du nicht reduzieren können. ggf 
durch einen höheren clock. je nach dem was da bei spi mode zulassig ist.

2. die datenstrukturen der SD-karte auswerten. die erzählt dir sicher 
wie schnell sie eigentlich ist, und wie schnell du sie takten kannst.

3. ggf überlegen den SD Mode zu implementiren wenn die HW 
voraussetzungen dafür vorhanden sind. Dadurch hast du 4 Datenleitungen 
und eine separate command Leitung anstelle von einer. Auchtung 
Lizenzpflichtig für den gewerblichen einsatz. Docku gibts bei 
sd-card.org. die sollte für die implementierung ausreichen. (ferner die 
HW beschrieben wurde. es gibt hersteller wie z.B. Samsung, da krigt man 
den teil nur als SD-Card member)

4. den Code kontrollieren, was mit dem Puffer gemacht wird in dem deine 
Daten zum lesen / Schreiben stehen. wie oft wird der umkopiert auf dem 
weg von USB Endpoint puffer bis zum FIFO der SPI / SD - Karte. Nach 
möglichkeit sollte hier der gleiche puffer verwendet werden.

5. werden auch die DMAs wenn vorhanden verwendet oder werden die daten 
von hand aus den puffern geschaufelt.

6. wie schon gemacht mit multiblock read / write arbeiten. ggf aber auch 
schauen ob das clockstop feater implementierbar ist. damit könnte der 
Multiblock read / Write für mehrere 8k pakete verwendet werden. beim 
Lesen nach empfangen der 8K kein stop senden, sonder einfach den klock 
abdrehen. wenn dann der nächste block genau danach kommt den klock 
wieder an ohne stop und neu zu addressieren.

7. wenn es von der datensicherheit vertretbar ist, versuchen so viel wie 
möglich parallel abzuarbeiten. USB empfängt den nächsten block während 
die SD - Karte den block davor noch wegschreibt. beim lesen umgekehrt. 
auf verdacht den nächsten block schon mal einlesen während usb noch am 
verschicken ist (wobei lesen sowieso meist schneller geht als schreiben)

8. nicht zu vernachlässigen ist auch die host seite. Windows macht da 
hin und wieder ganz seltsame sachen. Der USB Daten Sceduler kann sich je 
nach OS version ganz unterschiedlich verhalten. Ich glaub bei XP wars 
so: Werden USB Datenpakete genackt, wird die zugeteilte bandbreite so 
lange halbiert bis nicht mehr genackt wird. dumm nur wenn man gerade 
knapp unter/über so einer grenze liegt. dann schöpft windows nicht die 
volle leistung der HW aus.

gruss

von Achim Elgert (Gast)


Lesenswert?

Hallo,

123 schrieb:
> Moin,
>
> 1. die Busy zeiten der SD - Karte wirst du nicht reduzieren können. ggf
> durch einen höheren clock. je nach dem was da bei spi mode zulassig ist.
>
Die Hardware gibt 18MHz Clock her, und so wird auch der SPI auch 
getaktet.

> 2. die datenstrukturen der SD-karte auswerten. die erzählt dir sicher
> wie schnell sie eigentlich ist, und wie schnell du sie takten kannst.
>
Höher wie 18MHz komme ich mit dem STM32F105 nicht.
Zumindest bekam ich die Info das alle 3 SPI's nicht höher wie 18MHz 
getaktet werden dürfen.

> 3. ggf überlegen den SD Mode zu implementiren wenn die HW
> voraussetzungen dafür vorhanden sind. Dadurch hast du 4 Datenleitungen
> und eine separate command Leitung anstelle von einer. Auchtung
> Lizenzpflichtig für den gewerblichen einsatz. Docku gibts bei
> sd-card.org. die sollte für die implementierung ausreichen. (ferner die
> HW beschrieben wurde. es gibt hersteller wie z.B. Samsung, da krigt man
> den teil nur als SD-Card member)
>
Der STM32F105 hat keinen SD Mode. Erst der STM32F2xxx, ist aber leider
nicht so sehr Pin kompatibel und kommt auch nicht mehr in Frage.

> 4. den Code kontrollieren, was mit dem Puffer gemacht wird in dem deine
> Daten zum lesen / Schreiben stehen. wie oft wird der umkopiert auf dem
> weg von USB Endpoint puffer bis zum FIFO der SPI / SD - Karte. Nach
> möglichkeit sollte hier der gleiche puffer verwendet werden.
>
Der Puffer wird von Anfang bis Ende gleich verwendet. USB Teil mit ca. 
950kByte/s ist wie ich finde auch gar nicht so schlecht.


> 5. werden auch die DMAs wenn vorhanden verwendet oder werden die daten
> von hand aus den puffern geschaufelt.
>
Die Daten werden per DMA an die Karte übertragen.

> 6. wie schon gemacht mit multiblock read / write arbeiten. ggf aber auch
> schauen ob das clockstop feater implementierbar ist. damit könnte der
> Multiblock read / Write für mehrere 8k pakete verwendet werden. beim
> Lesen nach empfangen der 8K kein stop senden, sonder einfach den klock
> abdrehen. wenn dann der nächste block genau danach kommt den klock
> wieder an ohne stop und neu zu addressieren.
>
Diesen Punkt müsste ich mir mal genauer anschauen. Danke für den Tipp.

> 7. wenn es von der datensicherheit vertretbar ist, versuchen so viel wie
> möglich parallel abzuarbeiten. USB empfängt den nächsten block während
> die SD - Karte den block davor noch wegschreibt. beim lesen umgekehrt.
> auf verdacht den nächsten block schon mal einlesen während usb noch am
> verschicken ist (wobei lesen sowieso meist schneller geht als schreiben)
>
Beim Lesen bin ich erstaunlicher Weise fast gleich schnell wie beim 
Schreiben. Allerdings ist mir noch nicht klar warum.
Müsste ich noch untersuchen. An eine Implementierung von quasi Parallel 
werde ich noch angehen. Muss aber im Moment erst einmal einen sauberen 
Stand fertigstellen um dann weitere Optimierungen vorzunehmen.

> 8. nicht zu vernachlässigen ist auch die host seite. Windows macht da
> hin und wieder ganz seltsame sachen. Der USB Daten Sceduler kann sich je
> nach OS version ganz unterschiedlich verhalten. Ich glaub bei XP wars
> so: Werden USB Datenpakete genackt, wird die zugeteilte bandbreite so
> lange halbiert bis nicht mehr genackt wird. dumm nur wenn man gerade
> knapp unter/über so einer grenze liegt. dann schöpft windows nicht die
> volle leistung der HW aus.
>
Dies ist auch eine interessante Info. Danke.
Werde ich mal anschauen.

> gruss


Gruß
Achim

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
Noch kein Account? Hier anmelden.