First I just opened and closed the port. I see this on the serial console:
Rx setup (8) 2122030000000000 Setup interface request -- testing -- 364 -- testing -- 365 Rx setup (8) 2122000000000000 Setup interface requestI did an open, a 2 second delay, then a close. I was surprised and interested to see that making a connection (using open()) and ending a connection (via close()) both inform our USB device about what has happened using setup packets on endpoint 0. This suggests that it should be possible to find out just what these do and for software on the F411 to know when there actually is a connection.
Note that I continually print the "testing" messages every second.
Next I do a 50 byte write and see:
Rx setup (8) 2122030000000000 VCP_DataRx 20000F40 50 Rx setup (8) 2122000000000000No surprises in that, so let's try a 200 byte write:
VCP_DataRx 20000F40 64 VCP_DataRx 20000F40 64 VCP_DataRx 20000F40 64 VCP_DataRx 20000F40 8No surprises there either. The data arrives in 64 byte "chunks" as determined by how much data can get moved in a single USB transaction.
Note: it is not a bug or a problem -- set below.
Going beyond this, I see buggy behavior. Sending 2000 bytes sends part of the data, then everything "locks up". Sending 1000 bytes works sometimes, but eventually it also locks up when I repeat the test over and over. It always fails when I send the data immediately after the open.
I never see a problem when I do a single write and limit the size of my writes to 50 bytes (less than the 64 byte size of a USB transaction.
However, when I attempt to do 10 writes back to back with 50 bytes each, it works the first two times, then on the third group of 10, it locks up after four 50 byte packets.
So, it doesn't look like serial timing interference. I do not get actual write errors on the linux side, but the close hangs for some reason.
I'll also note that once a hang happens, the F411 is permanently hung. Even though the unix side times out and allows close to finish, the situation in the F411 is "stuck" and all efforts to write data now fail.
I test using 50 byte packets with 0.1 second delays between them and after 56 packets, get a hang. I change the delay to 0.2 second and I still get a hang after 56 packets!
As a last test, I changed the delay to 1 second and reactivated the print for VCP_DataRx. After 40 packets of 50 bytes, the VCP_DataRx messages stopped and 16 packets later, the linux side writes hung. So 56 again.
200 writes of 50 bytes (10000 total) with 1 millisecond delays. 200 writes of 50 bytes (10000 total) with no delays. 200 writes of 100 bytes (10000 total) with no delays.The last go across as:
VCP_DataRx 20000F44 64 VCP_DataRx 20000F44 36Finally I send 500 writes of 200 bytes and it works fine -- and is very fast.
Note that FS usb is 12 Mbit/second. However, we know that we have 1000 transactions with 64 bytes moved per second. That is 64K bytes/second (call a byte 10 bits and that is 640K bits per second). Well, maybe the overhead with USB really is that high. Or there are things I don't understand yet.
I'm actually reading that FS usb can send 64 bytes every 512 us, which would be close to double my rate, thus 128K bytes/second. I see that bulk endpoints can have 1024 byte payloads which would certainly change things.
Not only that, but there can be up to 19 bulk transactions of 64 bytes in a frame. Frames do come at 1000 Hz. With 1000 * 19 * 64 bytes per second, we get 1.2 Mbytes/second. This does seem to be the maximum theoretical transfer speed for FS.
Note also that in library/usbd_cdc_core.c our endpoints get announced during enumeration as "Bulk".On my list of things to do is to write code on the linux side to use "usblib" or whatever it is currently called. I expect this to be educational and hope that it will allow better monitoring of what is going on with the USB connection.
Tom's Computer Info / tom@mmto.org