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
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:
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.
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));
}
Tarabyte
EinigeEE
Tarabyte