使用serialport.open()时IOexception错误

最终更新这是我们固件的全部时间。 在某种程度上令人尴尬,但我很高兴我们可以继续前进,我可以把学习Java关闭一天。 我的答案如下。

更新所以我或多或少地放弃了这一点。 我认为这是一个归结为API的错误,但我没有时间,资源和技能组合来深入了解它。 我认为存在一些Windows只是中指的硬件。 我已经下载了Eclipse,切换到Java并将尝试查看是否有效。 如果没有,你会看到我回到这里。 但是,我绝对喜欢解决这个问题,所以如果有人有时间或倾向深入研究这个问题,我很乐意看到你提出的问题。 显然我会不时回来看看。 请确保你在评论中’@’我,所以我会收到通知。


原始邮政

我知道还有其他一些人在处理这个问题,但我希望有人可以帮助我。 我正在尝试连接到COM端口,但是当我尝试使用serialport.Open()命令时,我收到了IOexception:

 System.IO.IOException: The parameter is incorrect. at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str) at System.IO.Ports.InternalResources.WinIOError() at System.IO.Ports.SerialStream.InitializeDCB(Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Boolean discardNull) 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 *programtitlehere.cs*:line 90 

我使用Stellaris LM4F232来模拟COM端口。 我可以使用Termite(一个终端程序)打开,访问并获得良好的结果,但每当我尝试使用Visual Studio时,它甚至都无法连接,我收到此错误。 现在我甚至不知道这个错误意味着什么,尽管我试图在其他地方阅读,但我仍然感到迷茫。

任何人都可以向我解释这里发生了什么,也许我可以开始尝试解决这个问题吗? 我可以包含更多代码,但说实话,那里没有太多代码; 串口设备的所有属性都是正常的,它只发生在这个设备上(我可以使用MSP430没有相同细节的问题)。

对于想要看到它的人,我的代码如下所示(注意这只是一个’沙盒’,而不是实际的程序,但症状是相同的):

  try { serialPort1.PortName = "COM5"; serialPort1.Open(); if (serialPort1.IsOpen == true) { textBox1.Text = "CONNECTED"; } else { textBox1.Text = "NOT CONNECTED"; } } catch (Exception ex) { MessageBox.Show("Error: " + ex.ToString(), "ERROR"); } 

其他设置由属性管理器完成(唯一的区别是波特设置为230400,其他所有设置都是默认值)。 我可以用它(一个MSP430)打开COM4,这对于所有意图和目的都是一个相同的设备。 我可以用白蚁打开COM5所以我知道连接很好)。 不,我不是想同时打开它们。 如果您需要更多信息,请告诉我,我可以发布更多信息。

谢谢!

编辑:我正在尝试解决这个问题的第三天仍然没有运气。 我真的不明白为什么我可以通过终端程序访问这个COM,而不是我自己的,因为我可以看到它绝对没有区别。 有谁知道一个程序可以“检查”一个COM端口,看看它的属性(除了我的意思是Windows管理器)? 我变得非常沮丧,并且在我的项目中保持不动,直到我弄明白…

