Git Product home page Git Product logo

jcurl / rjcp.dll.serialportstream Goto Github PK

View Code? Open in Web Editor NEW
621.0 621.0 196.0 3.47 MB

SerialPortStream is an independent implementation of System.IO.Ports.SerialPort and SerialStream for better reliability and maintainability. Default branch is 2.x and now has support for Mono with help of a C library.

License: Microsoft Public License

Batchfile 0.09% C# 80.74% CMake 0.90% Shell 0.33% C 10.05% C++ 7.83% Dockerfile 0.07%

rjcp.dll.serialportstream's People

Contributors

amarok79 avatar ardave avatar jcurl avatar meinsiedler avatar tedvanderveen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rjcp.dll.serialportstream's Issues

Interface of SerialPortStream

Have there been any efforts or thoughts to add an interface for SerialPortStream? This would simplify the testing without having actual hardware connected to the computer and using just some fake implementations to return a stream of bytes.

Real-time serial communication requires fastest possible response times

The internal Read (and possibly Write) buffer introduces latency which might be significant. I think this actually isn't a SerialPortStream task (even more if not optional), since it violates the Single Responsibility Principle (SRP).

Imho, a dedicated (and configurable) BufferedStream class should take care of this, and not the SerialPortStream itself.

Further more, the example you gave:

So long as the process doesn't block, your main application might sleep for 10 seconds and you've still lost no data

Sounds like a bad practice at best :-) An I/O stream should operate as fast as possible, closest to the "low level" as possible, anyway this should be the default.

All in a constructive spirit, of course. Thank you for your great work and response.

Can not get port name correctly

I used SerailPortStreamCore package to enumerate the ports on Windows IoT Core on my Raspberry Pi 3. The demo is a console app in dotnet core 2.0 (published for win10-arm).
There is a Silicon Labs CP210x USB to UART Bridge plugged in the device.
But when i run the console app, the port name shows garbled. The result is same even though there is no any USB 2 UART controller plugged in.

dotnetcore version: 2.0
windows iot core:16299

Linux library names

After buliding packages for ubuntu (using dh_make to create the templates), the libnserial.so is in the "dev" package, while libnserial.so.1 and libnserial.so.1.0 is in the main package. Naturally, to get software working, we shouldn't include the "-dev" package, but just the single binary package.

Checking other packages in Ubuntu shows the same structure for non-mono libraries, so this is the way to go.

