Compare commits
3 Commits
v1.1.0-pre
...
master
Author | SHA1 | Date | |
---|---|---|---|
cb7f331b6a | |||
1101b71faf | |||
582412f4dc |
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Nefarius.Peripherals.SerialPort;
|
namespace Nefarius.Peripherals.SerialPort;
|
||||||
|
|
||||||
@ -22,4 +23,14 @@ public class CommPortException : ApplicationException
|
|||||||
public CommPortException(Exception e) : base("Receive Thread Exception", e)
|
public CommPortException(Exception e) : base("Receive Thread Exception", e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommPortException(string message, int error) : base(message)
|
||||||
|
{
|
||||||
|
Win32Error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Win32 error that caused the exception.
|
||||||
|
/// </summary>
|
||||||
|
public int Win32Error { get; } = Marshal.GetLastWin32Error();
|
||||||
}
|
}
|
@ -22,6 +22,7 @@ public partial class SerialPort : IDisposable
|
|||||||
private readonly ManualResetEvent _writeEvent = new(false);
|
private readonly ManualResetEvent _writeEvent = new(false);
|
||||||
private bool _auto;
|
private bool _auto;
|
||||||
private bool _checkSends = true;
|
private bool _checkSends = true;
|
||||||
|
private CancellationTokenSource _cts;
|
||||||
|
|
||||||
private Handshake _handShake;
|
private Handshake _handShake;
|
||||||
private SafeFileHandle _hPort;
|
private SafeFileHandle _hPort;
|
||||||
@ -70,8 +71,12 @@ public partial class SerialPort : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
_hPort = PInvoke.CreateFile(PortName,
|
_hPort = PInvoke.CreateFile(PortName,
|
||||||
(uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE), 0,
|
(uint)(FILE_ACCESS_RIGHTS.FILE_GENERIC_READ | FILE_ACCESS_RIGHTS.FILE_GENERIC_WRITE),
|
||||||
null, FILE_CREATION_DISPOSITION.OPEN_EXISTING, FILE_FLAGS_AND_ATTRIBUTES.FILE_FLAG_OVERLAPPED, null);
|
0,
|
||||||
|
null,
|
||||||
|
FILE_CREATION_DISPOSITION.OPEN_EXISTING, FILE_FLAGS_AND_ATTRIBUTES.FILE_FLAG_OVERLAPPED,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
if (_hPort.IsInvalid)
|
if (_hPort.IsInvalid)
|
||||||
{
|
{
|
||||||
@ -80,7 +85,7 @@ public partial class SerialPort : IDisposable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CommPortException("Port Open Failure");
|
throw new CommPortException("Port Open Failure", Marshal.GetLastWin32Error());
|
||||||
}
|
}
|
||||||
|
|
||||||
_online = true;
|
_online = true;
|
||||||
@ -147,6 +152,7 @@ public partial class SerialPort : IDisposable
|
|||||||
_rxException = null;
|
_rxException = null;
|
||||||
_rxExceptionReported = false;
|
_rxExceptionReported = false;
|
||||||
|
|
||||||
|
_cts = new CancellationTokenSource();
|
||||||
_rxThread = new Thread(ReceiveThread)
|
_rxThread = new Thread(ReceiveThread)
|
||||||
{
|
{
|
||||||
Name = "CommBaseRx", Priority = ThreadPriority.AboveNormal, IsBackground = true
|
Name = "CommBaseRx", Priority = ThreadPriority.AboveNormal, IsBackground = true
|
||||||
@ -171,21 +177,25 @@ public partial class SerialPort : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
if (_online)
|
if (!_online)
|
||||||
{
|
{
|
||||||
_auto = false;
|
return;
|
||||||
BeforeClose(false);
|
|
||||||
InternalClose();
|
|
||||||
_rxException = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_auto = false;
|
||||||
|
BeforeClose(false);
|
||||||
|
InternalClose();
|
||||||
|
_rxException = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InternalClose()
|
private void InternalClose()
|
||||||
{
|
{
|
||||||
PInvoke.CancelIo(_hPort);
|
PInvoke.CancelIo(_hPort);
|
||||||
|
|
||||||
if (_rxThread != null)
|
if (_rxThread != null)
|
||||||
{
|
{
|
||||||
_rxThread.Abort();
|
_cts.Cancel();
|
||||||
|
_rxThread.Join();
|
||||||
_rxThread = null;
|
_rxThread = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +409,9 @@ public partial class SerialPort : IDisposable
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a single character has been received.
|
||||||
|
/// </summary>
|
||||||
public event Action<byte> DataReceived;
|
public event Action<byte> DataReceived;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -457,7 +470,7 @@ public partial class SerialPort : IDisposable
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (true)
|
while (!_cts.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
COMM_EVENT_MASK eventMask = 0;
|
COMM_EVENT_MASK eventMask = 0;
|
||||||
|
|
||||||
@ -474,7 +487,7 @@ public partial class SerialPort : IDisposable
|
|||||||
{
|
{
|
||||||
if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING)
|
if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING)
|
||||||
{
|
{
|
||||||
sg.WaitOne();
|
WaitHandle.WaitAny(new[] { sg, _cts.Token.WaitHandle });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -20,5 +20,7 @@ internal class Program
|
|||||||
serialPort.Write("START\r\n");
|
serialPort.Write("START\r\n");
|
||||||
|
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
|
|
||||||
|
serialPort.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user