编辑2:我发现了一个明显的解决方法,但我还没有在这里工作。 现在我得到了一些不同的IO错误,但至少它是运动(不确定它是否进展)。 我还了解到这是一个.NET错误,自2.0以来就存在。 我仍然喜欢任何帮助,但如果我弄清楚,我会报告回来。 Zach的代码(上面链接的解决方法)如下所示:

 using System; using System.IO; using System.IO.Ports; using System.Runtime.InteropServices; using System.Text; using Microsoft.Win32.SafeHandles; namespace SerialPortTester { public class SerialPortFixer : IDisposable { public static void Execute(string portName) { using (new SerialPortFixer(portName)) { } } #region IDisposable Members public void Dispose() { if (m_Handle != null) { m_Handle.Close(); m_Handle = null; } } #endregion #region Implementation private const int DcbFlagAbortOnError = 14; private const int CommStateRetries = 10; private SafeFileHandle m_Handle; private SerialPortFixer(string portName) { const int dwFlagsAndAttributes = 0x40000000; const int dwAccess = unchecked((int) 0xC0000000); if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("Invalid Serial Port", "portName"); } SafeFileHandle hFile = CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero); if (hFile.IsInvalid) { WinIoError(); } try { int fileType = GetFileType(hFile); if ((fileType != 2) && (fileType != 0)) { throw new ArgumentException("Invalid Serial Port", "portName"); } m_Handle = hFile; InitializeDcb(); } catch { hFile.Close(); m_Handle = null; throw; } } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr arguments); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true)] private static extern int GetFileType(SafeFileHandle hFile); private void InitializeDcb() { Dcb dcb = new Dcb(); GetCommStateNative(ref dcb); dcb.Flags &= ~(1u << DcbFlagAbortOnError); SetCommStateNative(ref dcb); } private static string GetMessage(int errorCode) { StringBuilder lpBuffer = new StringBuilder(0x200); if ( FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity, IntPtr.Zero) != 0) { return lpBuffer.ToString(); } return "Unknown Error"; } private static int MakeHrFromErrorCode(int errorCode) { return (int) (0x80070000 | (uint) errorCode); } private static void WinIoError() { int errorCode = Marshal.GetLastWin32Error(); throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode)); } private void GetCommStateNative(ref Dcb lpDcb) { int commErrors = 0; Comstat comStat = new Comstat(); for (int i = 0; i < CommStateRetries; i++) { if (!ClearCommError(m_Handle, ref commErrors, ref comStat)) { WinIoError(); } if (GetCommState(m_Handle, ref lpDcb)) { break; } if (i == CommStateRetries - 1) { WinIoError(); } } } private void SetCommStateNative(ref Dcb lpDcb) { int commErrors = 0; Comstat comStat = new Comstat(); for (int i = 0; i < CommStateRetries; i++) { if (!ClearCommError(m_Handle, ref commErrors, ref comStat)) { WinIoError(); } if (SetCommState(m_Handle, ref lpDcb)) { break; } if (i == CommStateRetries - 1) { WinIoError(); } } } #region Nested type: COMSTAT [StructLayout(LayoutKind.Sequential)] private struct Comstat { public readonly uint Flags; public readonly uint cbInQue; public readonly uint cbOutQue; } #endregion #region Nested type: DCB [StructLayout(LayoutKind.Sequential)] private struct Dcb { public readonly uint DCBlength; public readonly uint BaudRate; public uint Flags; public readonly ushort wReserved; public readonly ushort XonLim; public readonly ushort XoffLim; public readonly byte ByteSize; public readonly byte Parity; public readonly byte StopBits; public readonly byte XonChar; public readonly byte XoffChar; public readonly byte ErrorChar; public readonly byte EofChar; public readonly byte EvtChar; public readonly ushort wReserved1; } #endregion #endregion } internal class Program { private static void Main(string[] args) { SerialPortFixer.Execute("COM1"); using (SerialPort port = new SerialPort("COM1")) { port.Write("test"); } } } } 

EDIT3:第6天:我还在瞎扯这个。 我的口粮很低,但我还在挣扎。 我觉得必须有所帮助。 无论谁找到这本杂志,我的遗体都会带回加拿大并找到妮可。 告诉她我爱她。

但严重的是,我不知道是什么导致了这个问题。 我想知道它是否纯粹是嵌入式的一面; 可能是因为它是USB去,或者因为该设备也能够成为主机。 有没有人遇到过这个问题? 它没有解释为什么我可以使用白蚁(一种终端程序,对于那些只是加入我们的观众)。 我一直试图找到a)工作的开源终端程序,b)看a)。 按照惯例,如果我在这里发现问题,我会报告回来,因为我现在已经找到了无数的论坛,听起来这个问题可以追溯到2006年。

编辑4:所以根据给出的建议,我下载了一个端口监控软件应用程序(我有Eltima串口监视器),它看起来像一个波特问题:

Eltima的屏幕截图

但奇怪的是,无论我设置什么波特,它仍然失败。 并且有人可以解释上升/下降的意义吗? 我试过谷歌搜索它,但关键字太笼统了。 像往常一样,我会继续报告任何变化。

此外,为了记录,我可以使用Eltima以波特115200(与白蚁相同)连接。 不幸的是,这在Visual Studio中不起作用。

编辑5:我们的情节出人意料。 我正在监视当白蚁连接到有问题的COM端口和BLAM时会发生什么! 白蚁抛出与我的程序完全相同的错误,但它忽略了它。 天才,对吗? 马虎,但它的工作原理。 现在我需要学习如何忽略IOExceptions。 当我弄明白的时候,我会报告回来。

