Re: CAN ISO-TP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I used following code:

import isotp
import time
s = isotp.socket()
s._socket.settimeout(2)
s.set_opts(s.flags.WAIT_TX_DONE)
s.bind("can0", isotp.Address(rxid=1, txid=2))

s.send(b"aaaaaaaaa") -> returns immediately with number of bytes
s.send(b"aaaaaaaaa") -> same OS error as above (Error 70)

pt., 7 maj 2021 o 09:59 Patrick Menschel <menschel.p@xxxxxxxxx> napisał(a):
>
> 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
>




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux