Erreur d'ouverture du port série
-
20-08-2019 - |
Question
J'essaie d'ouvrir et de lire à partir d'un port série à l'aide de la classe System.IO.Ports.SerialPort. J'ai fait glisser le port série à partir du volet d'outils (VS 2008) sur mon formulaire Windows. J'ai une grille de propriétés configurée pour pouvoir facilement modifier les propriétés du port série lors de l'exécution. Lorsque j'essaie d'ouvrir le port, le message d'erreur ci-dessous s'affiche. Je ne comprends pas pourquoi parce que je peux ouvrir et lire à partir du port avec Hyperterminal. Des idées?
System.IO.IOException Error connection: A device attached to the system is not functioning
at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.InternalResources.WinIOError()
at System.IO.Ports.SerialStream.set_DtrEnable(Boolean value)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at Test.CardReader.frmMain.Connect() in D:\Develop\2.0\Projects\Kiosk\EmbeddedBrowser\Windows Forms\Test.CardReader\Form1.cs:line 166
Remarque: il s’agit d’une connexion USB et il s’agit d’un port série virtuel.
Mes paramètres sont les suivants:
BaudRate = 9600
DataBits = 8
DiscardNull = false
DtrEnable = false
Handshake = None
Parité = Aucune
ParityReplace = 63
PortName = COM3
ReadBufferSize = 4096
ReadTimeout = -1
ReceivedBytes = 1
TrsEnable = False
StopBits = One
WriteBufferSize = 2048
WriteTimeout = -1
J'ai téléchargé PortMon à partir de sysinternals. J'ai capturé 2 journaux, le premier explique comment se passe Hyperterminal lorsque le port est ouvert, le second est ce qui se passe lorsque la classe .net SerialPort tente d'ouvrir le port:
Hyperterminal:
IRP_MJ_CREATE USBSER000 SUCCESS Options: Open
IOCTL_SERIAL_SET_QUEUE_SIZE USBSER000 SUCCESS InSize: 8192 OutSize: 8192
IOCTL_SERIAL_CONFIG_SIZE USBSER000 SUCCESS Size: 0
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_SET_RTS USBSER000 SUCCESS
IOCTL_SERIAL_SET_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:f6 XOFF:6
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:80000001 Replace:80000040 XonLimit:80 XoffLimit:200
IOCTL_SERIAL_SET_TIMEOUTS USBSER000 SUCCESS RI:10 RM:0 RC:0 WM:0 WC:5000
IOCTL_SERIAL_SET_WAIT_MASK USBSER000 SUCCESS Mask: RLSD ERR
IOCTL_SERIAL_GET_MODEMSTATUS USBSER000 SUCCESS
IOCTL_SERIAL_WAIT_ON_MASK USBSER000
IRP_MJ_READ USBSER000 Length 80
Port série Net:
IRP_MJ_CREATE USBSER000 SUCCESS Options: Open
IOCTL_SERIAL_GET_PROPERTIES USBSER000 SUCCESS
IOCTL_SERIAL_GET_MODEMSTATUS USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_CLR_RTS USBSER000 SUCCESS
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:0 Replace:0 XonLimit:4096 XoffLimit:4096
IOCTL_SERIAL_GET_BAUD_RATE USBSER000 SUCCESS
IOCTL_SERIAL_GET_LINE_CONTROL USBSER000 SUCCESS
IOCTL_SERIAL_GET_CHARS USBSER000 SUCCESS
IOCTL_SERIAL_GET_HANDFLOW USBSER000 SUCCESS
IOCTL_SERIAL_SET_BAUD_RATE USBSER000 SUCCESS Rate: 9600
IOCTL_SERIAL_CLR_RTS USBSER000 SUCCESS
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IOCTL_SERIAL_SET_LINE_CONTROL USBSER000 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
IOCTL_SERIAL_SET_CHAR USBSER000 SUCCESS EOF:1a ERR:0 BRK:0 EVT:1a XON:11 XOFF:13
IOCTL_SERIAL_SET_HANDFLOW USBSER000 SUCCESS Shake:0 Replace:0 XonLimit:4096 XoffLimit:4096
IOCTL_SERIAL_CLR_DTR USBSER000 * 0xC0000001
IRP_MJ_CLEANUP USBSER000 SUCCESS
IRP_MJ_CLOSE USBSER000 SUCCESS
La solution
En ce qui concerne les différences entre hyperterminal et l’objet de port série .NET, Hyperterminal est une application commerciale et stable. Si l'objet de port série sous-jacent est mort ou a généré une exception, Hyperterminal vous l'a cachée. L'objet de port série .NET génère plus d'exceptions que tout autre objet .NET que j'ai utilisé.
Points à souligner:
- Chaque fois que vous modifiez un paramètre, fermez-le d'abord, changez-le puis rouvrez-le. Certains ports le détestent vraiment quand vous le changez en étant ouvert.
- Attendez-vous à faire beaucoup d'essais de capture autour de votre objet de port série, autour de tout ce que vous faites.
- Assurez-vous d’avoir une exception pour chaque exception possible dans la liste et assurez-vous que chacune vérifie le message (il peut être différent dans différentes circonstances). Beaucoup sont récupérables simplement en fermant et en rouvrant.
- Essayez de suivre exactement où les exceptions sont levées. Voyez si la modification de l'ordre que vous définissez résout le problème ... l'objet est vraiment difficile.
Si vous avez explicitement essayé de définir DTR sur false avant de l'ouvrir, il vous suffira de sourire et de le mettre à nu avec cet appareil. L'objet SerialPort n'est pas l'un des exemples élogieux d'une bibliothèque bien implémentée dans .NET. Si vous remarquez, hyperterminal obtient la même erreur, mais il l’ignore.
Si vous le pouvez, essayez-le avec un port série standard ou un périphérique USB de marque différente. Si vous obtenez toujours la même erreur, il se peut que cela soit du côté de votre application.
Autres conseils
En temps réel UART
, DTREnable
affirmera la DTR
broche de votre true
pour indiquer que vous êtes prêt à recevoir des données.
En fonction de l'implémentation de votre pilote, vous devrez peut-être définir <=> sur <=> pour ouvrir le port.
Consultez ce message du forum . Je soupçonne que cela a à voir avec le matériel ou le pilote fonctionne mal. Cela n'explique pas pourquoi cela fonctionne avec Hyperterminal cependant. Suivez les conseils de Joseph M. Newcomer pour voir ce que Hyperterminal fait différemment.
il semble que la différence réside dans la poignée de main.
Je n'ai pas eu de problèmes avec la classe serialport et des applications écrites fonctionnant à 800 000 bps.