2009-09-11 10 views
1

J'ai un périphérique qui génère des messages via un port série. Lorsque je redémarre l'appareil, le port d'achèvement d'E/S s'arrête de lire les octets.GetQueuedCompletionStatus arrête de lire un port série

Le code est appelle GetQueuedCompletionStatus():

BOOL bRet = GetQueuedCompletionStatus(
     m_hCompletionPort, 
     &dwBytesTransferred, 
     &dwCompletionKey, 
     &pOverlapped, 
     INFINITE); 

PortMon ressemble:

... 
IRP_MJ_WRITE Serial1 SUCCESS  LENGTH: 7 REBOOT. 
IRP_MJ_READ  Serial1 CANCELLED LENGTH: 1  

Logging montre le résultat suivant:

bRet=true, dwBytesTransferred=7, pOverlapped=0x0202B028, GetLastError()=997 
(sleep forever) 

Est-il possible de détecter cette échec et rétablir les communications?

Je peux surveiller un battement de chaleur et fermer/rouvrir le port série, mais il ne semble pas correct que l'API de Windows permette aux communications série de tomber silencieusement comme ceci.

Répondre

1

Si vous faites WaitForSingleObject sur la poignée pour le port série que vous avez ouvert pour commencer à lire des données, la poignée est-elle signalée lorsque le périphérique est redémarré? Peut-être que c'est un moyen de dire quand vous avez besoin d'ouvrir le port à nouveau?

+0

Merci. J'essayais de gérer cela sans avoir à prendre en compte l'utilisation du port IO Completion, mais il semble que je n'ai pas beaucoup le choix. –

+0

Vous avez le choix: Voir ma réponse! – janm

1

IO Achèvement Les ports peuvent certainement gérer ce cas sans problème. Vous n'avez pas besoin de fermer et de rouvrir l'appareil.

Le problème le plus probable dans ce cas est que vous avez une erreur sur la ligne (causée par la réinitialisation du périphérique) que vous n'avez pas effacée à l'aide de ClearCommError().

Vous devez utiliser SetCommState() et SetCommTimeouts() de manière appropriée pour votre périphérique. Dans le DCB que vous passez à SetCommState(), vous devez définir fAbortOnError. Si vous supprimez une erreur, vous devez appeler ClearCommError() avant de remettre en file d'attente une autre lecture.

1

RE: Janm (je ne peux pas sembler ajouter un commentaire à votre réponse désolé)

J'ai essayé définissant divers paramètres, y compris les drapeaux fAbortOnError, mais GetQueuedCompletionStatus() serait encore attendre indéfiniment du DCB. J'ai également essayé périodiquement de temporiser l'appel, et en vérifiant le port série pour les erreurs. Le port série a toujours l'air bien, mais la déconnexion briserait définitivement le port d'achèvement d'E/S. Le redémarrage de l'appareil crée probablement un état d'erreur transitoire ... Je dis probablement, parce que je n'ai jamais été capable de le détecter!

Un collègue développeur a également eu une fissure à ce problème, et ils ont également échoué. Nous avons donc simplement réécrit le code pour utiliser des lectures de port série superposées, et maintenant cela fonctionne bien.

Il y a probablement quelque chose, quelque part que nous avons manqué ... à la fin nous avons perdu plus de temps à essayer de résoudre le mystère que cela a pris pour réécrire le code.

+0

Intéressant. J'ai développé un certain nombre de systèmes qui font exactement cela en utilisant IOCompletionPorts; mes conceptions ont eu tendance à utiliser un grand nombre de lectures à un seul octet. Ceux-ci sont utilisés pour les systèmes de contrôle où pendant le test, le port série a été soumis à toutes sortes d'abus. Une autre possibilité est qu'il existe un bogue dans le pilote de périphérique série. Cela est plus probable si vous utilisez une carte série tierce, plutôt que le pilote natif Windows avec un port série standard. – janm

Questions connexes