Am 07.05.21 um 09:24 schrieb Bartosz Zdanowicz: > pt., 7 maj 2021 o 09:02 Patrick Menschel <menschel.p@xxxxxxxxx> napisał(a): >> >> Am 06.05.21 um 23:28 schrieb Bartosz Zdanowicz: >>>> Can you create a candump log from vcan0 to see, what's going on the bus? >>>> >>> On RPI after first send I got >>> pi@raspberrypi:~ $ candump can0 >>> can0 002 [8] 10 09 41 41 41 41 41 41 >>> >>> After the second message I got mentioned OSError and there is no data >>> on candump. Sending again I received next frame: >>> pi@raspberrypi:~ $ candump can0 >>> can0 002 [8] 10 09 41 41 41 41 41 41 >>> can0 002 [8] 10 09 41 41 41 41 41 41 >>> >>> On my local PC where I get no system Error I got one frame per every send: >>> bartosz ~/Work/DeltaThermal/can-isotp master candump vcan0 >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 >>>> >>>> ... >>>> So how is Python getting this information? >>>> >>> In general, that's the biggest issue for me. Because in my real >>> application I'm using python select() and recv() on that socket. When >>> this error is raised, my select() on socket deduce something is >>> received and recv() function also throws an error. I just tried to get >>> a minimal example that reproduces the issue which is above. In those >>> cases I would expect timeout, not OSError. >> >> >> As expected, timeout error on missing flow control. Since it's tx side >> it just tells -ECOMM instead of -ETIMEDOUT . >> >> https://github.com/raspberrypi/linux/blob/rpi-5.10.y/net/can/isotp.c#L10 >> https://github.com/raspberrypi/linux/blob/rpi-5.10.y/net/can/isotp.c#L755 >> >> Is there a specific reason why you use select.select() instead of >> Socket.recv(timeout) / Socket.send() ? >> >> Best Regards, >> Patrick > > I have a seperate thread that waits and process data, since I have > multiple sockets opened I want to wait for any of them: > > while True: > ready_sockets = select.select(self.sockets, [], [], self.timeout)[0] > if not ready_sockets: > logging.info("No data received") > continue > for socket in ready_sockets: > self.process_data(socket=socket) > > In process_data I call: > > received = socket.recv() > if received: > #process data > > My main thread is sending data on those sockets: > schedule.every(X).seconds.do(request_that_sends_using_socket.send(), > socket=socket) > > So the flow is that my thread sends data to another device, and the > processing thread is waiting for data. When I don't send any data I > get only prints "No data received" which is expected cause no device > is responding (no device is running). When I send data (no other > device is running) I get an error on send AND my select() is finished > with an error socket inserted to ready_sockets. That means I enter > self.process_data() function with socket and also recv() fails. So it > seems it's not only that OSError is raised but also that socket is > somehow "invalid" because it triggers select() which should not be > triggered (no data was received). Ok, try to enable CAN_ISOTP_WAIT_TX_DONE via socket.setsockopt() . https://github.com/raspberrypi/linux/blob/rpi-5.10.y/net/can/isotp.c#L14 https://gitlab.com/Menschel/socketcan/-/blob/master/socketcan/socketcan.py#L583 and wrap tx into a try-except block. try: self.process_data(socket=socket) except OSError as e: print(e) With this you actually have a chance to do error handling on tx path instead of hitting an already present error of the previous op. Regards, Patrick