¿Con qué frecuencia debe ejecutarse la tarea HD USBDeviceTask () de Microchip?

2

Estoy integrando el módulo USB de ejemplo en mi aplicación existente y solo puedo hacer que funcione cuando deshabilito las interrupciones.

Estoy trabajando en el mla example instalado en la ruta:

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

Detalles

  • Estoy implementando cada una de las funciones de devolución de llamada USB exactamente como se hace en el ejemplo.
  • El reloj USB es 48MHz
  • El reloj de la CPU (f_osc) es 16MHz
  • pic18f25k50
  • una interrupción de alta prioridad para Timer1 hace tic cada 250us, todo lo demás sucede cada 1s
    • nunca te duermas, sin embargo, esto todavía parece reiniciarse

¿La pila USB del microchip no es segura para subprocesos?

¿No estoy ejecutando la tarea USB lo suficientemente rápido?

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
}

Cuando falla, veo que el administrador de dispositivos continúa actualizándose acompañado de una de estas ventanas emergentes cada 5 segundos en Windows 7:

    
pregunta tarabyte

3 respuestas

2

Intenta usar USB en el modo de interrupción. Los dispositivos USB deben responder a las solicitudes del host dentro de un determinado período de tiempo. No ha detallado cuánto tiempo tarda en ejecutarse su rutina de tareas de temporizador, pero a raíz de este error, parece que se está demorando demasiado y que el USB no tiene forma de responder de manera oportuna.

Sin detalles específicos de su aplicación, sugeriría ejecutar USBDeviceTasks () como la única tarea de interrupción de alta prioridad y establecer el temporizador y sus tareas como prioridad más baja.

De esta manera, cuando el host solicita una respuesta del PIC cuando está ejecutando las tareas del temporizador, hará una pausa en la ejecución de esa rutina, responderá al host y luego volverá a esa rutina.

    
respondido por el SomeEE
1

La clase USB HID puede sondear tan rápido como cada 1 ms. Por lo tanto, lo ideal es llamar a USBDeviceTask () con más frecuencia que cada 1 ms.

En el lateral, he intentado llamar a USBDeviceTask () cada 10 ms, ¡y parece que funciona bien!

    
respondido por el Steve
0

Tengo mis propias funciones de apagado / apagado cuando entro y salgo del modo inactivo y no me di cuenta de que la función de devolución de llamada suspendida por USB predeterminada pone el dispositivo en suspensión:

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).
}

Esto es ciertamente algo que no tenía la intención de hacer, así que he comentado por ahora.

Aunque es un poco aparte, un bucle do-while realmente proporciona una implementación más legible aquí, de todos modos, mejor:

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

Lea otras preguntas en las etiquetas