ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ Это была наша прошивка все время. Смущаю до некоторой степени, но я счастлив, что мы можем двигаться вперед, и я могу учить изучение Java еще на один день. Мой ответ ниже.
UPDATE Поэтому я более или менее отказался от этого. Я думаю, что это ошибка, которая сводится к API, но у меня нет ни времени, ни ресурсов, ни навыков, чтобы добраться до сути. Я думаю, что существует некоторое аппаратное обеспечение, которому Windows просто дает средний палец. Я загрузил Eclipse, переключился на Java и попытаюсь посмотреть, работает ли это. Если нет, ты увидишь меня здесь. Тем не менее, я был бы очень рад решить эту проблему, и если у кого есть время или желание углубиться в это, я бы с удовольствием посмотрел, что вы придумали. Очевидно, я буду периодически проверять это время. Пожалуйста, убедитесь, что вы "@" меня в своих комментариях, поэтому меня предупреждают.
ОРИГИНАЛЬНАЯ ПОЧТА
Я знаю, что есть несколько других людей, которые занимаются этой проблемой, но я надеялся, что кто-то сможет мне помочь. Я пытаюсь подключиться к COM-порту, но я получаю исключение IO, когда пытаюсь использовать команду serialport.Open()
:
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, он даже не подключается, и я получаю эту ошибку. Теперь я даже не знаю, что означает эта ошибка, и я, несмотря на попытки читать в другом месте, все еще чувствую себя потерянным.
Может кто-нибудь объяснить мне, что здесь происходит, и, может быть, я начну пытаться понять это? Я могу добавить больше кода, но, честно говоря, там не так много; все свойства устройства serialport являются нормальными, и это происходит только с этим устройством (я могу использовать 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, все остальные по умолчанию). Я могу открыть COM4 с этим (MSP430), который для всех целей и задач является идентичным устройством. Я могу открыть COM5 с Termite, поэтому я знаю, что соединение хорошее). И нет, я не пытаюсь открыть их одновременно. Если вам нужна дополнительная информация, дайте мне знать, и я могу опубликовать больше.
Спасибо!
EDIT: я на третий день пытаюсь понять это и до сих пор не повезло. Я не понимаю, почему я могу получить доступ к этому COM через терминальную программу, а не по своему усмотрению, когда я вижу, что нет абсолютно никакой разницы. Кто-нибудь знает о программе, которая может "исследовать" COM-порт, чтобы увидеть его свойства (помимо диспетчера Windows, я имею в виду)? Я становлюсь довольно расстроенным и вроде как стоять в моем проекте, пока не узнаю об этом...
EDIT2: Я нашел очевидное обходное решение, но мне еще нужно заставить его работать здесь. Теперь я получаю несколько разных ошибок ввода-вывода, но по крайней мере это движение (не уверен, что это прогресс). Я также узнал, что это ошибка .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-to-go, или потому, что устройство также может быть хостом. Кто-нибудь сталкивался с этой проблемой? Это не объясняет, почему я могу использовать Termite (терминальная программа, для тех, кто просто присоединяется к нам). Я пытался найти терминальную программу с открытым исходным кодом, которая: а) работает и б) видит а). Как обычно, я отчитаю, если я открою здесь эту проблему, так как теперь я нашел бесчисленные форумы, на которых звучит эта проблема, относящаяся к 2006 году.
EDIT4: Так, в соответствии с приведенным советом, я загрузил приложение для мониторинга портов (я получил Eltima Serial Port Monitor), и он выглядит как проблема с бодом:
но, как ни странно, какой бы бод я ни устанавливал, он все еще терпит неудачу. А также может кто-нибудь объяснить, что означает "вверх-вниз"? Я пробовал искать его, но ключевые слова слишком общие. Как обычно, я буду сообщать о любых изменениях.
Кроме того, для записи я могу подключиться с помощью Eltima при бодах 115200 (так же, как Termite). К сожалению, это не работает в Visual Studio.
EDIT5: Наш сюжет имеет неожиданное завихрение. Я отслеживал, что происходит, когда Termite подключается к рассматриваемому COM-порту и BLAM! Термиты выдают ту же ошибку, что и моя программа, но игнорируют ее. Гений, да? Sloppy, но он работает. Теперь мне нужно научиться игнорировать IOExceptions. Я отчитаю, когда выясню, как это сделать.
EDIT6: Итак, как выясняется, это проблема скорости в бодах, но она идет глубже. Я использую программное обеспечение для мониторинга последовательного порта Eltima, и он очень интуитивно понятен и прост в использовании. Я бы рекомендовал его. После некоторых исследований я узнал, что вы не можете игнорировать это исключение и все еще подключаться к последовательному порту с использованием библиотеки .NET. Поэтому я должен углубиться в API Win32 и написать свой собственный. Я нашел несколько страниц, которые касаются этого, но, честно говоря, я никогда не делал ничего подобного раньше, так что может быть какое-то время, пока я не отчитаюсь, но я обязательно это рассмотрю и вернусь к каждому. Есть слишком много людей, которые страдают от этой проблемы. Я нашел довольно много форумов и веб-сайтов, где я могу видеть те же самые симптомы, но никто на самом деле ничего не сделал, кроме того, сказал: "Да,.NET сосет". Я планирую писать полный статический класс библиотеки, а затем публиковать либо на своем веб-сайте, и здесь, и где бы я мог. Надеемся, что .NET заметит (эта ошибка существует с версии 2.0). Я отчитаю, когда это будет сделано!
EDIT7: Это намного сложнее, чем я думал.
EDIT8: Я не знаю, если кто-то следит за этим или нет, но я хотел сказать, что я все еще нахожусь, но я выхожу из города на неделю в командировке. Я все еще рад услышать предложения и альтернативные идеи, хотя!