Hallo an alle,
ich habe ein Problem mit Arduino Uno. Ich möchte, via aufgestecktem USB
Host Shild über Bulk Only, auf ein Mass Storage Sektoren lesen und
schreiben.
Nun gibt es für Mega und größere Arduinos fertige Bibliotheken die mit
FAT arbeiten. Das brauche ich nicht.
---------
https://www.circuitsathome.com/mcu/mass-storage-support-for-usb-host-library-2-0-released/
Hier heißt es: "On the other hand, the mass storage component can be
used without a file system by simply reading/writing physical sectors;
this approach can save a lot of memory. The documentation for the mass
storage class code is available here." "here" ist der Verweis auf die
BulkOnly Class Reference.
---------
Ich bekomme irgendwie nicht hin, BulkOnly mit dem Host Shild arbeiten zu
lassen. Es gibt Beispiel-Sketches zu dem Host Shield, die funktionieren.
Lesen zum Beispiel Infos vom Host Shield aus, wenn der Datenträger
angesteckt wird. Mehr aber nicht. Ansonsten nur Beispiele für USB-PS2,
Tastatur oder was auch immer. Wenn ich BulkOnly nutze, scheint die
Bibliothek auf den Standard-USB-Anschluss eines Uno zuzugreifen, andere
Erklärung habe ich momentan nicht.
Mal ein Beispielcode:
1
#include <masstorage.h>
2
#include <UsbCore.h>
3
#include <SPI.h>
4
5
6
USB Usb;
7
8
//uint8_t BulkOnly::GetLastUsbError();
9
//BulkOnly::BulkOnly (USB * p)
10
int* p;
11
BulkOnly myStorage = BulkOnly(*p);
12
13
void setup() {
14
Serial.begin( 115200 );
15
while (!Serial);
16
Serial.println("Start");
17
18
if (Usb.Init() == -1)
19
Serial.println("OSC did not start.");
20
else Serial.println("Ok.");
21
22
23
Usb.Task();
24
25
int maxLun = myStorage.GetbMaxLUN();
26
Serial.print("Max LUN: ");
27
Serial.println(maxLun);
28
}
29
30
void loop() {}
Irgendwie ist der Code sicher noch ziemlich unausgereift und offenbar
falsch, auch in der Vorgehensweise. Das ist mein Problem. Wo liegen die
Fehler, die ich mache?
Die Ausgabe zu obigem Code wäre:
BulkOnly will da einen Zeiger auf "USB" haben. IMO müsste das
1
BulkOnlymyStorage=BulkOnly(&Usb);
heissen. Spuckt da der Compiler nicht zumindest eine Warning aus?
USB hat eine komplexe State-machine, ich glaube nicht dass Du schon so
früh korrekt die LUNs abfragen kannst. Der müsste ja erstmal USB Reset
und Enumerierung (Deskriptoren etc) machen, das dauert >100ms.
Andererseits habe ich nicht in die Doku von USB::Task() geschaut ob da
was wartet.
BulkOnly myStorage = BulkOnly(&Usb);
ist korrekt.
Es gibt ein .ino-File USB_desc. das initalisiert und fragt das Host
Shield ab. Zur Probe habe ich einen USB-Stick dran. Nach der ganzen
Prozedur von USB_desc zeigt er die Beschreibung an, da sind auch Sachen
bei, die das angeschlossene USB-Gerät betreffen. Wenn das alles durch
ist, leuchtet der USB-Stick dauernd. Deshalb gehe ich davon aus, dass
der mindestens einen Kontakt mit dem Host Shild hat. Aber sämtliche
nachfolgende Operationen mit BulkOnly schlagen fehl. Obwohl der Code,
nach einiger Fehlerausräumung, ok ist (wie das: BulkOnly(&Usb);).
Es bleibt das Problem, dass ich die Verbindung von BulkOnly zum USB Host
Shield nicht hinbekomme. Ob ich dann also LUNs abfrage oder Capacity, da
kommt nichts bei raus, nur: "0". BulkOnly::Init() dauert auch ne Weile,
das mache ich vorher auch noch, liefert aber nicht "0" zurück (Returns 0
for success).
MfG
Ich habe das andere verworfen und diese BulkOnly-Geschichte in dieses
USB_desc.ino eingebunden (dort wird Usb.Task() aufgerufen und zwar ein
mal am Anfang in loop(){}), nachdem er alle Informationen vom USB Host
Shield ausgegeben hat.
1
void loop()
2
{
3
Usb.Task();
4
5
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING )
6
{
7
Usb.ForEachUsbDevice(&PrintAllDescriptors);
8
Usb.ForEachUsbDevice(&PrintAllAddresses);
9
10
..............
11
..............
12
..............
13
14
while ( 1 ) { // stop
15
#ifdef ESP8266
16
yield(); // needed in order to reset the watchdog timer on the ESP8266
17
#endif
18
}
19
}
20
}
Also dort, wo die Punkte stehen, probier ich jetzt mit BulkOnly rum, wie
ich beschrieben habe.
Sowohl BulkOnly als auch der Rest Cod in USB_desc verwenden dasselbe
USB-Objekt, weil das ja nur einmal mit: USB Usb; erzeugt wird.
MfG
Du hast in Deiner loop() eine Endlosschleife, d.h. Dein loop() wird
genau einmal ausgeführt.
(Sieh Dir das while an)
Ich glaube nicht, daß das sinnvoll ist.
Ich, weiß, das while habe ich gesehen. Das Script soll dort
anhalten. Warum der Author das Ganze dann überhaupt in loop() gepackt
hat, weiß ich auch nicht. So ist der Beispielcode.
Ich sehe das Problem, dass der USB Host Shield, via SPI angesprochen
wird. Man muss also mit dem USB Host Shield kommunizieren, um auf das
extern angeschlossene Gerät zuzugreifen. Funktioniert bei
SD-Kartenlesern genau so. Falls masstorage.h den USB Host Shield als
Endgerät sieht, kann das nicht funktionieren, Endgerät wäre ja der USB
Stick am Host Shield. Und hier weiß ich dann erst mal nicht weiter.
MfG
Die Task()-Funktion muss aber zyklisch aufgerufen werden, um Änderungen
am Devicestatus etc. erkennen zu können.
Deswegen gehört deren Aufruf in loop().
> Ich sehe das Problem, dass der USB Host Shield, via SPI angesprochen> wird. Man muss also mit dem USB Host Shield kommunizieren, um auf das> extern angeschlossene Gerät zuzugreifen.
Und was soll daran das Problem sein? Dein µC kommuniziert mit dem
USB-Host-Controller. Nur mit dem.
Alle USB-Aktivitäten gehen durch den Host-Controller hindurch, das ist
die unterste Ebene, die Du auf jeden Fall aufrechterhalten musst.
Dein Zugriff auf ein USB-Gerät, das am Host-Controller angeschlossen
ist, erfolgt nichtsdestotrotz durch den Host-Controller hindurch, d.h.
die grundlegende Kommunikation per SPI bleibt immer bestehen.