jcurl / RJCP.DLL.SerialPortStream

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.
Microsoft Public License
639 stars 199 forks source link

No Ports shown on Linux dotnet core 2.0 #30

Closed nzain closed 7 years ago

nzain commented 7 years ago

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

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?

nzain commented 7 years ago

Running the same code on a Win 10:

GetPortNames returned 2 items
 > port[COM3]
 > port[COM1]

This is not the same computer (at work now) and it is dotnet core 2.0.0-preview1-002111-00 (and of course a different native serial implementation).

I just found your wiki entry on "providing debug infos" - sorry for being late on this. I'll provide every info this evening from my private PC.

jcurl commented 7 years ago

Thanks for the report. Windows and Linux have two completely different implementations. Running on your Linux box uses the nserial library and is coded in the "portlinux.c" file. As described in the header there:

// We look in the path '/sys/class/tty/*' for a list of all TTY devices. Each
// TTY will be considered a real device if it contains a softlink
// 'device/driver' which is a symlink to the directory for the driver for the
// TTY. That then excludes a lot of the PTY (Pseudo TTYs).
//
// Then for each device, we look at the file 'dev' to get the major and minor
// device node. Once we have a list of all the device nodes, we then do a
// recursive search through '/dev' looking for any entries with those device
// nodes. If the device is of type 'platform:serial8250' which is readable
// by '/sys/class/tty/*/device/modalias', we will also open the device and
// check that it is a real serial port or not.

Probably the simplest explanation why you get zero devices is you do not have access (on a standard Linux, users are not in the dialup group). That is checked using the "access" system call.

// Check user has permissions before adding
        if (access(path, R_OK | W_OK)) {
          nslog(handle, NSLOG_WARNING, "getports: file not accessible: %s (errno=%d)", path, errno);
          continue;
        }

If you want to further debug, you can install google test. You can modify the build script to provide debugging of the native library itself (it's already there, but commented out)

CFLAGS="-O0 -g -Wall" cmake -DCMAKE_BUILD_TYPE=Debug -DNSLOG_ENABLED=ON .. && make

Then the library will write to /tmp/nserial.log.

jcurl commented 7 years ago

You can also install the google test framework and build, which you can test the cases on your PC. For most test cases, you'll need two serial ports with a NULL modem cable.

nzain commented 7 years ago

Thanks for the detailed description! Your assumption was correct, insufficient permissions (didn't know that only root can access those). Running the app as root indeed shows my connected ftdi on /dev/ttyUSB0:

$ dotnet ./demoapp.dll
GetPortNames returned 2 items
 > port[/dev/ttyAMA0]
 > port[/dev/ttyUSB0]

The next days will show, if this library works on my arm cortex-A7.

jcurl commented 7 years ago

You should add your user to the correct group rather than running as root. Cheers!

nzain commented 7 years ago

Agreed, but since I'm kind of experimenting for an embedded linux based on buildroot, there won't be any users :) In particular, there is no extra user for serial ports, they are owned by root:root.

# ls -l /dev/ttyUSB0 
crw-------    1 root     root      188,   0 Jan  1 00:00 /dev/ttyUSB0