From: Johan S. <jo...@st...> - 2014-06-22 21:10:15
|
Hi, I've previously mentioned my work on LinkUSB performance improvements [1], and my goal to write a libftdi based implementation. The client-timings are generally cut about 2.5 times, depending on operation. A temp sensor is read in ~50ms instead of ~123ms. I now have some code which works fine, I'm running this with my LinkUSB 1.5 on FreeBSD 9.2, performing temperature readings of 24 mixed temperature sensors, and 4 DS2406's. The temperature is read every 30 seconds, and I (try to) scan for alarm ever 0.3 seconds. In other words, pretty heavy load. This has been running for a few days without any problems now. -----(TL;DR below)----- Some background (partly recap from earlier thread, but some new facts, and also repeating here to keep it gathered): This might be seen as "micro-optimization", not really useful if you have a small net with few sensors. However, with a couple of DS2406's wired as inputs, I want as low reaction time as possible. This is quite a big step towards that goal. Other optimizations I'm doing is of course simultaneous conversions and using alarms etc, but that's another story. It all started with the random outages I wrote about in the other thread, in which I got some tips on the LinkUSB's different baudmodes. While looking into this, I also noticed that my DS2480B-based lab net performed much faster than the LinkUSB-based net. After some digging I found a few areas which could be improved. It boils down to mainly two things: * The FTDI FT232R (USB<->RS232) chip which the LinkUSB utilizes, does not perform well with low amounts of data. The 64byte data buffer is by default flushed every 16ms, or when full. Most OWFS operations does not produce those amounts of data, so every transaction was delayed up to 16ms. This has been mitigated by changing the FTDi chip timer to 1ms, and this is also the main reason libftdi is used. (FTDI docs calls this the "latency timer") * The LinkUSB operated at 9600bps by default. Every sent byte on the 1-wire bus is transmitted hex encoded, so 2 bytes is used for every single wire-byte. The DS2480B uses raw bytes, thus the LinkUSB yielded half the speed. This has been mitigated by using 19200bps instead of 9600bps. Higher speed (38400) is not usable, since it overruns the 1-Wire bus unless we take special care of rate-limiting. Could maybe be used to speed up the search functionality.. A third thing I made some experiments on was the fact that OFWS jumps in and out of "byte" mode. However, trying to setting this mode explicitly and going in/out from it only when it was actually required, yielded worse timings in the end (with the above fixes applied).. Most likely since these changes where made in separate writes, taking up all the time which could potentially be gained. This experiment was ditched. I also noticed that there was some issues with using the BREAK condition to reset my device. The manual says a BREAK condition should be able to reset the device. I'm communicating with iButtonLink regarding this, and they are looking in to it, believing I've found a bug. Today I actually noticed that sending a break DOES work, but only when inside "b" mode (sending bytes to the wire). To be strict, the manual actually only talks about break support in the sections regarding the different data modes.. So might actually be working as intended. Anyway, one brute force way of resetting would thus be to send "b", then break, then re-probe at 9600bps.. But I'll wait for further response from their developers before doing anything with this. ----------- The changes adds the following: * A LIBFTDI configure option: if not auto-detected/forced-yes, all ftdi related code is dropped out using similar conditionals as for example the W1 code. * A new device arg: --linkusb=<serial> which tells owfs to use libftdi to find a specific USB device with that serial. * Improved performance, if using the new device arg. Some examples: Reading a DS18S20 temperature (12bit, after simultaneous conversion. 9 byte response): - Old LINK code: 123ms (- Old LINK code with FTDI latency timer externally set to 1ms: 75ms) - New LinkUSB FTDI code: 51ms For the DS18B20 the improvement is actually even better, a separate commit is already merged into master [2], and without that fix the DS18B20 took 250ms. Reading DS18*20 /power data (1 byte response): - Old LINK code: 100ms - New LinkUSB FTDI code: 43ms The code is available in a branch on my fork: https://sourceforge.net/u/stromnet/owfs/ci/ftdi-linkusb/. The changes can roughly be summarized: * A new file ow_ftdi.c has been added, implementing a new com_type ct_ftdi * ow_com* has been altered to support ct_ftdi in addition to ct_serial * ow_link.c is mostly untouched, with exception for the Link detection code which now tries to detect a link device using multiple baud rates. For old link mode, this should not introduce any changes at all, except that it now has a chance to find devices configured for >9600bps. * ow_arg changes to support new arg To check this out locally, use: git clone https://str...@gi.../u/stromnet/owfs owfs-stromnet git checkout ftdi-linkusb Then follow the regular build-from-source commands as indicated in README. Anyhow, I hope someone else finds these improvements interesting, and is willing to spend some time reviewing the changes, and also to do some testing with different OS'es and different Link12/Link45/LinkUSB versions (I only have a LinkUSB v1.5). Ultimately my hope is of course that this makes it into the master branch. I do have one thing on the todo list, and that is auto-detection. Currently you have to explicitly specify a LinkUSB FTDI serial number (Linux: lsusb, FreeBSD: usbconfig). This is not very optimal. However, at least my device uses the standard FTDI Vendor/product ID. This means I cannot distinguish a random FTDI-based RS232-adapter and a LinkUSB, without actually talking to the device. This can of course be done, but I'm not sure it's "acceptable" to start writing to every FTDI adapter found.. How is this solved with other auto-detected devices? Looking forward to any and all feedback! :) Johan [1] https://sourceforge.net/p/owfs/mailman/owfs-developers/thread/53905A08.40906%40stromnet.se/#msg32422357 [2] https://sourceforge.net/p/owfs/code/merge-requests/1/ |