EDIT6:事实certificate这是一个波特率问题,但它更深入。 我一直在使用Eltima串口监控软件,它非常直观且易于使用。 我会推荐它。 经过一些研究,我了解到你不能忽略这个exception,仍然使用.NETs库连接到串口。 所以我必须深入研究Win32 API并编写自己的API。 我发现有几页涉及到这一点,但说实话我以前从未做过这样的事情,所以可能需要一段时间才会报告,但我一定会想出来并回到大家面前。 有太多人遭受这个问题。 我找到了不少论坛和网站,我可以看到完全相同的症状,但除了说“是的,.NET糟透了”之外没有人真正做过多。 我计划编写一个完整的静态库类,然后在我的网站上,这里和其他任何地方发布。 希望.NET会注意到(这个bug自2.0以来就存在)。 我会在完成后报告!

EDIT7:这比我想象的要困难得多。

EDIT8:我不知道有没有人跟着这个或者不是,但是我想说我还在,但是出差一个星期出差。 我仍然很高兴听到建议和其他想法!

这来自串口驱动程序,它对其中一个设置不满意。 由于波特率是一个很好的候选者,驱动程序往往只允许高达115200.虽然这不是一个限制,当这是一个专用的CAN总线产品。

解决这个问题的最佳方法是使用SysInternals的PortMon实用程序,您可以看到发送给驱动程序的内容。 首先观察终止,这是你已知的工作基线。 然后修改SerialPort属性,直到你的程序发送的初始化命令(如你在PortMon中看到的那样)与Termite相匹配。 只是价值,而不是订单。 如果那还没有消失,那么就把它带到停车场并用你的车多次回来并购买另一个品牌。


更新:它看起来像一个波特率问题。 这是.NET中的一个问题,它不会像终端仿真程序那样忽略驱动程序的错误返回代码。 由于您正在与模拟的串行端口通信,因此实际值无关紧要。 然而,CAN总线速度可能存在问题,速率是可变的,我不清楚它们是如何协商的。 这往往是在过去使用DIP开关完成的,很可能是驾驶员希望您通过波特率设置指定速度。 在盒子或手册中应该有一些东西。 典型速度为40,250或500 Kbps。 制造商当然会知道,给他们打电话。

我遇到了与此主题中报告的类似问题,但我设法解决了这个问题!

我在VCP上使用STM32F2xx!

事实上,这是我的固件问题,我忘了在USB回调中包含串口设置!

从PC和固件连接串口的过程:

  1. 当PC打开串口通信时,PC会将一些命令发送到“配置端点”
  2. 在固件中,它将有一个回调,固件将提供所有USB信息(他们称之为USB描述符)
  3. USB信息是每个端点的配置(例如:延迟,数据大小传输,USB类型 – 高速或低速)
  4. 一旦固件完成发送所有信息,PC将确认并且USB通信成功打开
  5. 然后,PC将发送命令以从固件获取串行端口设置
  6. 串行端口设置为 – 波特率,数据奇偶校验,位长度
  7. 在固件中,它应该将串口设置回复给PC( 我的错误发生在这里,我没有回复任何串口设置回PC
  8. 如果成功,PC将启动串口通讯!
  9. 如果失败,PC将发出一个打开的串口错误(但请注意,有时会绕过此错误)

在STM32固件代码中:

 static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length) { switch (cmd) { case CDC_GET_LINE_CODING: { //I was missing this part uint32_t baudrate = 9600; pbuf[0] = (uint8_t)(baudrate); pbuf[1] = (uint8_t)(baudrate >> 8); pbuf[2] = (uint8_t)(baudrate >> 16); pbuf[3] = (uint8_t)(baudrate >> 24); pbuf[4] = 0; pbuf[5] = 0; pbuf[6] = 8; break; }: .... 

所以我们惊心动魄的故事即将结束。 它一直是固件(即嵌入式设备上的代码)。 我们改变了一些function,基本上是戳了一下,切碎,添加并完全清理了代码,瞧,代码正在运行。 这张照片总结得很好。 诅咒你的固件!!

但是,我(冗长)问题中描述的错误仍然存​​在于许多人身上,我知道有很多人仍然拥有它。 我只能说是好运,并检查你的固件四倍(显然三重检查这些天是不够的)。

我遇到了同样的情况。 我正在尝试将串行通信连接到/ dev / ttyUSB0上的3G USB Dongle(华为E303F)。 我在Raspbian中使用mono(raspberry-pi2)。 在我的开发PC和macOS中,我的程序运行正常。 但是当我将它部署到Raspbian时,我在Serial.Open()上遇到IOException Broken Pipe错误。

我花了三天时间调试并尝试所有可能的解决方案。 最后我发现我必须设置……

 serialPort.DtrEnable = true; serialPort.RtsEnable = true; 

在调用之前.Open()。 我希望这可以帮助那些面临同样问题的人。

我有同样的问题,并将baudRate设置为1 FIXED IT !!!!!