-
Notifications
You must be signed in to change notification settings - Fork 30
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
Backend API and iCE40-usbtrace support #193
Conversation
Some structs that are used in ui need to be accessible from other backends as well. Speed, InterfaceSelection, (Cynthion/Device)Usability Move/rename CynthionStop -> BackendStop
ice40usbtrace has its own header structure so we need to regenerate the original USB packet including checksum.
This simply switches out the Cynthion for the Ice40usbtrace
Co-authored-by: Martin Ling <[email protected]>
Use iCE40-usbtrace for human-facing text and Ice40Usbtrace for types, as per upstream repo and Rust conventions.
The error is still just printed out, for now.
This was just adding some extra indirection around parse_packet.
Worked fine for me 👍 |
BTW as a side note there is a couple of improvements that could be made to the ice40usb trace support. It has an interrupt end point that ideally should be monitored that reports :
|
One thing that might be fixing here though is that in case of overflow, the usb stream end. You get a popup :
But then any attempt to click the "start capture" button again just ends with :
|
That's good to know, and indeed may have some impact on the API surface. I had guessed that there were features like this from the commented entries in The buffer fill status is something I've been planning to add to Cynthion as well, along with a level indicator in the UI, so that's definitely something that's in scope. I think a good way to do that would be for the backend to be given an additional The state information is a bit different because we'll need to stop the capture when it hits the overflow state. I think perhaps the solution there is that we clone the The difference between Cynthion and iCE40-usbtrace here is that on Cynthion, we plan to keep all data flow happening on a single bulk endpoint, with multiplexing of different data types done in-band within the stream format. The reason for that approach is that it maximises the achievable throughput on the bus, as the host only has to poll one endpoint. So on Cynthion we'd give that copy of The iCE40-usbtrace backend would instead need to be making interrupt transfers on a second endpoint. I think the API already allows for that though. One way to do it would be to just spawn a separate worker thread for the interrupt transfers in That would leave us running three threads for one relatively simple USB device, but the extra thread doesn't really cost us anything, and Rust makes the concurrency easy to get right. And it keeps the rest of the code common to both backends. |
We definitely need to fix that before this can be merged. I'm not sure I understand exactly how this happens yet though. The message comes from Presumably that is happening when the decoder thread spawned from Which in turn implies that the But nothing should have shut down the transfer queue at this point, so the best explanation I see for that iteration ending is that Is there some unusual header that's sent on the bulk endpoint in the event of an overflow? It might be useful to try ignoring that error, by replacing this line in block_on(stop_rx)
.context("Sender was dropped")?; with let _ = block_on(stop_rx); That may allow things to progress to the point where some other error is reported. |
As well as simplifying the code, this ensures that a BackendStop is not dropped in the case where the PacketIterator ended early with an error.
There's little point in raising an error in these cases. Whatever has happened, the best we can do is to proceed with the rest of shutdown.
@smunaut I've pushed a couple of further commits, which should avoid the Could you try the overflow case again and let me know what happens now? |
@martinling Sorry it took me a while to test. I think there is a bug in the firmware so I wouldn't worry about the handling of the overflow case ATM ... |
Ok, I ended up fixing the firmware (for the most part ...). So what happens now in case of overflow is you'll get either a short packet ( < 64 bytes ) or a ZLP if it ends up shutting down on a packet boundary. ( During normal operation you'll always get full packets only ). Now, packetry doesn't notice this (which is fine) and so it just thinks it's still capturing. Pressing stop result in a message about write error / STALL (because the stop request will fail given hw is already stopped ). |
OK. I suppose what we could do there would be to detect the short packet in However, in the current architecture we can't do a lot once we've detected that, because the So the API is missing a way for the queue worker thread to signal that the device has stopped of its own accord. I'd anticipated that happening from the decoder thread rather than the queue worker thread, but I guess we need a way to signal it from either of them, since there's also the case where a bulk transfer error happens (e.g. device disconnected).
I think we'll have to just catch that STALL case and ignore it. Even in the case where the UI has initiated the shutdown, there's still the possibility that the device overruns before the host gets around to sending the stop command.
I believe this is because the worker thread running So the queue worker thread is left running, and it still has the Seems like the next step is to just ignore the STALL and that should avoid this. |
@smunaut can you test again please? I've pushed a change which always ignores a STALL response for the This should fix the error on shutdown after the device has stopped of its own accord due to an overflow, and hopefully should mean you're able to restart capture again afterwards. If not, let me know what still goes wrong. Note that it's also no longer ignoring errors other than I don't think that should break anything, as I'm assuming that ignoring errors there was due to a |
@martinling Just tried, works fine. After an overflow you can slop and re-start with no issues. |
Great! In that case, I think this is ready for final review and merge. |
This PR defines a common backend API for USB capture devices, and adds support for the iCE40-usbtrace device.
The changes are made on top of a rebased version of #190. Tested with Cynthion only at this stage; @asdfuser and @smunaut, please test this with iCE40-usbtrace!
I have broken the changes to the
ice40usbtrace
backend down into as many commits as possible, so if I've broken anything hopefully it's easy to bisect. However, the final commit that ports everything to the new API is still a fairly big change.The backend API is not very generic; it assumes that capture devices will work quite similarly to the two examples we currently have. That allows for sharing a lot of code, but means we might have to revisit the design in future if we need to support devices that work substantially differently. I expect it will suffice for OpenViszla, though.