Forum: Mikrocontroller und Digitale Elektronik STM32 USB Device Lib - Mass storage class


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mike (Gast)


Lesenswert?

Hallo,
ich teste gerade die Mass storage class - Implementierung (MSC) in der 
USB Device Library Als Board nutze ich eine "Black pill" mit STM32F411.

Ich habe als ersten Test eine Ramdisk mit 96kB eingerichtet und die 
Funktionen STORAGE_Read_FS und STORAGE_Write_FS implementiert. 
Funktioniert perfekt, das Ding erscheint als Laufwerk am PC, nach 
Formatierung kann es als solche genutzt werden.
Nun möchte ich als Speicher ein über SPI angebundenes Flash vom Typ 
25Q128 verwenden. Das Lesen läßt sich geradlinig umsetzen. Allerdings 
habe ich mit der Implementierung der Schreibroutine Probleme:
Um einen Block auf das Flash zu schreiben, muß zuvor der zugehörige 
Sektor gelöscht werden. Die Sektorgröße beträgt 4kB, also 8 Blöcke. Ich 
habe also einen statischen Cache mit 4kB angelegt; beim ersten 
Schreibbefehl wird der zugehörige Sektor in den Cache gelesen, das 
Schreiben erfolgt zunächst in den Cache. Erst wenn versucht wird, in 
einen anderen Sektor zu schreiben, wird der Cache aufs Flash 
programmiert, wobei zuvor der Sektor mittels Sector erase gelöscht wird. 
Hier gibt es zwei Fragen:

1.Kann man erkennen, ob am PC "Auswerfen" gedrückt wurde, um den Cache 
noch zurückschreiben zu können? Wenn nein, werde ich das über eine 
Timeout-Funktion lösen, wird mehr als 1 Sekunde nicht auf den Speicher 
zugeriffen, wird der Schreibvorgang abgeschlossen.

2. Die zweite - komplexere - Frage hängt mit dem USB-MSC-Protokoll 
zusammen. Was ist, wenn ein neuer Schreibbefehl eintrifft, der alte aber 
noch nicht abgeschlossen ist? Insbesondere das Löschen eines Sektors 
kann laut Datenblatt über 100ms dauern. So lange kann man den Controller 
ja nicht einfach warten lassen. Wie teilt man den "busy"-Status der 
USB-Library mit?  STORAGE_IsReady_FS scheint nicht das Richtige zu sein, 
denn hier ein Nicht-OK -Rückgabewert als ausgworfenes Medium 
interpretiert.

von Jim M. (turboj)


Lesenswert?

Auswerfen schreibt nur ausstehende Daten auf den Datenträger - es sei 
denn man signalisiert im SCSI Inquiry dass das Medium "removable" ist. 
Dann sendet Windows tatsächlich auch das entsprechende SCSI Kommando.

Neuer Schreibbefehl kann nicht auftauchen solange der alte nicht 
"abgeschlossen" ist.

Ausnahmen gäbe es nur mit TCQ oder NCQ - das ist per default aus. Ich 
weiss grade nich OTOH wie man die überhaupt einschaltet per SCSI 
Protokoll.

Mike schrieb:
> Insbesondere das Löschen eines Sektors
> kann laut Datenblatt über 100ms dauern. So lange kann man den Controller
> ja nicht einfach warten lassen.

Doch, man kann. Der PC als Host wird erst nach ein paar Sekunden 
ungeduldig.

von Max G. (l0wside) Benutzerseite


Lesenswert?

Auch wenn der alte Beitrag zwei Jahre alt ist, passt er doch prima zu 
meiner Frage.

STORAGE_Read_FS() und STORAGE_Write_FS() werden aus dem USB-Interrupt 
heraus aufgerufen. Speicherzugriff lesend und vor allem schreibend 
dauert ein bisschen (lesend vom externen Flash ein paar 100µs, 
schreibend deutlich länger).
Ist es sinnvoll, so lange den USB-Interrupt zu blockieren? Oder ist es 
besser, USBD_FAIL zurückzugeben (was als Status USBD_CSW_CMD_FAILED = 
0x01 an den Host schickt)? Versucht der Host es dann noch mal (so dass 
man in der Zwischenzeit die Lese-/Schreiboperation durchführen kann)? 
Oder bricht der Host dann ab?

Grüße Max

von Thomas Z. (usbman)


Lesenswert?

Max G. schrieb:
> Ist es sinnvoll, so lange den USB-Interrupt zu blockieren? Oder ist es
> besser, USBD_FAIL zurückzugeben

nein nie! Wenn das richtig programmiert ist sendet der usb core solange 
automatisch NAK bis du das Paket verarbeitet hast. Dann gibst du den EP 
frei und das nächste Paket kommt.

von Max G. (l0wside) Benutzerseite


Lesenswert?

Thomas Z. schrieb:
> nein nie! Wenn das richtig programmiert ist sendet der usb core solange
> automatisch NAK bis du das Paket verarbeitet hast. Dann gibst du den EP
> frei und das nächste Paket kommt.

Das ist grundsätzlich klar. Allerdings ist "richtig programmiert" und 
"von ST generierter Code" leider ein ziemlicher Widerspruch. Ich wollte 
aber auch nicht Wochen mit USB-Programmierung verbringen.

Ich liebäugele damit, die ST-Middleware wieder rauszuschmeißen und auf 
TinyUSB umzusteigen. Das scheint besser designt zu sein, der ST-Code ist 
häufig nicht sehr schön.

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.