Letzte Aktualisierung Es war unsere Firmware die ganze Zeit. Bis zu einem gewissen Grad peinlich, aber ich bin froh, dass wir uns weiterentwickeln können und ich Java für einen weiteren Tag abschalten kann. Meine Antwort ist unten.E/A-Ausnahmefehler bei Verwendung von serialport.open()
UPDATE Also habe ich mehr oder weniger aufgegeben. Ich denke, es ist ein Fehler, der auf die API zurückzuführen ist, aber ich habe weder die Zeit, noch Ressourcen noch Fähigkeiten, um dem auf den Grund zu gehen. Ich denke, es gibt einige Hardware, denen Windows nur den Mittelfinger gibt. Ich habe Eclipse heruntergeladen, bin zu Java gewechselt und werde versuchen zu sehen, ob das funktioniert. Wenn nicht, wirst du mich hier wiedersehen. Allerdings würde ich das gerne lösen, und wenn jemand Zeit oder Lust hat, tief in dieses Thema einzutauchen, würde ich gerne sehen, was Sie daraus machen. Natürlich werde ich von Zeit zu Zeit hier vorbeischauen. Bitte stelle sicher, dass du mich in deinen Kommentaren "@" schreibst, damit ich benachrichtigt werde.
ORIGINAL POST
Ich weiß, es gibt ein paar andere Menschen mit diesem Thema beschäftigen, aber ich hatte gehofft, dass mir jemand helfen könnte. Ich versuche, einen COM-Port zu verbinden, aber ich erhalte eine IO-Ausnahme, wenn ich versuche, den serialport.Open()
Befehl zu verwenden:
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
ich einen Stellaris LM4F232 bin mit einem COM-Port zu emulieren. Ich kann öffnen, zugreifen und ich bekomme gute Ergebnisse mit Termite (ein Terminal-Programm), aber jedes Mal, wenn ich es mit Visual Studio versuche, wird es nicht einmal verbinden und ich bekomme diesen Fehler. Jetzt weiß ich nicht einmal wirklich, was dieser Fehler bedeutet, und obwohl ich versuche, woanders zu lesen, fühle ich mich immer noch verloren.
Kann mir jemand erklären, was hier passiert und vielleicht kann ich anfangen, das herauszufinden? Ich kann mehr Code hinzufügen, aber um ehrlich zu sein, gibt es dort nicht viel; Alle Eigenschaften des Serialport-Geräts sind normal, und es passiert nur mit diesem Gerät (ich kann ein MSP430 mit den gleichen Details kein Problem verwenden).
ist mein Code unten für Menschen gezeigt, die es (man beachte das ist nur eine ‚Sandbox‘, nicht das eigentliche Programm, aber die Symptome sind identisch) sehen möchten:
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");
}
und die anderen Einstellungen sind erledigt mit dem Property Manager (einzige Differenz ist Baud ist auf 230400 eingestellt, alle anderen sind auf ihren Standard). Ich kann COM4 damit öffnen (ein MSP430), der in jeder Hinsicht ein identisches Gerät ist. Ich kann COM5 mit Termite öffnen, also weiß ich, dass die Verbindung gut ist). Und nein, ich versuche nicht, sie gleichzeitig zu öffnen. Wenn Sie weitere Informationen benötigen, lassen Sie es mich wissen und ich kann mehr posten.
Danke!
EDIT: Ich bin an Tag drei der versuchen, dies herauszufinden und immer noch kein Glück. Ich verstehe nicht wirklich, warum ich auf diese COM über ein Terminalprogramm zugreifen kann und nicht auf mein eigenes, wenn ich soweit sehe, dass es überhaupt keinen Unterschied gibt. Kennt jemand ein Programm, das einen COM-Port "untersuchen" kann, um die Eigenschaften davon zu sehen (neben Windows-Manager meine ich)? Ich werde ziemlich frustriert und stehe irgendwie still in meinem Projekt, bis ich das herausgefunden habe ...
EDIT2: Ich habe eine scheinbare Problemumgehung gefunden, aber ich muss es noch zur Arbeit bringen here . Jetzt bekomme ich ein paar verschiedene IO-Fehler, aber zumindest ist es Bewegung (nicht sicher, ob es Fortschritte gibt). Ich habe auch gelernt, dass dies ein .NET-Bug ist, der seit 2.0 existiert. Ich würde immer noch jede Hilfe lieben, aber wenn ich es herausfinde, werde ich zurück melden.Zachs Code (die Problemumgehung oben verlinkten) ist unten dargestellt:
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: Tag 6: Ich Aufstecken noch an diesem entfernt. Meine Wasserrationen sind niedrig, aber ich kämpfe weiter. Ich glaube, dass Hilfe sicher am Horizont sein muss. Wer dieses Tagebuch findet, bringt meine Überreste zurück nach Kanada und findet Nicole. Sag ihr, dass ich sie liebe.
Aber im Ernst, ich habe keine Ahnung, was dieses Problem verursacht. Ich frage mich, ob es rein auf der eingebetteten Seite ist; vielleicht weil es USB-to-go ist oder weil das Gerät auch ein Host sein kann. Ist jemand auf dieses Problem gestoßen? Es erklärt nicht, warum ich Termite (ein Terminal-Programm, für die Zuschauer, die uns gerade beitreten) verwenden kann. Ich habe versucht, ein Open-Source-Terminal-Programm zu finden, das a) funktioniert und b) siehe a). Wie üblich, werde ich zurück melden, wenn ich das Problem hier entdecke, wie ich jetzt unzählige Foren gefunden habe, wo es Leute dieses Problem aus dem Jahr 2006 hat geklingelt haben.
EDIT4: Also wie der Rat gegeben, ich habe heruntergeladen Port-Monitoring-Software App (ich habe Eltima Serial Port Monitor) und es wie ein Baud Problem sieht:
aber seltsam, egal welche Baud ich stelle es immer noch nicht. Und kann jemand erklären, was das Up/Down-Ding bedeutet? Ich habe versucht, es zu googeln, aber die Schlüsselwörter sind zu allgemein. Wie üblich werde ich weiterhin Änderungen melden.
Auch für die Aufzeichnung, kann ich mit Eltima bei einer Baud von 115200 (wie Termite) verbinden. Leider funktioniert das nicht in Visual Studio.
EDIT5: Unsere Handlung nimmt eine überraschende Wendung. Ich habe beobachtet, was passiert, wenn Termite eine Verbindung zum fraglichen COM-Port und zu BLAM herstellt! Termite wirft genau den gleichen Fehler wie mein Programm, aber es ignoriert es. Genie, oder? Sloppy, aber es funktioniert. Jetzt muss ich lernen, IOExceptions zu ignorieren. Ich melde mich zurück, wenn ich es herausgefunden habe.
EDIT6: So wie es sich herausstellt, ist es eine Baudrate Problem, aber es geht tiefer. Ich habe Eltima Serial Port Monitoring Software verwendet und es ist sehr intuitiv und einfach zu bedienen. Ich würde es empfehlen. Nach some research habe ich gelernt, dass Sie diese Ausnahme nicht ignorieren können und immer noch eine Verbindung mit der seriellen Schnittstelle mit .NET-Bibliothek herstellen. Also muss ich tiefer in die Win32 API gehen und meine eigene schreiben. Ich habe ein paar Seiten gefunden, die das berühren, aber um ehrlich zu sein, habe ich noch nie so etwas getan, also kann es eine Weile dauern, bis ich zurückmelde, aber ich werde es definitiv herausfinden und zu jedem zurückkommen. Es gibt viel zu viele, die unter diesem Problem leiden. Ich habe ziemlich viele Foren und Websites gefunden, auf denen ich genau die gleichen Symptome sehen kann, aber niemand hat wirklich viel getan, außer 'Yeah, .NET sucks' zu sagen. Ich habe vor, eine komplette statische Bibliotheksklasse zu schreiben und dann auf meiner Website zu veröffentlichen, hier und wo auch immer ich kann. Hoffentlich wird .NET Notiz nehmen (dieser Fehler existiert seit 2.0). Ich melde mich zurück, wenn es fertig ist!
EDIT7: Das ist viel schwieriger als ich dachte, es wäre.
EDIT8: Ich weiß nicht, ob jemand dem folgt oder nicht, aber ich wollte sagen, dass ich immer noch dabei bin, aber für eine Woche auf einer Geschäftsreise außerhalb der Stadt bin. Ich bin immer noch glücklich, Vorschläge und alternative Ideen zu hören!
Welche Einstellungen verwenden Sie zum Verbinden? Können wir bitte den Code sehen? –
Ich habe meinen Code zum ursprünglichen Beitrag hinzugefügt. Ich weiß nicht, wie man Code in den Kommentaren hinzufügt ... – tmwoods
Ich vermute nur, dass deine Eigenschaften irgendwie falsch sind. Vielleicht versuchen Sie, die Baudrate auf 9600 zu senken. –