Open jacobrosenthal opened 9 years ago
Linux/OSX normal ioctl setup, and custom baud on linux
serinfo.flags &= ~ASYNC_SPD_MASK;
serinfo.flags |= ASYNC_SPD_CUST;
ioctl(fd, TIOCSSERIAL, &serinfo);
ioctl(fd, TIOCGSERIAL, &serinfo);
osx we use a different ioctl call to do custom baud if (ioctl(fd, IOSSIOSPEED, &speed) == -1) {
Then we set control and break codes with TIOCMSET TIOCM_RTS | TIOCM_CTS | TIOCM_DTR | TIOCM_DSR TIOCSBRK TIOCCBRK
Tagging @nebrius and linking to https://github.com/libuv/libuv/pull/379
@jacobrosenthal @dtex @nebrius This seems like the issue where we're tracking built in serialport support to libuv. I was about to close this but it seems.. pertinent. Anyone know how that's going?
I had a long discussion with @jessicaquynh and @TheAlphaNerd about moving this forward.
As of today this is what the bindings
interface looks like. Full Documentation
list
returns a list of objects describing available serialportsopen
takes a path and options, opens a file handle, and configures the port's baudRate, parity, stopbits, locking, and flow control.close
closes the file handleread
mimics fs.read but is guaranteed to read at least one byte (abstracting away uv_poll
/epoll
/I/O Completion Ports
)write
mimics fs.writeFile
set
/get
sets and gets flow control flags and break status (probably conflated)flush
/drain
flushes and drains the port at the os level.update
updates the buadrate of an open port (maybe more options in the future, not well defined yet)This are the nodejs interfaces I wish I had that would allow me to not use any c/c++
fs.poll
a callback interface to let me know the port is readable, writable, or disconnectedfs.read
that worked for serialports on windows. I have a file handle but I get access deniedfs.writeFile
that worked for serialports on all platforms. I haven't yet debugged what's going on but it doesn't work so we implemented something similar.fs.flush
to call tcflush
or PurgeComm
fs.drain
to call tcdrain
or FlushFileBuffers
fs.setBaudRate
Setting baudrates cross platform for custom and preset baud rates. 250k baud is currently not supported in node serialport because it's hard. There are a finite set of tricks for linux, osx and windows to make this work right and serialport hasn't yet figured them all out yet.fs.setFlowControl
/ fs.getFlowControl
to set and get flow control flagsfs.getBreak
/ fs.clearBreak
to set and clear break status.Here are the c functions I use that could have JS equivalents. We could build some of the above with these functions.
ioctl
/ SetCommState
tcsetattr
/ tcgetattr
EscapeCommFunction
/ GetCommModemStatus
flock
@saghul what are your thoughts on the above? Would you have time in the next week to break ground on libuv extras?
what are your thoughts on the above?
Looks good! One comment I have to make is that IMHO nothing serialport related belongs in the fs module. Yes, everything is a file descriptor in Unix, but conceptually a serial port is not a file :-)
Would you have time in the next week to break ground on libuv extras?
I'll try to get the basic building blocks + build system ready.
In case it helps, this can also serve as API inspiration: http://doc.qt.io/qt-5/qserialport.html Alas we can't borrow any code from Qt because it's GPL.
One thing that would be nice to see is a libuv level API proposal. If this is going to "inherit" from uv_stream_t
we might need to make internal adjustments. It's important we catch those as early as possible.
I'll have to study qt serialport. Python's serialport is another good reference, I've used it for ioctl tricks on different platforms more than a few times.
We're not currently using uv_stream_t
directly. We do have a write queue that was implemented early on but I'm hoping to move away from it. For reads uv_stream_t
does select on osx, overlapped reads on windows and .. I'm not sure on linux. For writes I'm less sure what's going on. But it looks like windows leverages iocp (or.. emulates it?) which is a lot more than we do.
I don't understand what a serialport is cross platform to libuv
. On unix it's not a file or a domain socket, but under the hood fs.read
is probably using uv_stream_t
and that works great. On windows is it a named pipe? I know fs.read
doesn't work there.
I imagine a uv_serial_t
would handle the reading and writing to an open serial connection. Would it include opening the file handles and the configuration primitives too?
For reads uv_stream_t does select on osx
Incorrect. That's only the case if the fd doesn't work with kqueue.
I don't understand what a serialport is cross platform to libuv.
I consider it an abstract entity. On Unix it's file descriptor, yeah, but that's it's an implementation detail. AFAIS it behaves like a stream so it should probably be one, and inherit the heavy lifting already inplace.
On unix it's not a file or a domain socket, but under the hood fs.read is probably using uv_stream_t and that works great.
No, it's not. Streams queue writes, while the fs operations run in parallel and use offsets.
I imagine a uv_serial_t would handle the reading and writing to an open serial connection. Would it include opening the file handles and the configuration primitives too?
I'd say yes. The whole idea behind putting this in the libuv layer is that the Node native module would just be a wrapper of the C part, plus handling of data types.
I love it. What should a proposal look like?
Since the plan is to put this in libuv-extras, I'd say something like http://docs.libuv.org/en/v1.x/tty.html would be a good start. That is: public API and datatypes.
The implementation can start as a C file (plus the header) while I figure out the best way to deal with libuv-extras as a companion library depending on libuv.
ping @reconbot you have a chance to look at this yet?
also @saghul can you build more on how serialport is not a file. Are you speaking in comparison to what you use the fs module for or unix files?
What would you define it as?
A device?
I have but it's a lot of work =p
Here's my start https://github.com/reconbot/libuv/blob/uv_serial_t/docs/src/serial.rst we can crib most of the QSerialPort class, but it's got a few legacy things I'll probably drop unless there's a compelling reason. I also need to square terminology with what we currently provide.
There isn't anything possible at this time. We're eventually going to support N-API but will probably always be a binary module.
During the hardware working group meetup at Cascadia we were asked to document ioclt or other calls used on all platforms to make sure we're able to target all the features we need for exiting functionality.