The DLL imports need to be modified to use "libnserial.so.1" instead (which is a little contradictory, because the mono docs suggest to use "nserial" where possible, so ".dll" or ".so" is attached depending on the platform. More important is the packaging for native binaries and making mono suit.

We should not use the config file for now that maps the nserial to libnserial.so.1, as some testing has shown that the dll.config file is not always reliably copied by building, and the user should be able to customise this for themselves for their specific project.

WinNativeSerial.IsOpen flag is always true

After physically severing the serial connection, the WinNativeSerial.IsOpen property is always true.
I have to mention that I'm using a USB to Serial adapter for testing. Regardless if I remove just the serial cable or disconnect the USB to Serial hub from the PC, the IsOpen flag is always true.

Regards,
Adrian V.

Device Error

I'm using an arduino style device (Teensy 3.5) at 115200 on COM3. I can open it just find with the Arduino monitor and it just prints an incrementing number on new lines (1, 2, 3, etc). Am I missing something really simple here?

IOException: Device Error
RJCP.IO.Ports.SerialPortStream.ReadCheckDeviceError (System.Boolean immediate) (at <98240c6c7bfd40d18eca5b369f29ae84>:0)
RJCP.IO.Ports.SerialPortStream.ReadTo (System.String text) (at <98240c6c7bfd40d18eca5b369f29ae84>:0)
RJCP.IO.Ports.SerialPortStream.ReadLine () (at <98240c6c7bfd40d18eca5b369f29ae84>:0)
(wrapper remoting-invoke-with-check) RJCP.IO.Ports.SerialPortStream:ReadLine ()
serial.Start () (at Assets/serial.cs:24)

I'm doing this from Unity 2017 running .NET 4.6.

using RJCP.IO.Ports;

SerialPortStream src = new SerialPortStream("COM3", 115200);
// This method runs once at startup.
void Start () {

    src.Open();
    string srcString = src.ToString();
        
    Debug.Log(srcString); // same as Console.Write
    Debug.Log(src.ReadLine().ToString());

}

// this runs once per frame until the program exits.
void Update() {
Debug.Log(src.ReadLine().ToString());
}

The wrong depency issue with nuget package

The nuspec has a dependency: dependency id="Microsoft.Win32.Registry" version="[4.3.0, )" . but it should be updated to 4.4.0 to work on Xamarin.iOS/Xamarin.Mac projects.

"Unable to clear the serial break state" exception in Open()

When calling SerialPortStream.cs:Open() on a serial port whose driver does not support clearing the serial break state an exception is generated and the port cannot be opened.

There is an attempt to catch this exception when setting the "BreakState" in SerialPortStream.cs:Open() but the exception is actually first generated before this point by the call to "m_NativeSerial.SetPortSettings()" (towards the end of this function the break state is set or cleared, causing the exception to be generated).

[SerialPortStream.cs]
        private void Open(bool setCommState)
        {
            if (IsDisposed) throw new ObjectDisposedException("SerialPortStream");
            if (IsOpen) throw new InvalidOperationException("Serial Port already opened");

            m_NativeSerial.Open();
            try {
                if (setCommState) {
                    m_NativeSerial.SetPortSettings(); **<--- EXCEPTION HERE**
                    // Fetch the actual settings and get the capabilities
                    m_NativeSerial.GetPortSettings();

                    try {
                        m_NativeSerial.BreakState = false;
                    } catch (System.IO.IOException) {
                        // Ignore IOException. Not all serial port drivers support clearing the
                        // Break signal, so we ignore it when opening.
                    }
                }
[WinNativeSerial.cs]

        /// <summary>
        /// Writes the settings of the serial port as set in this object.
        /// </summary>
        /// <exception cref="ObjectDisposedException"/>
        /// <exception cref="InvalidOperationException">Port not open.</exception>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
        public void SetPortSettings()
        {
            if (m_IsDisposed) throw new ObjectDisposedException("WinNativeSerial");
            if (!IsOpen) throw new InvalidOperationException("Port not open");

...snip...

            if (m_BreakState) {
                m_CommModemStatus.SetCommBreak();
            } else {
                m_CommModemStatus.ClearCommBreak(); **<--- EXCEPTION FROM HERE**
            }
        }

Reading same barcode returns different amount of bytes on Linux

Hello, using this library with ReadAsync() i get first time a good byte array and if i continue to scan the same barcode, it will start to give me different bytes array, some of them good but mostly bad, is there any solution for this? Using Windows i can't see the problem there, the problem just on Linux, i am using Kubuntu 16.04.

Testing Process

I'm interested in helping out, having used this project multiple times and now being free to assist. Only problem is I don't actually have any devices that use serial ports anymore because they were provided by my work.

Looking through the issues, it looks like you're only testing with physical devices, and doing most of the testing yourself. It would be useful to clarify your testing process, and whether you'd like tests to use certain physical devices or if software emulated devices would work as well.

Write Buffer Size for USB CDC Device (VCOM)

Hello. I have a microcontroller device that is set up as a USB CDC device, that creates a virtual COM port. I would like to write data to this device as fast as possible, and according to this StackOverflow question, I can maximize my throughput by writing 2 kB chunks in 1 ms intervals.

Is this possible using SerialPortStream? There are two questions related to this, from what I understand.

  1. Can Windows send data every 1 ms frame? Or will it be more like 10 ms?
  2. I see SerialPortStream.cs has a WriteBufferSize property. Should I be setting this to 2 kB, to match the settings of my microcontroller buffer? Or does the low-level driver need to have a buffer size of 2 kB? If so, is there any way to set this from SerialPortStream?

Remote peer could not receive the data send from RaspberryPi(based on Debian stretch) via SerialPortStream

Hi, thanks for the great work.
I'm using a USB to TTL with CP2102 chip.
this is via lsusb:
Bus 001 Device 009: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light

I've build your lib in my Pi, and then added the output file into my .NET Core 2.1 application, the application finally can run, and it even can listed the available serial port via SerialPortStream.GetPortNames(), what I get is /dev/ttyUSB0.
I want do sth more:

public void Test()
{
    SerialPortStream comPort = new SerialPortStream("/dev/ttyUSB0", 9600, 8, Parity.Odd, StopBits.One)
            {
                ReadTimeout = 5000,
                WriteTimeout = 5000
            };
    comPort.DataReceived += Port_DataReceived;
    comPort.Open();
    //pesudo code, send 0x5020FA every 1 second.
    timer.Fire(()=>{
        comPort.Write(new byte[]{0x50, 0x20,0xFA});
        logger.Debug("Msg send");
    }, 1000);
}
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    var buffer = new List<byte>();
    while (this.comPort.BytesToRead > 0)
    {
        var readByte = this.comPort.ReadByte();
        logger.Debug("RAW read: 0x" + readByte.ToString("X").PadLeft(2, '0'));                    
    }
}

by running this app, I can see the UsbToTtl's led for TX is blinking as expected.
for the remote peer side(a PC), I've opened a RS232 port, and connected PC Rx UsbToTtl's Tx, I noticed either I always received the E5, B7, and if I connected the PC Tx to UsbToTtl's Rx, the UsbToTtl's rx led will keep on, and will hang the Pi to death though I never send anything from PC, any idea?

How to access response data

If we use SerialPortStream to send characters to a COM port with WriteLine, we cannot get the response sent back.
The DataReceived event never fires and there is no data when we call Read after WriteLine, even if we wait for a few seconds.
There are no examples showing how to do this, and even the test code doesn't show how this is done.
Is it possible to get the response somehow?

Long delay when opening a serial port (around 30 seconds)

I am seeing a long delay when doing a .Open() on a serial port stream.
Delays of 15 to 30+ seconds are common.

A run of the VS 2015 performance profile shows that the delay appears to be in:

Ports.Native.Windows.CommModemStatus.ClearCommBreak().

Is this expected?
Note that this a USB virtual COM port.

Exception when writing data to serial port und raspberry pi

Hey!

I have no idea but I get an exception if I want to write data to the serial port. Could you help me please?

`Calling
await _stream.WriteAsync(buffer, 0, buffer.Length);

Unhandled Exception: System.Exception: Error 5
at RJCP.IO.Ports.Native.UnixNativeSerial.ThrowException()
at RJCP.IO.Ports.Native.UnixNativeSerial.SetPortSettings()
at RJCP.IO.Ports.SerialPortStream.Open(Boolean setCommState)
at RJCP.IO.Ports.SerialPortStream.Open()
System.NotSupportedException: Stream does not support writing.
at System.IO.__Error.WriteNotSupported()
at System.IO.Stream.BeginWriteInternal(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state, Boolean serializeAsynchronously, Boolean apm)
at System.IO.Stream.BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_1(Object state) at System.Threading.QueueUserWorkItemCallbackDefaultContext.WaitCallback_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.QueueUserWorkItemCallbackDefaultContext.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch()

Closing/disposing a port doesn't throw an exception on blocking methods

First let me say this library looks great, a very impressive achievement considering the history of System.IO.Ports.SerialPort.

Shouldn't blocking Read/Write/etc raise ObjectDisposedException (or at least IOException and then on consequent calls ObjectDisposedException) when the SerialPortStream is being closed/disposed?

Sample code

It would be awesome to have some small example code for this library. Especially for serial-noobs like me.
I have looked at the tests to try to figure it out, but some sample code would help alot.

FileNotFoundException when calling GetPortNames()

Hi! I am running a UWP-App to test the Library. The first step in opening a new port was to check if it is available. But when I called SerialPortStream.GetPortNames() the FileNotFoundException was thrown with the description: "Could not load file or assembly 'Microsoft.Win32.Registry, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'"
OK, without validating the existence of the port I wanted to connect via

try
{
    string[] ports = SerialPortStream.GetPortNames();
    SerialPortStream sps = new SerialPortStream("COM3", 57600, 8, Parity.None, StopBits.One);
    sps.Open();
}
catch(Exception ex)
{
    Debugger.Break();
}

This led to "Access Denied: COM3"
There is no problem accessing the port with other tools like HTerm, and unlike #11 there is definitely no other program talking with the port, and there is no possiblilty to have an error like #38 because the above lines of code are the only ones existing. So I downloaded and referenced the source and the error happens here:

m_ComPortHandle = UnsafeNativeMethods.CreateFile(@"\\.\" + PortName,
                NativeMethods.FileAccess.GENERIC_READ | NativeMethods.FileAccess.GENERIC_WRITE,
                NativeMethods.FileShare.FILE_SHARE_NONE,
                IntPtr.Zero,
                NativeMethods.CreationDisposition.OPEN_EXISTING,
                NativeMethods.FileAttributes.FILE_FLAG_OVERLAPPED,
                IntPtr.Zero);

as the returned handle is invalid (-1) and the WinIOError() @ int e = Marshal.GetLastWin32Error(); shows a 5 leading to UnauthorizedAccessException.
Do you have a hint where to search for a possible mistakes?

Device Error

Trying to read output from Arduino Uno clone (with CH340 on board):

var arduino = new SerialPortStream("COM6", 9600, 8, Parity.None, StopBits.One);
arduino.DtrEnable = true;

arduino.Open();

while (true)
{
    Console.Write(arduino.ReadExisting());
    System.Threading.Thread.Sleep(1000);
}

ReadExisting() throws:

Unhandled Exception: System.IO.IOException: Device Error
   at RJCP.IO.Ports.SerialPortStream.ReadCheckDeviceError(Boolean immediate) in c:\Users\jcurl\Documents\Programming\HELIOS\serialportstream\code\SerialPortStream.cs:line 629
   at RJCP.IO.Ports.SerialPortStream.ReadExisting() in c:\Users\jcurl\Documents\Programming\HELIOS\serialportstream\code\SerialPortStream.cs:line 931
   at ArduinoReader.Program.Main(String[] args) in C:\Users\Andrei\documents\visual studio 2017\Projects\ArduinoReader\ArduinoReader\Program.cs:line 17

Same code with System.IO.Ports.SerialPort works fine.

Windows 10 x64 1703, .NET 4.6.1

Open port error

I get error on open port.
Exception thrown: 'System.IO.IOException' in RJCP.SerialPortStream.dll
Additional information: Unknown error 0x79: COM7

Sometimes also Unknown error 0x490: COM7

open_details

Info on web:
0x79 - ERROR_SEM_TIMEOUT - The semaphore timeout period has expired.

It helps only if i resrtart bluetooth. Another info is that i do not have problems with all bluetooth devices.
Can this be fixed somehow ?

symbol lookup error: ~/bin/usr/local/lib/libnserial.so.1: undefined symbol: pthread_once

Hello
I first compiled the support library libnserial.so for yokto-linux. (With Crosscompelling). I early install cmake in my Host.
After cloning the repository, I executed the following:
$ git clone https://github.com/jcurl/serialportstream.git
$ cd serialportstream/dll/serialunix
$ ./build.sh

After I started my programs I get the following errors:
./dotnet: symbol lookup error: path/bin/usr/local/lib/libnserial.so.1: undefined symbol: pthread_once
how can I solve this?

Access Denied: COM4

I'm receiving an UnauthorizedAccessException when calling Open(). The port can be opened by other apps. This is Windows 10, VS 2k15 and .net 4.6. Thanks.

    public async Task<MspResponse> SendMessage(MspCodes mspCodes, byte[] data = null) {

        var signal = new SemaphoreSlim(0, 1);
        var response = new MspResponse(MspCodes.MSP_API_VERSION);

        using (var serialPortStream = new SerialPortStream(PortName, BaudRate)) {
            serialPortStream.WriteTimeout = 100;
            serialPortStream.ReadTimeout = 100;

            serialPortStream.DataReceived += (sender, args) => {
                try {
                    var sps = sender as SerialPortStream;
                    if (sps == null) return;

                    var readBuffer = new byte[sps.BytesToRead];
                    sps.Read(readBuffer, 0, readBuffer.Length);
                    if (sps.IsOpen) sps.Close();
                    response = DeserializeMessage(readBuffer);
                } finally {
                    signal.Release();
                }
            };

            try {
                if (!serialPortStream.IsOpen)
                    serialPortStream.Open();
            } catch (UnauthorizedAccessException exception) {
                Debug.WriteLine(exception.Message);
                throw;
            }


            var request = new MspRequest(mspCodes, data);
            var buffer = SerializeMessage(request);
            serialPortStream.Write(buffer, 0, buffer.Length);

            await signal.WaitAsync(10000);
        }

        return response;
    }

Access Denied: COM3

Hi, I am using Serial Port Stream on .NET 4.5.1 / Windows 10 Pro x64 as a replacement for the default SerialPort implementation in the .NET Framework. However, when I go to open my port, I get an access denied exception.

 public bool IsConnected
 {
     get {
         if (!isConnected.HasValue) {
            mutex.WaitOne();
            if (!serialPortStream.IsOpen) { serialPortStream.Open(); } // Exception thrown here.
            ...
         }
    }
}

The stack trace is as follows.

 at RJCP.IO.Ports.Native.WinNativeSerial.WinIOError() in c:\Users\jcurl\Documents\Programming\HELIOS\serialportstream\code\Native\WinNativeSerial.cs:line 937
 at RJCP.IO.Ports.Native.WinNativeSerial.Open() in c:\Users\jcurl\Documents\Programming\HELIOS\serialportstream\code\Native\WinNativeSerial.cs:line 845
 at RJCP.IO.Ports.SerialPortStream.Open(Boolean setCommState) in c:\Users\jcurl\Documents\Programming\HELIOS\serialportstream\code\SerialPortStream.cs:line 245

Any idea why this might be happening? The implementation I was using before with the SerialPort from .NET Framework was working fine, and I can open the port using Advanced Serial Port Monitor with no problems.

This is the serial port in Device Manager.
serialport

Linux Arm

I am so happy to have found this library!
I would like to use it with .NET Core on a Raspberry PI.
So far I was able to compile it with .NET Core on my Windows machine.
As I am not (yet) a Linux expert:
Your libnserial debian packages only include x86, x64.
Do you think there will be any problems compiling it on an ARM86 (Raspberry PI) with Ubuntu 16.04?

.net core

Has this been tested against core? I would like to be able to use it for both Mac and Windows. Thanks!

Large number of allocations resulting from tracing, even though it's disabled

I currently investigate memory allocations of an application, which uses your library. My usage scenario consists of a short message sent to a serial device, then waiting for a response and then do that again. When talking to the serial device every 15-20 ms, I see a number of allocations coming from your library.

I noticed a large number of allocations (~ 11 KB/sec) coming from a single location that can be easily improved. Please, see PR #57 for that.

Next, I see allocations coming from your use of TraceSource for tracing, which generates ~35 KB/sec in my scenario, even though tracing is disabled. This comes mainly from boxing arguments and from TraceSource itself.

I would like to reduce allocations here, but don't know how to proceed.

Basically, we need to rewrite every

SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0,
    "{0}: SerialThread: ProcessWriteEvent: {1} bytes - Purged", m_Name, bytes);

to something like

if (IsTracingEnabled)
{
    SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0,
        "{0}: SerialThread: ProcessWriteEvent: {1} bytes - Purged", m_Name, bytes);
}

This additional if(..) will ensure that we don't box arguments if not really necessary.

Now, TraceSource itself doesn't support something like IsEnabled, thus, there is no way to determine whether tracing has been enabled or not.

I would propose to introduce another BooleanSwitch into code, so that we can check condition. But, that would mean developers need to add another line to their app.config for enabling tracing (in addition to https://github.com/jcurl/SerialPortStream/wiki/Tracing).

Something like this would be necessary.

<?xml version="1.0" encoding="utf-8" ?>
 <configuration>
   <system.diagnostics>
     <switches>
       <add name="SerialPortStreamTracingEnabled" value="true" />
     </switches>
   </system.diagnostics>
 </configuration>

What do you think?

Thread Names on Linux

On linux the thread names for the UnixNativeSerial threads are too long to be of any use. As a result the two threads are indistinguishable.

Perhaps shorten the prefix to "UNS"

Assembly 'RJCP.SerialPortStream' in NuGet /netstandard1.5 folder misses PublicKeyToken; version 2.1.3

Hello!

I encountered a problem when using your library in a .NET Standard 2.0 library of myself that is then used in a .NET 4.7.1 console app. The issue arises from a PublicKeyToken mismatch in the different assemblies you deploy with your NuGet package.

For instance, your net40 and net45 assemblies have a PublicKeyToken of 5f5e7b70c6a74deb, whereas your netstandard1.5 assembly has none.

Now, a .NET Standard 2.0 library will generally bind to your netstandard1.5 assembly, which has no PublicKeyToken. When I then use this .NET Standard 2.0 library in another .NET 4.7.1 console application - which is by the way a common use case - then this console application will bind to the net45 version of RJCP.SerialPortStream, which has a PublicKeyToken.

In such situation, compilation works fine, but at runtime, I get a System.IO.FileLoadException: 'Could not load file or assembly 'RJCP.SerialPortStream, Version=2.1.3.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)' exception, which is caused by the different PublicKeyTokens.

I would expect to have all assembly variants in a NuGet package to have the same PublicKeyToken, meaning your .NET Standard 1.5 assembly should be strong-signed too.

No Ports shown on Linux dotnet core 2.0

I'm using dotnet core 2.0 (preview 3 at the time of writing) on

  • x64 Debian Stretch Linux
  • armhf "selfmade" buildroot 2017-3 linux

I followed your instructions on compiling the serialunix library (I don't say libnserial to avoid confusion with the very common libserial library) and installed it on both target systems. Finally, setting the $LD_LIBRARY_PATH accordingly allows the following simple code to run without a DllNotFoundException.

            string[] portnames = SerialPortStream.GetPortNames();
            Console.WriteLine("GetPortNames returned {0} items", portnames.Length);
            foreach (string name in portnames)
            {
                System.Console.WriteLine(" > port[{0}]",  name);
            }

However, on both machines the result is empty:

nzain:~/git/demoapp$ dotnet run
GetPortNames returned 0 items

Any ideas? How can I debug this problem?

I/O Thread crashing?

Hi
First of all, thank you very much for this library! It is very useful and much appreciated.
However, I have bumped into a problem where the I/O thread is closing down after a while when a try to send a large amount of text data (~160kB). The data is sent by calling WriteLine with approximately 3600 lines of 44 characters. But after 1000-2000 lines (not same every time) I get the exception:

System.InvalidOperationException occurred
HResult=-2146233079
Message=Serial I/O Thread not running
Source=RJCP.SerialPortStream
StackTrace:
at RJCP.IO.Ports.SerialPortStream.Write(String text) in c:\Users\jcurl\Documents\Programming\HELIOS\serialportstream\code\SerialPortStream.cs:line 1274
at RJCP.IO.Ports.SerialPortStream.WriteLine(String text) in c:\Users\jcurl\Documents\Programming\HELIOS\serialportstream\code\SerialPortStream.cs:line 1296
at SimpleTestApp.Interface.TerminalInterface.WriteLine(String text) in C:\Mattias\SimpleTestApp\SimpleTestApp\Interface\TerminalInterface.cs:line 136
InnerException:

I have managed to enable trace:

IO.Ports.SerialPortStream Verbose: 0 : COM12: SerialThread: ProcessWriteEvent: 4048 bytes
IO.Ports.SerialPortStream Verbose: 0 : COM12: SerialThread: DoWriteEvent: WriteFile(1884, 61923013, 4488, ...) == False
IO.Ports.SerialPortStream Verbose: 0 : COM12: SerialThread: ProcessWaitCommEvent: EV_TXEMPTY
IO.Ports.SerialPortStream Verbose: 0 : COM12: CommEvent: EV_TXEMPTY
IO.Ports.SerialPortStream Verbose: 0 : COM12: SerialThread: ProcessWriteEvent: 4488 bytes
IO.Ports.SerialPortStream Verbose: 0 : COM12: SerialThread: DoWriteEvent: WriteFile(1884, 61927501, 5192, ...) == False
IO.Ports.SerialPortStream Verbose: 0 : COM12: SerialThread: ProcessWaitCommEvent: EV_TXEMPTY
IO.Ports.SerialPortStream Verbose: 0 : COM12: CommEvent: EV_TXEMPTY
IO.Ports.SerialPortStream Error: 0 : COM12: SerialThread: Overlapped WriteFile() error 121 bytes 0
IO.Ports.SerialPortStream Error: 0 : COM12: SerialThread: Died from The semaphore timeout period has expired. (Exception from HRESULT: 0x80070079)

This problem is verified on two different Windows 10 computers using SerialPortStream 2.1.1.0. I can send the file without problems using TeraTerm.

Du you have any thoughts about what could be the problem?

Building libserial on macOS

Hi

EDITED To show the final process to build in mac.

I've just tested the library using macOS and Net Core 2.0.
Just preliminar, but seems to be working fine so far. Port enumerations (GetPortDescriptions/GetPortNames) don't seem to work, but reading/writing are working fine.

Just made some changes in order to build the dll on the mac, and i am writing them here, just in case anyone is interested.

Disclaimer: i was focusing on building the serial library and had some problems building gtest, so i removed the tests building . I'll try to get them to build when i have some free time. So, i don't recommend this procedure unless you know the risks of using an untested dll.

Just open the dll cmake file, /dll/serialunix/libnserial/CMakeLists.txt , and change this line:

FRAMEWORK ON
with this:

if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")  
  FRAMEWORK OFF 
else  
  FRAMEWORK ON 
endif()

It just disables the framework if built on macos and keep it as it was in other systems.
Now you can build it. The include and library files will be located in the subfolder ./bin/usr/local

You can keep them there or copy then to your preferred location. Take into account that you need to include the path to the libraries in LD_LIBRARY_PATH so that your app can find them.

One last step. The source code is looking for a library called libnserial.so.1 , so you need to rename the library or create a symbolic link with that name. In my case, i installed the library in /usr/local/lib, so i had to create the link like this:

ln -s /usr/local/lib/libnserial.dylib /usr/local/lib/libnserial.so.1.dylib

That's it. Did not test it much, but at least i got to send/receive data using .Net core on a mac, which is great.

thanks for this awesome piece of software!!

Read(..) timeout

Just found that calling .Read(..) that if no data is available to be read within the ReadTimeout period, that a "TimeoutException" does not occur.

That is the behaviour in the original .NET SerialPort. Was easy to work with (just check for 0 bytes read).

I honestly like the non-exception way better, but if you're going for backwards compatibility, it will be a breaking change from SerialPort.

Infinite timeouts in 2.0 Core

Setting the Read/Write timeouts doesn't seem to do anything in .NET Core 2.0, running version 2.1.2.

Calling Read() blocks forever, as does ReadAsync with a cancellation token. The token is triggered, but the ReadAsync method continues to block. This is both on Windows and Linux ARM.

The only workaround I've found is brutal - spin off the reads into a separate process so that the process can be completely shutdown should a device fail to respond.

Library Documentation

Where can I find documentation explaining the methods/events/properties of this library?
Thanks

Does a blocking read byte method exist?

Hi there

Please pardon my ignorance, but i'm looking for the simplest possible method (imho) and not finding it - a way to read a byte from the stream when it becomes available. I'm happy to block until the byte arrives.

Please can you point me to such a method?

Thanks!

Including SerialPortStream in Visual Studio Installer Setup Project

I'm trying to make a Setup Project using Visual Studio Installer in VS2015, with a project where I'm using SerialPortStream. But when building the setup project, I get the following warning message:

------ Starting pre-build validation for project 'PoseidonSetup' ------ 
WARNING: Unable to find dependency 'MONO.POSIX' (Signature='0738EB9F132ED756' Version='4.0.0.0') of assembly 'RJCP.SerialPortStream.dll'
WARNING: Unable to find dependency 'MONO.POSIX' (Signature='0738EB9F132ED756' Version='4.0.0.0') of assembly 'RJCP.SerialPortStream.dll'
WARNING: Unable to find dependency 'MONO.POSIX' (Signature='0738EB9F132ED756' Version='4.0.0.0') of assembly 'RJCP.SerialPortStream.dll'
------ Pre-build validation for project 'PoseidonSetup' completed ------

Do you know what this is? I'm not manually adding any dependencies, and RJCP.SerialPortStream.dll gets added automatically.

Intermittent serial port issue - no data is written.

Great library! Thanks for building this for the community. I'm using this in a project and am running into a very strange issue. We have a windows service running on a 64bit Windows 10 Enterprise machine that maintains an open SerialPortStream connection to a peripheral. At seemingly random intervals our calls to SerialPortStream.Write fail to send data over the COM port. The method call does not fail and no errors are returned. I've turned on diagnostic tracing for the SerialPortStream library and can see when it switches from writing data to failing to do so. I have attached a sample log below. Any ideas? Your insight is greatly appreciated.

LogSample.txt

Just a note, I do not have a command timeout set on this SerialPortStream.

DiscardInBuffer

Hello,
First of all thumbs up for the good work.
Second I got an

Unhandled exception System.NotImplementedException in mscorlib
System.NotImplementedException
The method or operation is not implemented.

when using the method DiscardInBuffer with Mono on Linux.
I have run some tests and found out that this method also didn't work before the update.

Receiving 00 Bytes on Linux-ARM

I'm trying to use this device as a Modbus master. Communication seems to work partially: for each request I receive a response with the expected number of bytes. However those bytes are all 00s!

Tx: 02-04-03-E7-00-35-80-5D

// expecting a 332 Bytes response

Rx: 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
LEN: 332

(The slave answers correctly when queried from another device)

Parity setting

Using the default constructor, if i set parity before opening,(in my case to odd), once i open the port the parity becomes none, and I have to set the parity to odd after opening the port for it to work.

using the constructor SerialPortStream(string port, int baud, int data, Parity parity, StopBits stopbits) also fails in keeping the parity setting once the port is open.

What are these dependecies ?

Hello

I'm trying to update/install SerialPortStream 2.1.1, but there is a large list of dependencies which were not there in the version 2.0.3 (see attached image). Why are these and how to get rid of them? Is that a problem in the NuGet package, because I can't see these dependencies in the source.
I'm using Visual Studio 2015 and .Net 4.6.2 project, but it makes no difference if I choose 4.5.2.
spsdeps
.

Pin Monitor 100% CPU

The TIOCMIWAIT ioctl returns EINVAL on some drivers/hardware. This results in 100% CPU usage for the thread as instead of blocking the function call immediately returns.

Perhaps it would be better to just introduce a delay (sleep) in cases like this since you can't wait on pin changes on this hardware.

Support VS 2017 Net Standard / Net Core Project Types

Currently the Net Standard 1.5 project type is the old json based project type. Is there a roadmap to update to the standard xml .csproj type that Microsoft added in VS 2017?

Are there any plans to transition from packages.config and move to PackageReference?

Unable to use COM ports after some times

Hi,

Thanks a lot for your great lib.

I am trying to use it to communicate with 3 systems at the same time:

  • One system is used to open or close automated Beer spout. This one I write to and it returns back an aknowledgement
  • Two systems I basically read from (with a listening thread) telling me how much beer is taken by the user. When I receive a message, I send back a short acknowledgement (the Flush method call you will see below)
    It works during some times, but fails at some point in time. In a nutshell, I can still use the first system correctly, but the two other ones I cannot read from anymore.
    I could attach to the process and can see the two listening threads (one for each COM port), trying to flush the acknowledgements I send.

We can also see 4 other threads related to COM but that I do not manage. I believe these are coming from your lib. More details in the screnshots below.

By the way, I am running Windows Server 2012 R2 with 3 USB to RS232 cables (PL23030 chipset).

Do you have an idea why this could occur? Deadlock?

Thanks a lot for your help
Christophe

allthreads
com_1
com_2

Write large data(~128kB) will cause out buffer wrap around

Hi Jason,

I tested the 2.0.0 release, and found a weird bug.

I need to write about 1MB data through UART. Each time I write 256 bytes (as a page) and wait for slave ack. When about 128kB data is writed, slave received the first page I've wrote.

I tried to flush and discard out buffer after every 256 bytes write, and this problem is resolved.

I have no time to read through the code to analysis what happened.

I can do more test if you need.

Regards.

lost SerialDataReceivedEventHandler

the transition from version 1.2 from nuget to 2.x from github, lost SerialDataReceivedEventHandler.

Severity Code Description Project File Line Suppression State
Error CS0246 The type or namespace name 'SerialDataReceivedEventHandler' could not be found (are you missing a using directive or an assembly reference?) SerialPortCommunication C:\work\C#\SerialPortCommunication\MyComm.cs 300 Active

using RJCP.IO;
using RJCP;
using RJCP.IO.Ports;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.