Wie oft muss der Task USB HID USBDeviceTask() von Microchip ausgeführt werden?

Ich integriere das Beispiel-USB-Modul in meine bestehende App und kann es nur zum Laufen bringen, wenn ich Interrupts deaktiviere.

Ich arbeite das mla-Beispiel ab, das unter dem Pfad installiert ist:

C:/microchip/mla/v2013_12_20/apps/usb/device/bootloaders/firmware/pic18fxxjxx

Einzelheiten

  • Ich implementiere jede der USB-Callback-Funktionen genau wie im Beispiel.
  • Der USB-Takt beträgt 48 MHz
  • Der CPU-Takt (f_osc) beträgt 16 MHz
  • pic18f25k50
  • ein Interrupt mit hoher Priorität für Timer1 tickt alle 250 us, alles andere passiert etwa alle 1 s
    • niemals schlafen gehen, aber dies scheint immer noch zurückgesetzt zu werden

Ist der USB-Stack von Microchip nicht Thread-sicher?

Führe ich die USB-Aufgabe nicht schnell genug aus?

while (1)
{
  // Clear the watchdog timer
  ClrWdt();

  // Run the USB task faster than xxxHz?
  USBDeviceTasks();

  // Do stuff
}

// high-priority foreground loop takes ~5us
void high_priority interrupt HighPriorityTasks(void)
{
  // Do stuff quickly, clear sources of interrupts
}

// low-priority foreground loop takes ~5us
void low_priority interrupt LowPriorityTasks(void)
{
  // Do stuff quickly, clear sources of interrupts
}

Wenn es fehlschlägt, sehe ich, dass der Geräte-Manager weiterhin aktualisiert wird, begleitet von einem dieser Popups etwa alle 5 Sekunden in Windows 7:Geben Sie hier die Bildbeschreibung ein

Antworten (3)

Versuchen Sie, USB im Unterbrechungsmodus zu verwenden. USB-Geräte müssen innerhalb eines bestimmten Zeitrahmens auf Hostanfragen antworten. Sie haben nicht angegeben, wie lange die Ausführung Ihrer Timer-Aufgabenroutine dauert, aber dieser Fehler scheint zu lange zu dauern und der USB kann nicht rechtzeitig reagieren.

Ohne spezifische Details Ihrer Anwendung würde ich vorschlagen, USBDeviceTasks() als einzige Interrupt-Task mit hoher Priorität auszuführen und den Timer und seine Tasks mit niedrigerer Priorität festzulegen.

Wenn der Host eine Antwort vom PIC anfordert, während er die Timer-Tasks ausführt, unterbricht er auf diese Weise die Ausführung dieser Routine, antwortet dem Host und kehrt dann zu dieser Routine zurück.

In dieser Version des USB-Stacks sehe ich keine USB_INTERRUPT-Makros. es scheint aber definitiv etwas mit der zeit zu tun zu haben
Mein Fehler - die falsche Bibliothek geöffnet. Nichtsdestotrotz können Sie USBDeviceTasks() einfach von main zu HighPriorityTasks verschieben, sobald die Interrupts richtig konfiguriert sind.
Ja, war mir nicht sicher, ob es sicher wäre, USBDeviceTasks() in einem Interrupt auszuführen.

Die USB-HID-Klasse kann alle 1 ms abfragen. Idealerweise möchten Sie also USBDeviceTask() öfter als alle 1 ms aufrufen.

Nebenbei habe ich versucht, USBDeviceTask() alle 10ms aufzurufen, und es scheint gut zu funktionieren!!

Ich habe meine eigenen Powerdown/Powerup-Funktionen beim Ein- und Aussteigen aus dem Ruhezustand und habe nicht bemerkt, dass die standardmäßige USB-Suspend-Callback-Funktion das Gerät in den Ruhezustand versetzt hat:

void USBCBSuspend(void)
{
  Sleep();         // Go to sleep, wake up when a USB activity event occurs
  //If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
  while((0 == USBIF_FLAG) && (0 == RCONbits.TO))      //If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
  {
    Sleep();     //Entry into sleep clears WDT count, much like executing ClrWdt() instruction
  }

  //After the USB suspend event ends, you should re-configure your I/O pins
  //for normal operation mode (which is allowed to consume more current).
  //However, it is recommended to put this code in the USBCBWakeFromSuspend()
  //function instead of here (so that this function will work with either
  //sleeping or clock switching to a lower frequency).
}

Dies ist sicherlich etwas, was ich nicht beabsichtigt habe, also habe ich das vorerst auskommentiert .

Eine do-while-Schleife ist zwar etwas nebensächlich, bietet hier aber ohnehin eine besser lesbare Implementierung:

// USB_onSuspend(void)
// Called when the USB host sends USB suspend signaling
void USBCBSuspend(void) {
  do {
    Sleep();
  } while ((USBIF_FLAG == 0) && (RCONbits.TO == 0));
}