When I attempt to communicate with serial devices using PowerShell in Ubuntu 18, I get an “access denied” message when I try to open the port. I can create the port object with no problem:
$port = new-object system.io.ports.serialport ttyACM0
And I can verify the created port:
Echo $port
…yields all the specifics. But when I try to open the port so that I can begin reading or writing:
$port.open()
…access is denied. Is this a procedural error on my part, or a short-coming in the cross platform PowerShell itself? I’ve tried this with onboard serial ports as well as USB to serial devices with no success.
Use the strace program to check whether the PowerShell process is trying to open /dev/ttyACM0 and whether that succeeds. If the error is coming from there, you may have to ask the superuser to add your user account to the dialout group or change the permissions of the special file.
I've already tried adding to dialout group. Made no difference. Has anyone succeeded with serial com in powershell under linux?
Did strace show the open call failing with EACCES or EPERM?
I've already tried adding to dialout group.
Use id --groups --name to check whether the change took effect; perhaps it did not if you have not logged in again.
@chalk-x please change the issue title to summarize the issue instead of duplicating the issue body.
I've already tried to resolve this by adding to the DIALOUT group. And I did verify that the change took effect. This was to no avail. I will try the STRACE program and report the results soon.
First let me clarify...I'm not a programmer or software developer. I'm an end-user / scripter. And my understanding of STRACE is very rudimentary. I couldn't get any results trying STRACE with the PowerShell command $port.open(). So I launched PowerShell itself with STRACE, then executed the serial port commands. I saw nothing resembling EACCES or EPERM following the $port.open() command.
I hope someone out there with more expertise can determine whether this serial port access issue is a simple procedural error, or an actual bug in the cross-platform PowerShell. What say you guys spin up PowerShell on your Linux machines, give this a try and see if you can get to the bottom of it?
Here's the STRACE from the creation of the serial port to the "access denied", (attempting to access onboard serial port ttyS0):
futex(0x1e24c8$port = new-object system.io.ports.serialport ttyS0
) = 0
futex(0x1e24c30, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x1fefd84, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1fefd30, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1e24c84, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x1e24c30, FUTEX_WAKE_PRIVATE, 1) = 0
fcntl(1, F_DUPFD_CLOEXEC, 0) = 108
fstat(108, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}) = 0
read(47, "335O314327277t235h_2374103gy9", 16) = 16
read(47, "326326242b$302.345/33A_Z205x356", 16) = 16
read(47, "v320250315,377212212R2512122416244376,", 16) = 16
mprotect(0x7fba37dc7000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37dc8000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37daf000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37916000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37916000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mprotect(0x7fba37dc9000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37dca000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba316d3000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba316d3000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mprotect(0x7fba37dcb000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37dcc000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37dd0000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37917000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37917000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mprotect(0x7fba37dcd000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x7fba37dce000, 4096, PROT_READ|PROT_WRITE) = 0
futex(0x1fefd84, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1e24c80, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x1e24c30, FUTEX_WAKE_PRIVATE, 1) = 0
write(108, "PS /home/bob> ", 14PS /home/bob> ) = 14
read(47, "32330632336207y251375# 375030410364]", 16) = 16
futex(0x1fefd80, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1fefd30, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1e24> $port.open()T_PRIVATE, 0, NULL
) = 0
futex(0x1e24c30, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x1fefd80, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1fefd30, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1e24c80, FUTEX_WAIT_PRIVATE, 0, NULLMethodInvocationException: Exception calling "Open" with "0" argument(s): "Access to the port 'ttyS0' is denied."
) = 0
futex(0x1e24c30, FUTEX_WAKE_PRIVATE, 1) = 0
write(1, "33[6n", 4) = 4
read(0, "33", 1) = 1
read(0, "[", 1) = 1
read(0, "5", 1) = 1
read(0, "6", 1) = 1
read(0, ";", 1) = 1
read(0, "2", 1) = 1
read(0, "1", 1) = 1
read(0, "R", 1) = 1
write(111, "n", 1
) = 1
read(47, "2572513410235824XySoG32425242r", 16) = 16
futex(0x1fefd84, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1fefd30, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1e24c84, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x1e24c30, FUTEX_WAKE_PRIVATE, 1) = 0
write(111, "PS /home/bob> ", 14PS /home/bob> ) = 14
read(47, "C223342200)320<3262035c35224323rv", 16) = 16
futex(0x1fefd80, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1fefd30, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x1e24c8exitUTEX_WAIT_PRIVATE, 0, NULL
I see interesting activity in response to the request to create the port. Can anyone interpret whether or not ttyS0 was actually set up as requested? I see NO ATTEMPT at all to access tty in response to $port.open(). My uneducated guess is that cross-platform PowerShell is either incomplete / broken with regard to serial ports...or there is a missing permission somewhere.
Try /dev/ttyS0 rather than plain ttyS0.
Same result..."access denied". Are you testing any of these suggestions yourself?
OOPS! Tested your suggestion again on a different machine and, VIOLA, the port opened! I will now see if I can open two ports and bounce text between them.
I'll play with this more tomorrow. So far here's what I know: For this to work I must first lauch PowerShell with "sudo". Then I must create the port object using /dev/ttyS0. Both of these conditions are required for the port to open.
Works beautifully. I'm stoked.
Everything is working perfectly with the combination of "sudo" and /dev/ path. Frustrating that it took so long to find the right "combination" to unlock the serial ports. Thanks for all the help. Case closed.
Are you testing any of these suggestions yourself?
No, I don't have a suitable computer with serial ports.
The access-denied error was rather misleading. The code that throws the exception apparently uses UnauthorizedAccessException for Windows compatibility but adds the real reason (file not found) as an inner exception. PowerShell 7 now hides the inner exception by default but Get-Error should show the details.
Most helpful comment
@chalk-x please change the issue title to summarize the issue instead of duplicating the issue body.