2017-06-12 2 views
2

Da ist dieser Flash-Speicher-IC auf meiner Platine, der an meinen ARM-Prozessor STM32F04 angeschlossen ist. Der USB-Port des Prozessors ist für den Benutzer verfügbar. Ich möchte, dass mein Flashspeicher als Speichergerät erkannt wird, wenn er über USB mit dem PC verbunden ist.Flash-Speicher als Massenspeichergerät mit STM32 USB Device Library

Als ersten Schritt habe ich meine USB-Klasse als MSC in meinem Programm definiert, was gut funktioniert. Seit ich meine Platine an den PC anschließe, erkennt sie ein angeschlossenes Massenspeichergerät mit dem Fehler "Sie sollten die Disk formatieren, bevor Sie sie verwenden".

Jetzt ist die Frage, wie ich meinen Flash als "den Speicher" zu meinem Prozessor definieren kann. Folgendes wäre wahrscheinlich ein Teil Ihrer Antwort: -usbd_msc_storage_template.c -FAT-Dateisystem

Ich verwende STM32F446-Prozessor. FREERTOS und FATFS. Windows 10 auf meinem PC.

Vielen Dank im Voraus :)

Antwort

2

Zunächst einmal - wenn Sie brauchen nur den Flash-Speicher auf dem PC als Massenspeichergerät sichtbar zu sein, dann FatFS Sie nicht brauchen, da sie Speicher zugreifen verwendet wird, in eine Datei-für-Datei-Weise von der MCU. Wenn der PC auf die Speichergeräte zugreift, verwaltet er die Dateisysteme selbst und Sie können auswählen, welche Art von Dateisystem beim Formatieren des Laufwerks verwendet werden soll. Bei der Kommunikation mit dem Speicher selbst auf den niedrigen Pegel wird dem Speicher lediglich mitgeteilt, dass er "X Bytes von der Y-Adresse lesen/schreiben" soll. Das Gerät muss nur bestimmte Daten schreiben oder lesen und das Ergebnis der Operation zurückgeben.

USB-Massenspeichergeräteklasse

Diese USB-Klasse stellt das Gerät an die Host als Speichergerät, so dass es bestimmte Anzahl von Bytes lesen oder schreiben von/nach angegebener Adresse. Im Falle von STM32F4 Sie haben die Funktionen, die Sie erwähnt, werden die implementieren folgende (basierend auf STM32Cube Bibliothek):

typedef struct _USBD_STORAGE 
{ 
    int8_t (* Init) (uint8_t lun); 
    int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint16_t *block_size); 
    int8_t (* IsReady) (uint8_t lun); 
    int8_t (* IsWriteProtected) (uint8_t lun); 
    int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); 
    int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); 
    int8_t (* GetMaxLun)(void); 
    int8_t *pInquiry; 
}USBD_StorageTypeDef; 

Wie Sie erwähnt haben, gibt es eine USBD_MSC_Template_fops.c/.h Dateien, die eine Probe leere Vorlage liefern für Sie implementieren, die wichtigsten Funktionen sind Read und Write, wo die echte "Arbeit" erledigt ist. Um Ihr Gerät so zu initialisieren, dass es als USB-Massenspeichergerät angezeigt wird, wenn es mit einem PC-Host verbunden ist, müssen Sie nur noch den USB selbst initialisieren (USBD_Init), die MSC-Geräteklasse registrieren (USBD_RegisterClass) und diese Struktur im Treiber registrieren (USBD_MSC_RegisterStorage) Starten des USB-Geräteprozesses für den Treiber (USBD_Start), wenn eine Verbindung zum Host erkannt wird. Es gibt zahlreiche Beispiele, die genau das tun - siehe Referenzimplementierungen für Discovery- oder Eval-Boards. Sie scheinen das richtig gemacht zu haben, da das Host-Gerät Ihr Gerät als USB-MSC-Gerät erkannt und als nicht formatiert gemeldet hat.

Der Grund, dass Ihr System sagt, dass das Laufwerk nicht formatiert ist, weil die leere Implementierung in der usbd_msc_storage_template.c Datei die erfolgreiche Ausführung (Rückgabecode 0) für STORAGE_Read Funktion zurückgibt, führt aber keine Lesevorgänge durch - es werden keine Daten zurückgesendet. Dies kann je nach Betriebssystem von Host zu Host unterschiedlich sein. Die wahrscheinlichsten Szenarien sind jedoch, dass entweder eine Meldung angezeigt wird, dass der Speicher nicht formatiert ist oder Daten beschädigt sind.

Interfacing USB-Massenspeichergerät Rückrufe mit physischen Speichern

Wie oben erwähnt, USBD_MSC_RegisterStorage Aufruf wird Ihre Struktur in der USB-MSC-Geräteklasse Treiber registrieren. An dieser Stelle ruft der Treiber selbst die von Ihnen zur Verfügung gestellten Funktionen zu bestimmten Zeitpunkten an - wann immer dies vom Host gewünscht wird. Wenn der Zielspeicher eine SD-Karte wäre, wäre es ein natürlicher Schritt, zuerst Funktionen zu implementieren, die auf Ihre SD-Karte zugreifen. Sobald diese Funktionen getestet und getestet sind, müssen sie nur noch in die USB-MSC-Geräte Read und Write integriert werden und - unter der Annahme der korrekten Interrupt-Prioritäten - sollte es "out of the box" funktionieren. Das System sollte in der Lage sein, die Karte zu formatieren und später Dateien zu lesen und zu schreiben, alles über Ihre MCU.

