Поля ЩПТ меняться от экземпляра последовательный порт с#
Я пытаюсь эмулировать связь между существующей частью программного и аппаратного обеспечения, используя расширенный монитор последовательного порта, я смог придумать эту информацию о связи.
In/out queue size 1024/512 Purge the serial port: RXABORT, RXCLEAR, TXABORT, TXCLEAR Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=5000 Baud rate 115200 RTS on DTR off Data bits=8, Stop bits=1, Parity=None Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13 Handflow: ControlHandShake=(), FlowReplace=(TRANSMIT_TOGGLE, RTS_CONTROL), XonLimit=256, XoffLimit=256
Сначала я попробовал использовать встроенный класс SerialPort самостоятельно, но ему не хватает универсальности, чтобы выполнить такую задачу, а затем я попробовал использовать System.Отражение для установки полей DCB, но всякий раз, когда я прихожу к полю, которое начинается со строчной буквы f, например "fParity" или "fDtrControl", оно дает мне исключение NullReferenceException.
Есть ли какой-либо другой способ, которым я могу изменить эти значения, чтобы они соответствовали приведенным выше?
Это метод расширения, который я написал, позволяющий изменять поля DCB
internal static class SerialPortExtensions { [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static void SetFlag(this SerialPort port, string flag, object value) { if (port == null) throw new NullReferenceException(); if (port.BaseStream == null) throw new InvalidOperationException("Cannot change X chars until after the port has been opened."); try { // Get the base stream and its type which is System.IO.Ports.SerialStream object baseStream = port.BaseStream; Type baseStreamType = baseStream.GetType(); // Get the Win32 file handle for the port SafeFileHandle portFileHandle = (SafeFileHandle)baseStreamType.GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(baseStream); // Get the value of the private DCB field (a value type) FieldInfo dcbFieldInfo = baseStreamType.GetField("dcb", BindingFlags.NonPublic | BindingFlags.Instance); object dcbValue = dcbFieldInfo.GetValue(baseStream); // The type of dcb is Microsoft.Win32.UnsafeNativeMethods.DCB which is an internal type. We can only access it through reflection. Type dcbType = dcbValue.GetType(); dcbType.GetField(flag).SetValue(dcbValue, value); // We need to call SetCommState but because dcbValue is a private type, we don't have enough // information to create a p/Invoke declaration for it. We have to do the marshalling manually. // Create unmanaged memory to copy DCB into IntPtr hGlobal = Marshal.AllocHGlobal(Marshal.SizeOf(dcbValue)); try { // Copy their DCB value to unmanaged memory Marshal.StructureToPtr(dcbValue, hGlobal, false); // Call SetCommState if (!SetCommState(portFileHandle, hGlobal)) throw new Win32Exception(Marshal.GetLastWin32Error()); // Update the BaseStream.dcb field if SetCommState succeeded dcbFieldInfo.SetValue(baseStream, dcbValue); } finally { if (hGlobal != IntPtr.Zero) Marshal.FreeHGlobal(hGlobal); } } catch (SecurityException) { throw; } catch (OutOfMemoryException) { throw; } catch (Win32Exception) { throw; } catch (Exception) { throw; } } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool SetCommState(SafeFileHandle hFile, IntPtr lpDCB); }
И именно здесь я инициализирую все значения:
COM.Open(); COM.SetFlag("BaudRate", (UInt32)115200); COM.SetFlag("StopBits", (byte)0); COM.SetFlag("ByteSize", (byte)8); COM.SetFlag("Parity", (byte)0); COM.SetFlag("fDtrControl", 0x00); COM.SetFlag("fRtsControl", 0x01); COM.SetFlag("XonChar", 0x11); COM.SetFlag("XoffChar", 0x13); COM.SetFlag("XonLim", (ushort)256); COM.SetFlag("XoffLim", (ushort)256);
РЕДАКТИРОВАТЬ
При дальнейшем исследовании оказывается, что поля с префиксом f не входят в структуру DCB, используемую SerialPort по какой-то странной причине. Однако есть поле flags, но оно имеет тип UInt32, поэтому я не уверен, как его использовать, если у кого-то есть дополнительная информация о том, как использовать это поле, пожалуйста, отправьте его в качестве ответа или комментария.