Open ctacke opened 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @dotnet/area-system-io See info in area-owners.md if you want to be subscribed.
Author: | ctacke |
---|---|
Assignees: | - |
Labels: | `area-System.IO`, `untriaged` |
Milestone: | - |
We are most likely missing a mapping for the 250000
rate:
The managed layer checks only if the value is negative:
The native layer maps the value and returns a default value if no mapping is defined:
For default value, when HAVE_IOSS_H
is not defined an error is set and the method returns:
And then the managed layer throws:
@wfurt @krwq I am not familiar with how the TermiosSpeed2Rate
mapping works. Could you briefly explain what it does and how can we solve the problem?
termios supports even non-standard rates. It seems that instead of returning B0 and throwing an error, it would be more robust to use the supported TCSETS2 struct with BOTHER (like I'm doing in my workaround) to attempt to set the rate the user is requesting and only throw if that is unsuccessful. Let the underlying platform driver tell you if the requested rate is or is not supported. Beyond these common printers and their 250kbaud, if someone builds some custom machine with some strange clock and supported baud rate, it would still let managed code call it.
Part of the problem is fact that the PAL code is but agains some headers and it may miss capability of never kernels. It may be worth of adding missing defines as needed to support known speeds even if the build machine does not. And trying it as custom speed makes sense to me as well. I'm not sure how common that is but trying it and leaving the decision to the driver make sense to me.
I know this is old issue, but is 8.0 working for you @ctacke? I finally got setup where I can play with it and it seems to be working OK e.g. should be fixed by #80534. I think this issue could be closed.
Description
Trying to open a System.IO.Ports.SerialPort for 250000 baud under Linux gives an argument exception. Even if it didn't the underlying code would still fail to properly open that rate.
This is a common serial rate for many 3D printers, such as all Lulzbot printers.
Bot said to add an Area, but didn't say where. So here it is: @adamsitnik
Reproduction Steps
Running on any version of .NET (fails in 5 and 6) on a Raspberry Pi with the latest 32-bit Rasberry Pi OS, attempt to open a serial port:
Expected behavior
I expect it to open and be usable.
Actual behavior
An exception is thrown.
Regression?
No response
Known Workarounds
I have a known-good, working workaround. It's ugly, but works. First, open the port with a supported rate, like 115200. then run this code:
I told you it was ugly.
NOTE that this code is unsetting the
CBAUD
flag and then setting theBOTHER
flag, which the BCL does not do. Simply allowing 250000 baud through is not enough, the logic above must be applied.NOTE 2 the above is not the right way to do it in the BCL. The proper fix should be done in C in the PAL, somewhere in this method:
https://github.com/dotnet/runtime/blob/c12bea880a2f1290d16adf97ec1000aa63631da2/src/native/libs/System.IO.Ports.Native/pal_termios.c#L350
I would have done a fork and PR, but honestly I don't have the native toolchain set up, and that feels like a huge headache. Anyone with a little C knowledge can port the above into that file.
Configuration
.NET 5.0 Raspberry Pi 4 ARM
This is not specific to this configuration. I'm willing to bet it will fail on any Linux kernel.
Other information
Fix and where it belongs are detailed above