简体   繁体   中英

USB serial communication with C#, Linux permission question

I am having a serial communication problem on Linux. I am trying to send and receive information between an arduino and the Unity3D engine which uses C# (mono) to open the serial communication. But I suspect that this is an issue with Linux permissions, which is why I post this here. I already added the user to the dialout group and serial communication is actually working when I compile and run the following C# using mono:

using System.IO.Ports;
sp = new SerialPort("/dev/ttyACM0", 9600);
sp.Open();

However, the same code in Unity3D at runtime tells me:

IOException: No such file or directory

The frustrating thing is that this is actually working on another Linux machine and I am having trouble understanding what the difference could be that is causing it not to work on the other.

Here are some differences on both systems:

The working Linux is Lubuntu 19 with the Unity3D installation inside of /home, which is on the same partition as root. The Unity3D version is 2019.2.

The non-working system is Linux Mint 19.3 with the Unity3D installation also in /home, but this is a different partition from root. The Unity3D version is 2019.3.

The permissions look slightly different too:

crw-rw----+ 1 root dialout 166, 0 mei  1 05:08 /dev/ttyACM0    --> Lubuntu
crw-rw---- 1 root dialout 166, 0 May  1 15:03 /dev/ttyACM0     --> Mint

Also:

getfacl /dev/ttyACM0

gives me the following on Lubuntu:

# file: dev/ttyACM0
# owner: root
# group: dialout
user::rw-
user:myname:rw-
group::rw-
mask::rw-
other::---

and the following on Linux Mint:

# file: dev/ttyACM0
# owner: root
# group: dialout
user::rw-
group::rw-
other::---

Does anyone have any insight into why in one scenario Unity3D can't access /dev/ttyACM0, while in the other one it can? Or any idea's how I might find out?

EDIT:

I played around a bit with the following to check what the program is allowed to read:

string[] fileArray = Directory.GetFiles(@"/dev");
    foreach(string s in fileArray)
    {
        Console.WriteLine(s);
    }

And when run inside of Unity3D only a handful of files are recognized, only those with "other" read permissions. In contrast, when I compile it outside of unity with mono, all the files in /dev are printed.

This confuses me, shouldn't Unity3D also be run with my user ID, and in turn have access to the dialout group permissions? Unity3D is launched through a launcher application, could this cause it to not be run as my user?

I would double check that the ACM device isnt reconnecting and being given ACM1/2/3 etc instead of 0. I've had the issue that it has timed out, reconnected and the number has incremented, because they are virtual this can happen very quickly and the system doesn't remove the previous devicefile before creating the new one. If you type dmesg into terminal it will show any re connections and what port they got assigned, running sudo dmesg -c will clear the output as it can be quite verbose.

Hope this helps. Hardware can be painful to work with sometimes.

I finally found the culprit. Apparently Unity3D recently changed their launcher (Unity Hub) to a sandbox version using flatpak, and for some reason /dev is blacklisted by default. To get around this Unity Hub should be launched with the parameter:

--device=all

The entire command to get this to work for me is:

/usr/bin/flatpak run --branch=stable --arch=x86_64 --device=all --command=start-unityhub com.unity.UnityHub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM