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