Bug inside DeviceFS possible
Pages: 1 2
Dave Higton (1515) 3526 posts |
My thanks to you again, Thomas. Your method to read the blocking status IOCTL definitely fills in word 1 of the IOCTL block, and seems to return what has last been set via the IOCTL: either &00000001 or &00000000. It seems to work identically on the Iyonix (USBDriver 0.55 of 2011-12-10) the BeagleBoard and the Raspberry Pi (both USBDriver 0.63 of 2012-12-04). Reading it before setting the noblock bit returns &00000000 as expected. USBDriver has all the keywords for the options that can be used as arguments when opening a stream, e.g. “nopad” (and “nopad” works), but the word “block” is not there. Using “noblock” when opening the stream appears to have no effect – it doesn’t set the IOCTL bit, but it doesn’t error out either. |
Dave Higton (1515) 3526 posts |
So it’s an interesting state of affairs. I can set a bulk IN stream not to pad, but if I set it not to pad but don’t set it not to block, and call OS_GBPB 4 requesting 2 bytes, the call never returns, no matter how many 2-byte packets are sent over the USB. The maxpacket size for the endpoint is 64. 32 2-byte packets don’t satisfy it. I haven’t tried it, but I wonder of it still requires to see a 64 byte transfer before it returns? Anyway, setting it not to pad and not to block allows it to return for each packet transferred over the USB. It still waits for each packet, so my next experiments will be on timeouts. |
Dave Higton (1515) 3526 posts |
Wow. Setting usbtimeout 5 causes it to go mad on the Iyonix, usually claiming that it has returned 64 bytes when it plainly has done no such thing. |
Dave Higton (1515) 3526 posts |
Once a stream has timed out, does this “timed out” status stick? It looks like it does. Further, it looks like no further transfers are attempted from that endpoint. OS_GBPB 4 always returns from that point onwards with V set and an error block saying “USB transfer failed: Timeout”. Is there a way of resetting the timeout error state? |
Thomas Milius (1471) 64 posts |
I would request always 64 Bytes. AFAIR you will get 2 Bytes if available then and not 4 Bytes (2 + 2 Bytes in case that 2 empty transfers has been setup) but I may be wrong. Pipebuffer size should be 65 (one larger as the maximum USB block size). FTDI devices are really a problem. Their Bulk transmission is more an interupt transmission. SO they are difficulty to handle. May be you can reset the timeout error state by performing a clear stall on the pipe: /* Clear stall at host side / |
Thomas Milius (1471) 64 posts |
I have no experience with timeout. AFAIR I did some small tries long time ago but never had a usage for it. |
Dave Higton (1515) 3526 posts |
Thanks for the info about clearing a stall, Thomas. I’ll try that tonight. Although I don’t recall seeing the USB analyser say that the bus was stalled. That’s something else for me to look carefully at tonight. Perhaps my expectation of what should happen with regard to blocking is wrong. What I want to achieve is to constantly poll the FTDI device, but without spinlocking the computer so that hardly anything else can run. Just to put some numbers on it: the FTDI device, by default, will transfer in either when it has 64 bytes available, or when 16 ms have elapsed since the last input transfer, whichever is sooner. It’s tempting to do a transfer, then not request another for 16 ms, so as not to waste the time. But, if input is coming in at 115200 baud, that’s a lot more than 64 bytes in 16 ms. I don’t know how many bytes it can buffer before overflowing and losing data – although it seems to have autonomous handshaking after all, so it may not be too bad. When I set a stream to non-blocking, I had expected that it would return 0 bytes if none were available. It turns out that non-blocking still makes it block until a transfer takes place, as far as I can see. Which makes “non-blocking” a bit of a misnomer. |
Thomas Milius (1471) 64 posts |
What I am not understanding why you are trying to write a driver for FTDI as I already wrote one. As you can see in my code it is not really fun due to the special FTDI behaviour. I am looking whether a transfer is already running and lots of things more. To avoid problems you need to ensure that exactly one input request is pending every time. If buffer becomes filled put it elsewhere and restart the next input transfer immediately afterwards. In my opinion this is this only thing you can do to ensure a correct transfer. AFAIR the USB stack does the task of restart for you under certain circumstances. If you are obtaining exactly 64 Bytes I think it will do so. Else you will need to do so explicitely. So you can detect short packages and draw your conclusions on it inside your program. Especally for the FTDI this behaviour is exactly what you don’t want to see because of the preriodic aspect and the stream character of the FTDI but it is fine eg. for mass storages. To be fair there are a lot more devices behaving like mass storage than FTDI based ones. |
Pages: 1 2