Forum: Compiler & IDEs Arduino Uno - Bulk Only via USB Host Shield


von T. F. (solotal)


Lesenswert?

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:
1
Start
2
Ok.
3
Max LUN: 0

MfG

von Jim M. (turboj)


Lesenswert?

Der folgende Teil vom Code sieht kaputt aus:
1
int* p;
2
BulkOnly myStorage =  BulkOnly(*p);


BulkOnly will da einen Zeiger auf "USB" haben. IMO müsste das
1
BulkOnly myStorage =  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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sollte USB::Task() nicht innerhalb von loop() aufgerufen werden?

https://www.arduino.cc/en/Reference/USBHostTask

von T. F. (solotal)


Lesenswert?

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

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und, rufst Du mittlerweile USB::Task() auf andere Art und Weise auf?

von T. F. (solotal)


Lesenswert?

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

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von T. F. (solotal)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

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.