-
Notifications
You must be signed in to change notification settings - Fork 127
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
Last port.write does not send all bytes on FTDI dongle #117
Comments
Thank you very much for your awesome and comprehensive example! I finally can confirm seeing truncated data on the wire when using FTDI FT232R based cable (TTL-232R-RPI). And as you already reported, just adding a The writes in the example theorectically might get truncated and I've created brainstorm/serialport-rs-reproducer#1 for addressing this and adding a simple CLI for experimenting. Playing around a little bit gives me the following impression:
Do we have an issue with flushing in general on macOS? |
A Python variant of this test ( |
Hi @sirhcel, @brainstorm told me about this issue and I got nerd-sniped into having a look. 😆 I'm 99% sure this is either a MacOS FTDI VCP driver bug, or a silicon bug! It only seems to appear on macOS, as only the macOS driver seems to send a "Reset" command to the FTDI chip when it closes the port (as per screenshot on the repro repo). Here's Linux (using in-kernel driver): (In fact, the Linux ftdi_sio.c driver doesn't have a custom Here's Windows (using whatever default drivers Windows installs): I also randomly bumped into a stackoverflow issue reporting the same behaviour on macOS, from 2014! I don't think there's anything that a userspace library can do about this. :|. If it's no longer a serialport-rs issue, I'd suggest the question becomes: should the FTDI "Reset" command clear the chip's TX FIFO? If yes, this is a bug in the macOS FTDI VCP driver and should be fixed by FTDI so it doesn't send this command when you close the serial device. If no, this is a bug in the FTDI clone chips and I suspect FTDI will not want to change the driver to accommodate. 😆 . FTDI don't document their USB protocol, so I guess the challenge is to reproduce on a known genuine FTDI chip. I'm not sure I have a 100% definitely genuine FT232 family chip at hand, but maybe someone does... |
After further looking into it and preparing the example
And with the FTDI FT232R dongle, the output data is garbled and looks like written data did not got appended to the transmit buffer but somewhat overwrote existing data:
To me this looks now like we are facing an issue with Apple's termios implementation or serial driver framework. Cross checking with
Resetting the port or IC might still be fine in case that flushing/draining the data beforehand works.
Such reports lower my expectation that Apple is keen on diagnosing and fixing such issues. :-|
I bought the serial hardware I'm using for these tests from DigiKey so I'm assuming that I'm testing on genuine hardware from these vendors.
It looks to me that we already left the scope of serialport-rs and the issues lies deeper down in the plumbing. On top of that it looks to me like neither FTDI nor SiLabs are providing drivers for Apple silicon as of now and the drivers shipped by Apple are the only ones available on this hardware so far. Let's see if there will be a timely response from Apple regarding the "feedback" ... |
That's extremely interesting, @sirhcel!
😮
It's a slightly moot point now, but I looked into this a little more. In the Linux driver there are some USB protocol details that credit FTDI for help with the protocol so they're probably correct. If I read the capture from @brainstorm's repo correctly then the host is sending individual Reset commands for "purge RX buffer", "purge TX buffer", and then "purge RX buffer" again! It seems from the description that the intent for these commands is to drop bytes in the buffers, not wait for them to be sent. I don't see any FTDI commands for managing the TX buffer otherwise (waiting for it to be empty, or checking if it's empty). So once the data goes to the chip the only options might be to wait for the bytes to be sent on the wire, or reset the TX buffer. Of course, maybe there are some commands in the protocol not included in Linux.
That is very interesting! I'm also curious what you hear back. |
This might be an effect from resetting the chip. But as we are talking about the land behind
Isn't this meant for
Aren't we just interested in getting the data on the wire? So waiting for the data to be sent is enough in our case. And this apparently works well on Linux. I had a dive through Linux serial driver stack today and found
I finally got feedback from Apple. The engineer stated that once the data gets passed from the serial framework to the USB serial driver, its job is done. I'm reading this as that there are no means for checking whether all data has been written out or enforcing this. I have no experience with writing device drivers for macOS so far. But in case I've got the recommendation that an application could wait before closing. But from a library perspective there would be a lot of fairy dust required to get an estimation for this time right ... |
Thanks for sharing your experience asking Apple about this.
Totally agree this seems to be the purpose of these. I also agree that this isn't what serialport-rs is asking for anywhere, but it seems to be happening anyway.
Oh, nice! This is exactly what I was looking for (and didn't find) when I last posted.
I guess this comes down to the OS vendor's interpretation of where "the terminal" sits in this pipeline, so there's some wiggle room! It doesn't seem unreasonable for them to say this, though. Although it does seem inconsistent with this philosophy if the driver later explicitly asks the USB device to discard some of that data from its FIFOs. There are also maybe fiddly implications for functions like
I have absolutely no knowledge of macOS drivers either, but agree based on a quick look. I did wonder where other control requests (baud rate, etc.) are sent, this looks like IOUserSerial. I suppose throwing I did note a way to reset the FIFOs (HWResetFifo). This seems like it maps to that I also wondered if there's was any non-BSD userland serial API that might change that default behaviour, but the Apple IOKit docs literally say to use the BSD APIs so I guess not.
I'm mostly a bystander here, but FWIW I agree. It's fiddly at best, and impossible if hardware flow control is enabled. EDIT: Added one more reply at the top. |
Seems to be a bug on MacOS where data is truncated so an arbitrary delay is used serialport/serialport-rs#117
As discussed on matrix.org and documented here: https://github.com/brainstorm/serialport-rs-reproducer, thanks
jr_fn
and @sirhcel for following up with me over the channel.The text was updated successfully, but these errors were encountered: