LatencyTimer / InBufferSize for OS X, new Info.plist

edited May 2015 in Software
Both Mac and Windows are using the FTDI VCP virtual com port, (usb serial port emulation driver.)  For the related setting on Windows see this post.

FTDI defaults the "Latency Timer" on both Mac and Windows to 16 milliseconds. This causes large pauses to occur in the input stream from the OpenBCI data. The link above shows how to set the timer to 1 ms on Windows via a control panel setting. On Mac there is no equivalent control panel, but there is a file called Info.plist that can be copied into the Mac kernel extension driver folder, that will override the default. It turns out on Mac, setting that value to 1 ms has no effect (default continues). But setting it to 2 ms, does seem to do the override and buffering delays are improved substantially.

You can download the file from here.

If you don't already have the FTDI driver installed, see this post. Many pre-Mavericks Mac came with this preinstalled. If you have Mavericks or Yosemite you need to do some extra steps to disable the Apple driver, outlined in that link.

Make a backup copy of the old Info.plist in the folder below, and copy the new Info.plist over the old one:

/System/Library/Extensions/FTDIUSBSerialDriver.kext/Contents

Easiest thing to do at this point is to just reboot, which will pickup the new driver parameters. Using your Processing GUI, you should now see improved buffering performance. Our entry in the plist file is the one labeled:

"<key>FT X Series</key>"

William
«1

