-
Notifications
You must be signed in to change notification settings - Fork 761
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows support for SerialPort #3809
Conversation
Signed-off-by: Tim Blechmann <tim@klingt.org>
rethrow any ctor exceptions to get better messages
will throw if both are set to true
test pointers directly; remove redundant casts
…throwing this matches the language level interface
deprecate timeout argument, return boolean for put
- change the way callbacks work at end of life - deprecate cleanupAll - use dedicated isOpen variable instead of dataptr introspection - add TODOs & comments
OK, this is ready for testing and review. I have updated the top comment with info on the changes. |
make extra clear this is a private method\!
…ible thanks to @scztt for catching this
Has anyone else had a chance to look at this yet? @scztt and I walked through the logic together and found small issues with GC and state that I've taken care of in the last few commits. It would be nice if someone could try hooking it up to a pre-existing system (Arduino, etc.) to do some real-world sanity testing. |
have verified the tests pass on Linux. going to get a Windows build up this week and test out with an arduino. |
okay i am STILL getting set up on windows because i am a dumb ass of life, but i have gotten a chance to test reading and writing bytes on linux with an actual arduino uno. serialtest.ino: void setup() {
Serial.begin(9600);
}
int incomingByte = 0;
void loop() {
if (Serial.available() <= 0) {
return;
}
incomingByte = Serial.read();
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
} supercollider code: (
var port;
port = SerialPort("/dev/ttyACM0", baudrate: 9600);
Routine.run {
var character, line;
loop {
character = port.read.asAscii;
(character == $\n).if {
line.notNil.if { line.join("").postln };
line = List[];
} {
line.add(character);
};
};
};
Routine.run {
var i = 0;
loop {
port.put(i);
i = i + 1;
1.wait;
};
};
) i haven't tested every implemented feature, but this is good news -- seems to be working great. |
update: got it working on windows! one bug is that we don't have EDIT: the latter link tells us that we can get a list of devices, identical to that of the arduino IDE, by running
so all we have to do is parse this. |
This commit adds a working implementation of SerialPort.devices for Windows by inspecting the HKLM\HARDWARE\DEVICEMAP\SERIALCOMM registry key.
This commit makes the following changes to SerialPort.devices: - Add more rules for matching device patterns, imported from the Arduino IDE. - Document SerialPort.devicePattern as a legacy feature. It makes two wrong assumptions: - Devices can be effectively matched using simple file globbing (Linux/macOS require regexps, and Windows requires running a command and parsing its output). - SerialPort.devices actually needs this kind of customization. It's not hard at all to get finer control by post-processing its output or just rewriting this simple method. - Emit a deprecation warning if a number is passed for the "port" argument to SerialPort. Brittle and unnecessary convenience.
latest commit has a minor API change -- i improved the matching rules for |
This commit disables one non-functioning SerialPort test, and skips SerialPort tests if the OS is Windows or it is determined that the socat utility is not installed. There is currently no skip mechanism in UnitTest, and due to time constraints we can't implement it right now. So I've just hacked it together using a guard clause.
in the interest of pushing this along, i have commented out a nonfunctioning unit test and have used guard clauses to skip the tests if we're on Windows or if the "socat" utility is not installed. |
Updated the tests, I believe based on the discussion at the dev meeting that this should be good to go now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!
Just saw that this is going on, great work! Some remarks (without having tested things yet; I'm quite out of sync with the latest SC developments):
|
I'm not sure if there is a question here?
Yes, that is what |
thanks for looking at the PR. i changed the device matching behavior, so i should be the one to justify it.
a major problem is that the serial port primitives aren't coupled to the device matching behavior. due to the complete decoupling of device matching and serialport creation, there really isn't any need for a user to customize |
ok. that makes sense. |
This PR adds Windows support for SerialPort and reworks the entire SerialPort class. Fixes #1008.
Based most of this off @timblechmann 's prior work.
Since we are now introducing this feature on a new platform, I thought this would be a good time to update the API/behavior a bit. I'm pretty sure I've done this in a non-breaking way for sane usage.
The main changes are:
cleanupAll
, no longer needed (see below)put
andputAll
- this just seems like bad design to me.put
will fail if there is an error writing; I don't think it's a good idea to go into an infinite loop trying to write at that point.isOpen
variable instead of the dataptr directly to determine open status (makes shutdown simpler)doneAction
- in general I think we're trying to cut down on overbearing posts.When
close
is triggered, a complex sequence of events happens:prDoneAction
close
eventually yields, allowing the SerialPort'sprDoneAction
to run on a separate threadprDoneAction
causes a deferred call toprCleanup
. At this point, not deferring would lead to a crash, because the C++ object's destructor needs its read thread to join, which would mean we are trying to join a thread from that thread itself - deadlock. This SC thread yields.prCleanup
sets the dataptr to nil and destroys the C++ object, and the read thread can now safely join.I don't know if there's a simpler way to do it, probably so, but this seems dead clear and doesn't potentially leak memory like the previous implementation did (AFAICT). It also means that the entire machinery of cleanup can be handled from the front by just
close
alone. Having separate user facing methods forclose
andcleanup
was IMO unnecessary baggage.Also included are tests for SerialPort. Unfortunately, I tried but was unable to find a programmatic way to run these tests on Windows; I would appreciate some manual testing from Windows users!
It would also be delightful to know if this compiles on RPi.
Quick progress checklist: