Skip to content

Commit

Permalink
Fixes Threetwosevensixseven#3. Mono on Linux does not fire `DataRecei…
Browse files Browse the repository at this point in the history
…ved` events. Instead a thread must be used to constantly read from the serial port. Fortunately, only `SerialPort.cs` needed changing, as it appears entirely safe to pass a null event.
  • Loading branch information
brett-smith committed Nov 7, 2024
1 parent 7e20a6b commit 475bc7e
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions UARTReplacement/SerialPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Plugins.UARTReplacement
Expand All @@ -21,6 +22,8 @@ public class SerialPort : IDisposable
private bool enablePiGpio5Output = false;
private UARTTargets target;
private string logPrefix;
private System.IO.Ports.SerialDataReceivedEventHandler handler;
private Thread readThread;

/// <summary>
/// Creates an instance of the SerialPort class.
Expand All @@ -31,6 +34,7 @@ public SerialPort(string PortName, UARTTargets Target, System.IO.Ports.SerialDat
try
{
target = Target;
handler = dataReceivedHandler;
logPrefix = target.ToString().Substring(0, 1) + "." + (PortName ?? "").Trim() + ".";
if (string.IsNullOrWhiteSpace(PortName))
{
Expand All @@ -51,8 +55,19 @@ public SerialPort(string PortName, UARTTargets Target, System.IO.Ports.SerialDat
LogClock(oldBaud, baud, false);
LogPrescaler(oldBaud, baud, "");
if (dataReceivedHandler != null)
port.DataReceived += dataReceivedHandler;
port.Open();
{
if (IsRunningOnMono())
{
port.Open();
readThread = new Thread(new ThreadStart(this.ReadThread));
readThread.Start();
}
else
{
port.DataReceived += dataReceivedHandler;
port.Open();
}
}
}
catch (System.IO.IOException ex)
{
Expand Down Expand Up @@ -98,6 +113,21 @@ public void Write(byte[] buffer, int offset, int count)
}
}

public void ReadThread()
{
try
{
while(true)
{
Thread.Sleep(10);
handler.Invoke(port, null);
}
}
catch(ThreadInterruptedException) {
// normal at dispose
}
}

/// <summary>
/// If there is a byte available in the UART buffer return it, otherwise a value representing no data.
/// </summary>
Expand Down Expand Up @@ -404,6 +434,11 @@ public bool IsEnabled
return port != null;
}
}

public static bool IsRunningOnMono ()
{
return Type.GetType ("Mono.Runtime") != null;
}

/// <summary>
/// Convenience method to log the clock and calculated baud to the debug console, every time the video timing clock changes.
Expand Down Expand Up @@ -462,6 +497,8 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
// Dispose managed state (managed objects).
readThread?.Interrupt();

if (port != null)
{
if (port.IsOpen)
Expand Down

0 comments on commit 475bc7e

Please sign in to comment.