Closed wiboticalex closed 2 years ago
As I understand it, the two solutions are both technically valid: either reduce the SO_SNDBUF size such that it is no greater than twice the size of the TX queue (multiplied by the CAN frame control structure size) or increase the TX queue size to the same effect. I normally use the latter:
https://gist.github.com/pavel-kirienko/32e395683e8b7f49e71413aebf5e1a89#file-setup_slcan-L101
But we can easily modify PyCyphal to set SO_SNDBUF
to some small value to make the default-size txqueuelen block correctly as well. What you suggested is correct, except that setting the SNDBUF to 1 byte seems arbitrary -- the kernel will override that setting to some minimum anyway, so you could just as well use zero.
Would you send a pull request?
Occasionally during a firmware update Yakut will crash and the socket that pycyphal has created will claim that there is "No buffer space available" aka ENOBUFS.
Traceback:
I have found that patching pycyphal's
transport/can/media/socketcan/_socketcan.py
in_make_socket
withallows updates (and I assume other large data transfers) to occur with no issues from my testing. I assume a proper fix using this method would probably set SNDBUF to something greater than 1 though.
There is some discussion of this issue in section 3.4 of http://rtime.felk.cvut.cz/can/socketcan-qdisc-final.pdf, although I found that I did not have to adjust the default queue length of 10 in my case even with using the minimum SNDBUF.
A couple other ways that this could be worked around that I found are increasing the default queue length (although is just hiding the issue?) or adding some retry logic to the
send
function when OSError's errno == errno.ENOBUFS.Any thoughts?