Es funktioniert auf die gleiche Weise für jede Art von Speicher, den Sie wählen. Die einzige Anforderung besteht darin, die Callback-Funktionen USBD_StorageTypeDef genau so zu implementieren, wie sie sind. Dies bedeutet, dass der Host eine beliebige Anzahl zufälliger Bytes an einer beliebigen Adresse innerhalb des gemeldeten Adressraums schreiben kann und Sie entweder uneingeschränkt gehorchen (alle Daten schreiben wie sie sind) und "erfolgreiche Ausführung" zurückgeben oder einen Fehler zurückgeben, was höchstwahrscheinlich der Fall ist bedeutet, dass Ihr Laufwerk ausgehängt wird und der Benutzer eine Fehlermeldung erhalten wird. Im Falle von Lesevorgängen bedeutet dies, dass das Gerät genau die Datenmenge zurückgeben muss, wenn der Host eine X-Byte-Anzahl von der Y-Adresse anfordert. Dies bedeutet, dass, wenn Ihr Speichertyp für diese Art des Zugriffs nicht perfekt geeignet ist, mehr Arbeit in der Schicht geleistet werden muss, die auf den physischen Speicher zugreift, um der USB MSC-Schnittstelle zu folgen. All dies führt uns natürlich zum letzten Punkt unten.

Flash-Speicher als Dateisystem-Speicher

Für den Flash-Speicher, wo Sie die Rohdaten direkt zugreifen gibt es bestimmte Nachteile, die sie nicht perfekt geeignet für Dateisystem-Anwendungen machen. Diese kommen von der Art, wie diese Erinnerungen konstruiert werden. Obwohl erreichbar, wird es zusätzliche Schritte, die, um diese Mängel zu verbergen getan werden muss:

  1. Writing „1“ einzeln - Flash-Speicher, wenn sie direkt nur zugegriffen ermöglicht es Ihnen, „0“ Bits unter schreiben angegebene Adresse. Sobald ein bestimmtes Bit zu "0" umgedreht wurde, kann es nicht mehr einzeln auf "1" zurückgeblättert werden. Um dies zu tun, muss der gesamte Datenblock zuerst gelöscht werden. Abhängig vom Flash-Speicherbereich sind dies typischerweise Bereiche von 512, 4096 usw. Bytes. Das bedeutet, wenn Sie das angegebene Byte von 1 (binär 0000 0001) auf 4 (binär 0000 0100) ändern möchten, müssen Sie den ganzen Sektor lesen, löschen und schreiben. Für Sie bedeutet dies, dass, wenn nur eines der Bits, die der Host zum Schreiben anfordert, von "0" auf "1" umgedreht werden soll, Sie zuerst diesen Bereich löschen müssen.

  2. Direktzugriff - Je nach Art des Speichers (NOR/NAND) können Sie möglicherweise nicht oder nur eingeschränkt auf Daten zugreifen. Insbesondere können Sie bei NOR-Blitzen Daten einzeln lesen oder schreiben, während bei NAND-Speichern aufgrund der Verbindung der Zellen nur der Seitenzugriff erlaubt ist. Dies bedeutet, dass Sie möglicherweise mehr Daten lesen oder schreiben müssen als nötig.

  3. Schreibdauer - Flash-Speicher haben eine bestimmte Anzahl von Schreibzyklen für jede Zelle. Das heißt, wenn Sie ständig Daten an dieselbe Adresse schreiben, können Sie diese Grenze sehr schnell überschreiten. Dies ist besonders wichtig für Dateisysteme wie FAT, wo der FAT-Bereich ständig beschrieben wird. Dies wird durch die Implementierung einer Form von Wear-Leveling gelöst, bei der die Schreibvorgänge im physischen Sektor gleichmäßig verteilt sind. Sie können es natürlich auch als schreibgeschützt festlegen, indem Sie true von IsWriteProtected zurückgeben, wenn dies für Ihre Anwendung möglich ist.

Jetzt als für wie aktuelle SD-Karten erreichen das alles - alle SD-Karten heute, dass ich bin mir dessen bewusst einen einfachen Mikrocontroller (eine Art von 8081, ARM7 oder ähnliche) enthalten, die alles oben plus SD-Protokoll implementiert . Wenn Sie mit der Karte sprechen, sprechen Sie nicht wirklich mit dem Rohspeicher, sondern kommunizieren mit der MCU, die zwischen Ihnen und Ihren Daten sitzt. Seine Rolle besteht darin, Ihnen die Illusion von perfekten kontinuierlichen Daten zu präsentieren.

+0

Vielen Dank für Ihre schnelle Antwort Jacek. Ich würde versuchen, diese API-Funktionen in usbd_msc_storage_template.c implementieren und sehen, was passiert. –

Verwandte Themen