Comments

  • Hi William,

    I have been trying for a while now to get this to work on my Mac and have had little luck. The main problem for me seems to be that changing the Info.plist file changes the signature (like a checksum I'm assuming?) on the FTDI driver so that when I try to run:

    s
    udo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext/

    I get the error:

    /System/Library/Extensions/FTDIUSBSerialDriver.kext failed to load - (libkern/kext) not loadable (reason unspecified); check the system/kernel logs for errors or try kextutil(8).

    I have tried setting a dev flag as suggested here (http://www.mommosoft.com/blog/2014/10/24/ftdi-chip-and-os-x-10-10/) by saying:

    sudo nvram boot-args=”kext-dev-mode=1″

    But before and after rebooting I get the exact same error and my terminal will fail to recognize the board. To get it to recognize it again I have to reinstall the FTDI drivers completely which, of course, doesn't solve the latency issue. 

    Any idea what else I can try? What other authentication methods could I use so that the loading will work? 
    Thanks,
    Rodrigo

    NOTE:
    I'm replacing the Info file like this:
    cp ~/Downloads/Info_k.plist /System/Library/Extensions/FTDIUSBSerialDriver.kext/Contents/Info.plist
    Where Info_k.plist is the file I downloaded from your post. (Which looks fine on Xcode and has the latency config set to 2.





  • Rodrigo, hi.

    The link below shows that folks had varying experience with the nvram command working, depending on whether or not quotes were used. Try issuing the command without quotes. You can also say "nvram -p" to print current settings -- to see if it is remembering your setting.

    http://dpsinsider.com/forums/topic/yosemite-dp4-breaks-dps/

    I only have Mavericks here myself, this new restriction on signing kexts went into effect on Yosemite.


  • Thank for the link!
    I got the driver to load, but now even worse, the latency is still there!!
    The Info file has the changed config to 2 ms and the driver recognizes my device, connects and streams, but still the exact same latency. 
    I really don't understand...

    I'm guessing it's a Yosemite issue? But how, it loads! How can it load but then ignore the changes in the Info file?!
  • PS:
    I tried every variation discussed in the forum, re-typing with quotes, without quotes, copy-pasting, everything. The copy-paste renders it unloadable and nvram -p lists the dev-mode as an "UNPRINTABLE STRING". Re-typing the command with or without quotes makes it:
    kext-dev-mode=1.
    The forum weirdly before it is set this way the variable is not printed at all, whereas the forum says it should be =0.

  • Well, that is good news about the driver loading. Odd how the cut/paste wrecks the nvram command. You're certain that the Apple driver is disabled as per the mommosoft instructions? You can list what kexts are loaded with: kextstat

    It's possible Yosemite is somehow throttling the driver. Can you edit the plist and try say 3ms, etc.? I sure as heck wish FTDI was more involved with this whole thing. How they could be distributing a driver written in 2012, it just makes no sense.
  • Just on a lark, I was searching for open source vcp drivers for Mac and found this:

    http://sourceforge.net/projects/osx-pl2303/
    https://www.mac-usb-serial.com/

    This is NOT for the FTDI usb chip, however, perhaps it would be possible to morph it into FTDI compatible. Without sweating bricks.  :-)  I don't know if FTDI provides enough low level info in their docs to accomplish this.

    Between Apple's secrecy (with their own driver and Yosemite misfeatures) and FTDI's tardy updates -- some kind of open source solution may be the only way out of the cage...


  • biomurphbiomurph Brooklyn, NY
    another option is to move to a different FTDI IC for future manufacturing that doesn't have this problem.

    it never ends...
  • edited March 2015
    Just sent an email (cc-ing you guys) to FTDI, pleading on my hands and knees for an update that understands Yosemite. Cross your fingers...

    By the way Joel, I think the issue is with the VCP driver itself, not the hardware. So other FTDI chips may behave the same on Yosemite. Now, that open source VCP driver (mentioned above) does support a range of usb serial chips, just not the FTDI.
  • I just checked and my CH340 and PL-2303 devices don't seem to have this problem.
    It will probably be easier to switch to better components than trying to hack the driver.  IME settings like this are often there as hacks to cover up defects in the hardware.
  • Nice to hear that the PL-2303 has some automated approach to avoid manual Latency Timer settings. However, we have hundreds of dongles in the field, so FTDI should be able to help us out. It worked fine on Mavericks and previous. So in large part, this is an Apple goof.

    How did you verify that PL-2303 works in this mode? Did you test with 32 byte packets sent at 4 ms intervals?

  • I actually just plugged them both in and verified that there's no latency setting.  16ms would be a huge gap in the data stream at higher data rates, and I've never seen that before with them.

    I can probably do some more testing if needed.  I'm just still kinda confused why there would be this latency problem.
  • The Latency Timer setting only applies to tiny packets like our 32 byte EEG samples, sent at 4 ms intervals. USB serial devices receiving a continuous stream of bytes have no latency issues, because once the receive buffer fills up, it is forwarded to the host OS.  FTDI (in their wanting to avoid excessive OS overhead) has this Latency Timer option for flushing tiny receive packets into the OS. It defaults to 16ms, and that works fine for most applications, but not ours.

    FTDI just returned my email and provided an attached, updated Mavericks / Yosemite driver. It's not posted on their site yet. Rodrigo I'm sure will test with it as soon as possible. And let us know if it improves his situation.

    At least FTDI is "on the case" and can make adjustments if we find further tweeks needed.

  • This is a copy of an email I sent FTDI support regarding my driver testing. Posting it for future reference:

    I have been testing out the new driver and still no luck with the latency. 
    Installation and set up goes fine using the instructions provided. 
    The new driver does not have a specified LatencyTimer configuration for the FT X Series and so, as expected, out of the box the latency persists. 
    I then modifying the Info.plist file from the new driver (copy attached) and replaced it.
    Weirdly, the driver actually loads (sudo kextload /Library/Extensions/FTDIUSBSerialDriver.kext/) or at least doesn't complain WITHOUT signing OR setting to dev-mode=1. This is pretty strange, perhaps because the driver is in a different location now? (Installation puts the driver in /Library/Extensions).

    Finally running kextstat shows this driver below is loaded and shows no other FTDI named drivers.
    110    0 0xffffff7f80c98000 0x7000     0x7000     com.FTDI.driver.FTDIUSBSerialDriver (2.3) <79 38 5 4 3 1>
    I'm assuming this is the driver we want.

    This all looks great, except the latency is still there. 

    I have changed the LatencyTimer to 1, 2 and 3 ms and still the same latency.

    I am testing latency by printing incoming packets using the print plugin of user.py (https://github.com/OpenBCI/OpenBCI_Python
    ). On linux and windows (with Timer fix) the exact same python script runs smoothly and isn't laggy. On windows I can basically control the lag of the printing by playing with the TimerLetancy value. 

    Oh and I've also rebooted constantly throughout these trials. 
  • Hey guys! I just signed up to let you know that I've edited the Info.plist file and managed to solve the latency issues on Mac (Yosemite). I have detailed the steps here: http://ebrain.io/openbci-ftdi-driver/

    It tuns out that setting the LatencyTimer option does not change anything, but changing the buffer read size does.

    Hope it helps!
  • edited May 2015
    @marion , hey brilliant. I see that FTDI has a new driver posted from April on their page,


    For Mavericks and Yosemite. We tested an early version of that in March. The Latency Timer setting did used to work for early Mavericks. But I think stopped working for later Mavericks and Yosemite. We were emailing with FTDI asking them to fix this. I guess they never did. Your workaround with the InBufferSize=64 looks like it will do the trick. As long as you are not seeing any overrun or lost data issues with that small a buffer. The OpenBCI packets are 33 bytes (31 bytes over the air, then dongle adds header & footer bytes). So I guess the buffer is flushed as soon as it reaches 64, then into the app.

    I'm guessing @Rceballos98 and @biomurph will confirm with their Macs. I'll give it a try as well on my Mavericks here.

    Thanks again,

    William
  • Awesome!
    I remember trying to change the buffer size, but I never got it that low I guess!

    I will try it right now,
    Thanks @marion
  • Hi @marion,

    So when you changed the info.plist using vim, did you just :wq to exit? One of the problems with changing the info.plist is that the signage (something like checksum I think) that apple requires on drivers, recognizes I have modified the file and then will not allow me to reload it.

    This is the error:
    rodrigo$ sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext
    /System/Library/Extensions/FTDIUSBSerialDriver.kext failed to load - (libkern/kext) not loadable (reason unspecified); check the system/kernel logs for errors or try kextutil(8).

    What OS version do you have? Is your system set on dev-mode?
  • Rodrigo and Marion, thanks for checking this out.

    On further consideration, I'm thinking that (as long as there is no packet loss), that we may be better off setting the InBufferSize to say 30 or 32. That way we will get a new packet through 250 times/sec (every 4 ms.) Even though there is a one packet lag.

    With the size set at 64 the timing is going to be more variable, with sometimes 8 or 12 ms between packets. Does that sound right? The technical term for this is packet jitter, and the ideal is for that to be as low as possible. The Latency Timer feature on Windows does this just fine (when set to 1 ms). With this feature missing on Mac, the InBufferSize sounds like it may be a good workaround, providing FTDI actually does MORE buffering internally before the packets are passed onto the user app. So that regardless of how small the app transfer buffer, packets are not lost. And our 33 byte packets every 4 ms are certainly a low data rate to begin with.

    Joel @biomurph , I'd like to hear your thoughts as well.

    It's remotely possible that FTDI could eventually fix the LatencyTimer bug under Yosemite / Mavericks, if we keep bugging them. The early release we got in March apparently missed their development window because it was too close to the April release data.

    William

  • edited May 2015
    Hi all,

    I just tried @marion's approach but ran into the same issue as @Rceballos98:

    Upon: 
    conor$ sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext/

    I get the following error:
    /System/Library/Extensions/FTDIUSBSerialDriver.kext failed to load - (libkern/kext) not loadable (reason unspecified); check the system/kernel logs for errors or try kextutil(8).

    Despite getting this error, however:

    conor$ kextstat | grep FTDI

    Yields the following printout:

    145    0 0xffffff7f82a07000 0x7000     0x7000     com.apple.driver.AppleUSBFTDI (1.0.1b16) <84 41 5 4 3>

    It seems Rodrigo and I are in the same place. 

    Now when I try to connect to my device through the Processing GUI, I am able to connect to the device (and see the software/hardware hand-shaking & initial registers of the ADS printing to the console). But when I hit start streaming, nothing comes through. Thoughts?

    I'm going to keep digging.

    Conor



  • marionmarion SF
    edited May 2015

    Did you guys try to remove the driver?

    sudo rm -rf /System/Library/Extensions/FTDIUSBSerialDriver.kext

    Then reboot the computer and follow the steps in my post? I just did that again and that worked. Let me know.

    My OS: Yosemite 10.10.2



  • Here's FTDI's latest app note from April,

    http://www.ftdichip.com/Support/Documents/AppNotes/AN_134_FTDI_Drivers_Installation_Guide_for_MAC_OSX.pdf

    Where they state,

    Please note that editing the kext to add a VID/PID, or alias a baud rate now requires re-signing with a
    kext-signing certificate.


    But of course we know this already. The March 23 post by Rodrigo mentions the kext-dev-mode nvram boot setting. But it's possible this has been tightened up even further in the latest Yosemite releases. Wondering if everyone could share their exact 10.10.x versions with us.

    Have not looked though these search results yet, could be some hints here,

    https://www.google.com/search?q=yosemite+kext-dev-mode


  • @wjcroft setting the buffer size to 32 does not work for me. The board can connect, but the data packets seem to not be coming though (I had the red light flashing fast but could not see data in the Processing GUI). 64 is the smallest buffer size I can set. Compared to the initial default value of 4096 bytes, that's not bad. Even though I agree with you, that's not ideal.

    Here are the results of my different trials:
    - InBufferSize = 16 // The board can't connect. No data. OBCI red light wasn't on.
    - InBufferSize = 32 // The board can connect. No data. OBCI red light was on but blinking fast.
    - InBufferSize = 64 // The board can connect. The data is there :-) OBCI red light is on and steady.

    Hope that helps a little.
  • Some of the guys doing the kext-dev-mode change are also "touch"ing some of the Extensions folders. It could be there is some date checking also going on. Such that the enclosing folder must have later date than the plist.

    http://visionstudios.ca/blog/ssd-trim-enabler-os-x-yosemite


  • "So when you changed the info.plist using vim, did you just :wq to exit? "

    Yes. Exit and save with :wq

  • Marion, are you using the kext-dev-mode patch? That is what is hanging up Conor and Rodrigo. Not sure if they turned that on. This should show up if you hold down Command-V at boot time so you see all the boot startup text.

  • OK, Marion, just saw your Yosemite version 10.10.2, according to this list, that could correspond to a whole range of builds,

    http://en.wikipedia.org/wiki/OS_X_Yosemite

    I don't see how you could be running the altered signature driver without the kext-dev-mode change. Unless you have an early build that is not checking this.

  • marionmarion SF
    edited May 2015
    @wjcroft Sorry, I totally forgot to mention that I am indeed using the kext-dev-mode patch. Nice catch!

    To enable it: sudo nvram boot-args="kext-dev-mode=1"


  • marionmarion SF
    edited May 2015
    @conor_obci @Rceballo98

    Let me know if the following command solves your issue:
    sudo nvram boot-args="kext-dev-mode=1"
  • @wjcroft, I'm Yosemite 10.10.3

    Now trying Marion's latest suggestions. Will keep you posted.
  • Does it matter when we enable the kext-dev-mode patch? 

    Also, just for clarification, can someone explain the difference between:

    sudo rm -rf /System/Library/Extensions/FTDIUSBSerialDriver.kext

    AND

    sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext




Leave a Comment