2017-01-24 1 views
1

Mon application utilise une puce FTDI USB et le pilote D2XX. Il utilise OIO (Overlapped IO) pour lire et écrire sur l'USB. Mes exigences incluent un délai de 30 secondes, quelque chose que je ne peux pas réduire. Le code semble assez robuste et stable.FTDI D2XX Annulation d'E/S superposées (OIO) après déconnexion et reconnection d'un câble USB

Une nouvelle exigence est de surmonter une déconnexion accidentelle et de reconnecter le câble USB (une infirmière a expulsé le câble). Une fois que j'ai reçu le message de Windows et déterminé qu'il s'agit de notre dispositif FTDI, j'ai découvert que je ne pouvais pas recevoir de nouvelles données sur une reconnexion de l'OIO avant l'expiration du délai OIO précédent.

Une fois que je découvre la déconnexion, je boucle sur l'appel suivant jusqu'à ce que tous faisaient la queue OIO sont récolta:

bool CancelOIO() 
{ 
    if (!FtdiRemaining) 
     return false; 

    FT_SetTimeouts(FtdiHandle, 1, 1); 
    FT_W32_PurgeComm(FtdiHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); 

    while (FtdiRemaining) 
    { 
     DWORD nBytes = 0; 
     if (!FT_W32_GetOverlappedResult(FtdiHandle, &FtdiOverLap[FtdiQindex], &nBytes, FALSE)) 
     { 
      if (FT_W32_GetLastError(FtdiHandle) == ERROR_IO_INCOMPLETE) 
       return true; 

      if (FT_W32_GetLastError(FtdiHandle) != ERROR_OPERATION_ABORTED) 
      { 
       CString str; 
       str.Format("FT_W32_GetOverlappedResult failed with %d\r\n", FT_W32_GetLastError(FtdiHandle)); 
       SM_WriteLog(str, RGB_LOG_NORMAL); 
      } 
     } 

     FtdiRemaining--; 
     FtdiTodo++; 
     FtdiQindex++; 
     if (FtdiQindex >= FtdiQueueSize) 
      FtdiQindex = 0; 
    } 

    return !!FtdiRemaining; 
} 

Je mis le délai d'attente à 1ms. Cela ne semble pas modifier le délai d'attente pour les OIO précédemment planifiées. J'ai appelé FT_W32_PurgeComm pour tout annuler. Cela ne semble pas non plus annuler l'OIO.

J'ai essayé d'appeler CancelIo et cela a renvoyé une erreur, le handle n'est pas valide. Ma compréhension est que c'est le code du conducteur pour y répondre. Cela pourrait être dû à la déconnexion.

Quoi qu'il en soit, j'appelle le code ci-dessus dans une boucle jusqu'à ce que tous les OIO programmés soient récoltés. Rien ne se passe pendant 30 secondes. Ensuite, tous les OIO semblent se terminer en moins de 1ms.

Comme un test de ce code, j'ai appelé avec le câble USB connecté et il revient en 1ms. Donc, le problème semble être lorsque le câble est débranché.

Questions: Qu'est-ce qui me manque? Y at-il un autre appel que je peux faire? Est-ce un bug?

Autres choses que j'ai essayées: Fermeture de la poignée avant d'appeler FT_W32_GetOverlappedResult. Cela entraîne un retour rapide. Mais mon application ne peut plus recevoir de données du nouveau handle. Bizarre. Quelqu'un sait pourquoi?

N'appelant pas ce code. L'application est en mesure de recevoir de nouvelles données à partir du nouveau handle, mais seulement après ces délais. Pourquoi?

CyclePort. Cela ne fait pas revenir ces OIO plus rapidement. Cela ne change pas l'utilisation des données de réception OIO jusqu'à ce délai.

Répondre

0

J'ai trouvé après des tests répétés deux comportements distincts. Le plus rapide revient assez rapidement, annulant OIO. L'autre a utilisé le délai d'expiration complet de 30 secondes. Essayez de réduire le délai d'attente pour réduire le délai d'annulation d'OIO.