gpt4 book ai didi

c# - 使用serialport.open()时发生I/O异常错误

转载 作者:行者123 更新时间:2023-12-03 12:57:05 24 4
gpt4 key购买 nike

最终更新

一直都是我们的固件。令人尴尬,但我很高兴我们可以继续前进,并且可以推迟学习Java。我的答案如下。

更新

所以我对此有所放弃。我认为这是API的一个错误,但是我没有时间,资源和技能来深入了解它。我认为存在一些Windows只是中指的硬件。我已经下载了Eclipse,并切换到Java,然后尝试查看它是否有效。如果没有,您会在这里看到我。但是,我绝对愿意解决这个问题,因此,如果任何人有时间或意愿来深入研究这个问题,我都希望看到您的想法。显然,我会不时地回到这里。请确保您在评论中用“@”代表我,以便我们得到提醒。

原始帖子

我知道还有其他一些人在处理这个问题,但是我希望有人可以帮助我。我正在尝试连接到COM port,但是当我尝试使用serialport.Open()命令时却遇到了I/O异常:

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,无论出于何种目的,它都是同一台设备。我可以用Termite打开COM5,所以我知道连接很好)。不,我不是想同时打开它们。如果您需要更多信息,请告诉我,我可以发表更多信息。

编辑:我在尝试解决这一问题的第三天,仍然没有运气。我真的不明白为什么我可以通过终端程序而不是我自己的终端程序来访问此COM端口,而我所看到的几乎没有什么区别。是否有一个程序可以“检查” COM端口以查看其属性(我的意思是Windows管理器除外)?我感到非常沮丧,并且在我的项目中停滞不前,直到我弄清楚了...

EDIT2:我已经找到了一个明显的解决方法,但尚未使它能够工作 here。现在,我遇到了一些不同的I/O错误,但至少它是运动的(不确定它是否在前进)。我还了解到,这是一个.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 On-The-Go(OTG),或者是因为该设备还可以作为主机。有人遇到过这个问题吗?但这并不能解释为什么我可以使用Termite(终端程序,对于那些刚刚加入我们的观众来说)。我一直在尝试找到a)可以正常工作并且b)看到a)的开源终端程序。和往常一样,如果我在这里发现问题,我会报告,因为我现在发现了无数论坛,听起来人们早在2006年就遇到了这个问题。

EDIT4:因此,按照给出的建议,我下载了一个端口监视软件应用程序(我得到了 Eltima Serial Port Monitor),它的确看起来像是一个波特问题:

但是奇怪的是,无论我设置了什么波特率,它仍然会失败。而且有人可以解释向上/向下的含义吗?我尝试使用Google搜索,但是关键字太笼统了。和往常一样,我将继续报告所有更改。

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

EDIT5:我们的情节令人惊讶。我正在监视当白蚁连接到有问题的COM端口和BLAM时会发生什么!白蚁抛出与我的程序完全相同的错误,但忽略它。天才吧?马虎,但它的工作原理。现在,我需要学习如何忽略IOExceptions。我一想起来就报告。

EDIT6:事实证明,这是一个波特率问题,但它会更深入。我一直在使用Eltima串行端口监视软件,它非常直观且易于使用。我会推荐。在 some research之后,我了解到您不能忽略此异常,仍然可以使用.NET的库连接到串行端口。

因此,我必须更深入地研究Win32 API并编写自己的API。我发现了一些与此有关的页面,但老实说,我之前从未做过这样的事情,因此可能要过一段时间才能报告,但我一定会弄清楚这一点并回复大家。有太多的人遭受这个问题的困扰。

我找到了很多论坛和网站,可以看到完全相同的症状,但是除了说“是的,.NET很烂”之外,没有人真正做过很多事情。我计划编写一个完整的静态库类,然后在我的网站上,我可以在任何其他地方发布。希望.NET会引起注意(此错误自2.0开始存在)。

最佳答案

这来自串行端口驱动程序。对其中一种设置不满意。波特率是一个很好的选择,驱动程序通常最多允许115200。尽管这不是专用CAN总线产品的限制。

解决此问题的最佳方法是使用Sysinternals的Portmon实用程序。您可以看到发送到驱动程序的内容。首先观察终止。这是您的已知工作基准。然后修改SerialPort属性,直到程序发送的初始化命令(与您在PortMon中看到的一样)与Termite匹配为止。只是值,而不是顺序。如果仍然无法解决问题,则将其带到 parking 场,然后用您的汽车翻回几次,然后购买另一个品牌。

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

关于c# - 使用serialport.open()时发生I/O异常错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14885288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com