pylessard / python-udsoncan

Python implementation of UDS (ISO-14229) standard.
MIT License
586 stars 201 forks source link

Transport layer frame capture problem #242

Closed ichbinbork closed 3 months ago

ichbinbork commented 3 months ago

Hey,

I'm using your lib in my desktop application and in the desktop application there is a field for flashing ECU. The flash process runs on a QThread and works fine when there is no frame in the bus. When I connect bus that contains more than one ECU, the CAN-TP layer miss messages. I can understand it from this message

 Did not receive IsoTP frame from the Transport layer in time (timeout=12 sec) 
2024-07-09 16:55:21 [ERROR] UdsClient: [TimeoutException] : Did not receive response in time. P2 timeout time has expired (timeout=12.000 sec)

Initially, I started to suspect the thread that was used for the flash update process. Then I created a simple script that sends single ECU Reset request within %80 bus load(250kbps). After that I realized that the response to this request was not captured by the isotp layer again. So I don't think that the cause of the problem is thread. I think there is a problem in the listener under high bus load.

I'm using these objects for creating connection and stack

            self.bus = can.interface.Bus(bustype=self.comboBox.currentText(), channel=self.comboBox_2.currentText(),bitrate=int(bitt))
            self.notifier = can.Notifier(self.bus, [can.Printer()])
            self.tp_addr = isotp.Address(isotp.AddressingMode.Normal_29bits,txid=0x18DDE890,rxid=0x18DDF0E8) #18DD90E8
            self.stack = isotp.NotifierBasedCanStack(bus=self.bus, notifier=self.notifier, address=self.tp_addr, params=isotp_params.isotp_params)
            self.stack.set_sleep_timing(0,0)
            self.conn = PythonIsoTpConnection(self.stack)

what do you think is causing this problem. Has anyone encountered this problem before at high bus load?

pylessard commented 3 months ago

First, careful with your threads, the UDS client is not thread safe. So you cannot call methods from different threads, it might cause race conditions

To understand your issue, please enable logging in debug and share:

  1. The log
  2. Can bus traffic raw dump

Cheers

ichbinbork commented 3 months ago

Sure, you can find the two ".trc" logs in the zip file. First one is succesful flash update process. The second one starts in empty bus then I'm sendind a message with 10ms cycle time. When I activate the message I couldn't catch the server response .For now I can provide only trace log.

logs.zip

pylessard commented 3 months ago

I don't see the python log. Would have been nice to understand what the stack rececives and what is ignored. CAN logs seems fine, I see a complete transmission and a response from the device. I can only assume that the client doe snot see the response.

Having messages from another ECU should not be an issue, the transport layer is supposed to drop unwanted message. Messages have a rate of 10ms which is fine.

If you manage to enable logging in DEBUG, you should see the TransportLayer telling everything it receives with some flags between square brackets next to it [i] or [p]. p stands for processed, [i] for ignored. https://github.com/pylessard/python-can-isotp/blob/v2.x/isotp/protocol.py#L837

ichbinbork commented 3 months ago

Here you can find the log that you mentioned udsoncan.log

I think the main problem the IsoTP transport layer misses the frame thats why UDS client doesn't recieve anything.

"No data received: [TimeoutException] - Did not receive IsoTP frame from the Transport layer in time (timeout=12 sec) 
2024-07-09 16:49:10 [ERROR] UdsClient: [TimeoutException] : Did not receive response in time. P2 timeout time has expired (timeout=12.000 sec)"

In addition to that I just run a simple script that sends change session request in %80 bus load and IsoTP layer miss that too. I think I'm doing something wrong but I couldn't find it yet

pylessard commented 3 months ago

Hi! Thank you for the log. I cannot tell what's wrong from it unfortunately. I was hoping to see the isotp logs as well.

Can you enable it like this logging.getLogger('isotp').setLevel(logging.DEBUG)

Cheers

pylessard commented 3 months ago

What was it?