Giter VIP home page Giter VIP logo

pyxcp's Introduction

pyXCP

Codacy Badge Maintainability Build Status Build status Coverage Status Code style: black GPL License

pyXCP is a lightweight Python library which talks to ASAM MCD-1 XCP enabled devices. These are mainly, but not only, automotive ECUs (Electronic Control Units).

XCP is used to take measurements, to adjust parameters, and to flash during the development process.

XCP also replaces the older CCP (CAN Calibration Protocol).


Installation

pyXCP is hosted on Github, get the latest release: https://github.com/christoph2/pyxcp

You can install pyxcp from source:

pip install -r requirements.txt
python setup.py install

Alternatively, you can install pyxcp from source with pip:

pip install git+https://github.com/christoph2/pyxcp.git

Alternatively, get pyxcp from PyPI:

pip install pyxcp

Requirements

  • Python >= 3.7

  • A running XCP slave (of course).

  • If you are using a 64bit Windows version and want to use seed-and-key .dlls (to unlock resources), a GCC compiler capable of creating 32bit executables is required:

    These .dlls almost always ship as 32bit versions, but you can't load a 32bit .dll into a 64bit process, so a small bridging program (asamkeydll.exe) is required.

First steps

T.B.D.

Features

T.B.D.

References

License

GNU Lesser General Public License v3 or later (LGPLv3+)

pyxcp's People

Contributors

bkadamien avatar chrisoro avatar christoph2 avatar codacy-badger avatar danielhrisca avatar dkuschmierz avatar jacobschaer avatar steffensanwald avatar toebsen avatar torgrimb avatar waszil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyxcp's Issues

python can filter is not correct

the read methodin python_can should be adapted:

first it should listen for the slave ID and second it should listen also for DAQ IDs.

def read(self):
if not self.connected:
#self.parent.logger.debug("Not connected. Returning None.")
return None
try:
#self.parent.logger.debug("Waiting to receive frame...")
frame = self.bus.recv(5)
except CanError:
#self.parent.logger.debug("Error occurred while receiving frame. Returning None.")
return None
else:
if frame is None or frame.arbitration_id != self.parent.can_id_master.id or not len(frame.data):
if frame.arbitration_id != self.parent.can_id_master.id:
print(f"Received frame with unexpected arbitration ID: {frame.arbitration_id}")
return None # Timeout condition.
print(frame)
extended = frame.is_extended_id
identifier = can.Identifier.make_identifier(frame.arbitration_id, extended)
return can.Frame(
id_=identifier,
dlc=frame.dlc,
data=frame.data,
timestamp=frame.timestamp,
)

Can't install pyxcp 0.18.58 on Ubuntu

just make pip install pyxcp==0.18.58 on Ubuntu 20.04.3 LTS.

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for pyxcp
Failed to build pyxcp
ERROR: Could not build wheels for pyxcp, which is required to install pyproject.toml-based projects

SLAVE_ID vs MASTER_ID

Is it possible that slave_id and master_id are swapped within the code?

From my understanding the master_id should be the id pyxcp should use to send data to the ecu. The ecu should response with the slave_id. Other xcp implementations used by vector canape or by peakcan xcp driver interpret the master_id as the id used to send data to the ecu and the slave_id used to receive data from the ecu.

So to summarize it according to xcp documentation:
There are at least 2 ids one id for RES/ERR/EV/SERV/DAQ and another one for CMD/STIM.
The id used by the tool to send data is CMD/STIM which should represent the master_id.
The id used by the tool to receive data is RES/ERR/EV/SERV/DAQ which should represent the slave_id.

error when calling WriteDAQMultiple

 File "devices\xcp.py", line 238, in listen
    reply = func(*args, **kwargs)
  File "devices\xcp.py", line 785, in prepare
    self.master.writeDaqMultiple(part)
  File "d:\Tools\project_venv\pyvenv_dev1.1\lib\site-packages\pyxcp\master\errorhandler.py", line 379, in inner
    res = executor(inst, func, arguments)
  File "d:\Tools\project_venv\pyvenv_dev1.1\lib\site-packages\pyxcp\master\errorhandler.py", line 358, in __call__
    preActions, actions, repeater = handler.actions(*getActions(inst.service, self.error_code))
  File "d:\Tools\project_venv\pyvenv_dev1.1\lib\site-packages\pyxcp\master\errorhandler.py", line 100, in getActions
    preActions, actions = eh.get(error_str)
TypeError: cannot unpack non-iterable NoneType object

I did not have this error with pyxcp 0.12.0

Infinite retry implementation/interpretation

A command timeout that the standard mandates to be indefinitely retry blocks completely the execution of the software flow.
E.g.: Master().connect() on a broken bus or shutdown ECU indefinitely blocks and termination of process is required.

Even though the standard says "Indefinite / Infinte Retry" I would prefer to have a configurable number of times that this is retried (even 0) and after that the command invocation shall just raise an exeption.
The user of the Master class can then decide externally, based on the exception, whether or not to retry.
I think that is the spirit of the "repeat infinte times" XCP protocol standard statement i.e. if it doesn't connect, of course you need to retry until it does.

Specific use case: if the ECU under test is unexpectedly behaving there is no way to automatically get out of the infinte retry.

  1. What do you think about my observation?
  2. Is there already a way to "bypass"/"configure" that indefinite retry without too much runtime patching?

Thank you

Timeout Error on connect

image
image

I keep getting timeout error(thrice) and then it shifts to UnrecoverableError. Any ideas on how to debug this?

REINIT_DAQ

Hi!

I get a sequence error during alloc_odt of my 2nd daq list.
In the standard it says to REINIT_DAQ
image

I can see in the source code this error action is not implemented
image

How do I reinit daq? I can't find any information about it anywhere

For x64 based machines no option to use x64 seed and key dll

On an x64 based Windows machine even if an x64 seed and key dll is available the package still forces the use of an x32 dll and the bridging program (at least I see no other option). It would be good if there was a configuration flag to allow the possibility of using an x64 dll. It certainly works on my system if I force the use_ctypes branch in getKey().

Is there any possibility to make this configurable.

btw. Thanks for making this project available it is extremely useful.

For CAN transport the slave response EV_CMD_PENDING is ignored

When I issue the PROGRAM_START command the slave responds with EV_CMD_PENDING at 0.3ms intervals for approximately 3s. My understanding is that the master should restart the time-out detection on this event. However it seems the master is ignoring these responses and I then see a timeout.

Is this functionality implemented?

Sometimes the master also seems to send the SYNCH command after approximately 1.2ms, but I have not investigated that scenario fully. Either way a SYNCH or timeout seems to be the wrong behaviour.

pip install failed

Hello,
I'm trying install pyxcp by pip install.
But it will be failed at Preparing metadata (pyproject.toml)
here is the error log

Collecting pyxcp
  Using cached pyxcp-0.18.41.tar.gz (123 kB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing metadata (pyproject.toml): started
  Preparing metadata (pyproject.toml): finished with status 'error'

  error: subprocess-exited-with-error
  
  Preparing metadata (pyproject.toml) did not run successfully.
  exit code: 1
  
  [20 lines of output]
  Traceback (most recent call last):
    File "E:\etas\venv\lib\site-packages\pip\_vendor\pep517\in_process\_in_process.py", line 363, in <module>
      main()
    File "E:\etas\venv\lib\site-packages\pip\_vendor\pep517\in_process\_in_process.py", line 345, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "E:\etas\venv\lib\site-packages\pip\_vendor\pep517\in_process\_in_process.py", line 164, in prepare_metadata_for_build_wheel
      return hook(metadata_directory, config_settings)
    File "C:\Users\A50044\AppData\Local\Temp\pip-build-env-wg9qxrkl\overlay\Lib\site-packages\pdm\pep517\api.py", line 59, in prepare_metadata_for_build_wheel
      return _prepare_metadata(builder, metadata_directory)
    File "C:\Users\A50044\AppData\Local\Temp\pip-build-env-wg9qxrkl\overlay\Lib\site-packages\pdm\pep517\api.py", line 39, in _prepare_metadata
      dist_info = Path(metadata_directory, builder.dist_info_name)
    File "C:\Users\A50044\AppData\Local\Temp\pip-build-env-wg9qxrkl\overlay\Lib\site-packages\pdm\pep517\wheel.py", line 128, in dist_info_name
      name = self.meta.project_filename
    File "C:\Users\A50044\AppData\Local\Temp\pip-build-env-wg9qxrkl\overlay\Lib\site-packages\pdm\pep517\base.py", line 144, in meta
      self._meta.validate(True)
    File "C:\Users\A50044\AppData\Local\Temp\pip-build-env-wg9qxrkl\overlay\Lib\site-packages\pdm\pep517\metadata.py", line 87, in validate
      return validate_pep621(self._metadata, raising)
    File "C:\Users\A50044\AppData\Local\Temp\pip-build-env-wg9qxrkl\overlay\Lib\site-packages\pdm\pep517\validator.py", line 85, in validate_pep621
      raise PEP621ValidationError(validator.errors)
  pdm.pep517.exceptions.PEP621ValidationError: {'license': ['none or more than one rule validate', {'oneof definition 0': ['must be of dict type'], 'oneof definition 1': ['must be of dict type']}]}
  [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

Encountered error while generating package metadata.

See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

I've tried python 3.7.4 64bitใ€3.7.4 32 bitใ€ 3.9.10 64bit but all have the same error.
Can you check out what's the problem?

Thank you

Utilize construct's enum access feature

Hi,
I'm wondering if it would be possible to introduce enum member access like this (let's use the CommModeBasic type):

import enum

# new enum-based type definitions:
ByteOrder = Enum(BitsInteger(1), enum.IntEnum('ByteOrder', 'INTEL MOTOROLA', start=0))
AddressGranularity = Enum(BitsInteger(2), enum.IntEnum('AddressGranularity', 'BYTE WORD DWORD RESERVED', start=0))

# new CommModeBasic type definition:
CommModeBasic = BitStruct(
    "optional" / Flag,
    "slaveBlockMode" / Flag,
    Padding(3),
    "addressGranularity" / AddressGranularity ,
    "byteOrder" / ByteOrder
)

This would enable one to check values like this:

cmb = CommModeBasic.parse(b'\x48')
print(cmb.byteOrder == ByteOrder.INTEL)
>> True

What do you think?

No more queues!

Transport layer now uses a flexible, policy based design.
In short:
I you want to continue using queues, there's now a policy object in between, e.g.:

x.daqQueue 
# becomes
x.policy.daqQueue 

No more changes required (this is LegacyFrameAcquisitionPolicy running under the hood).
In any case, have a look at xcphello_recorder.py and run it, even if you are an experienced user!

P.S.: re-run python setup.py develop to rebuild extension module.
Now I have to fix some over-heating problems (including myself), than I'll write some more words.

How to use

Hi!

How do I use this library?
Browsing through source, I also don't understand how it uses an .a2l to set up the client side communication, like INCA and CANoe does.

Infinite loop of listener pyxcp.transport.can.CanInterfaceBase that does not stopping after session disconnect

There is Infinite loop in pyxcp.transport.can.Can.listen. So even if we are closing connection using pyxcp.master.master.Master.disconnect - listener does not stopping pulling data. Seems like an issue for me

How it was reproduced by me
Insert print line into (https://github.com/christoph2/pyxcp/blob/master/pyxcp/transport/can.py#L328) just for visual debug

print("listening")

And then run this one, using config from below

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import struct

from pyxcp.cmdline import ArgumentParser

ap = ArgumentParser(description="pyXCP hello world.")


def run(address):
    with ap.run() as x:
        x.connect()
        print("Connected")
        x.setMta(address=address)
        b_data = x.upload(4)
        print(f"Get params, bytes {b_data}")
        data = struct.unpack('>f', b_data)[0]
        print(f"Get params, decoded {data}")
        print("Disconnecting")
        x.disconnect()
        print("Disconnected")


print("open first XCP session")
run(address=0x528013B8)

print("open second XCP session")
run(address=0x010F4E28)

I was using PeakCan adapter

Config that was used
{
    "TRANSPORT": "CAN",
    "CAN_USE_DEFAULT_LISTENER": true,
    "ACCEPT_VIRTUAL": true,
    "BAUDRATE_PRESET": true,
    "CAN_ID_BROADCAST": 256,
    "MAX_DLC_REQUIRED": false,
    "BTL_CYCLES": 16,
    "SAMPLE_RATE": 1,
    "SAMPLE_POINT": 87.5,
    "SJW": 2,
    "TSEG1": 5,
    "TSEG2": 2,
    "CAN_DRIVER": "PCan",
    "CAN_ID_MASTER": 2572287332,
    "CAN_ID_SLAVE": 2572182781,
    "CREATE_DAQ_TIMESTAMPS": false,
    "CHANNEL": "PCAN_USBBUS1",
    "BITRATE": 500000
}

Watch output of running this code. Even after closing listener still continue running in the loop

output logs.txt

Solution

add into method pyxcp.transport.can.Can.close call to end listener loop using self.finishListener()

Help

Hello,

I'm a senior computer engineering student working on my senior design project at the moment, my project requires reading some hardware through ethernet and the hardware lists xcp on udp/ip as the communication protocol.

My team has to use a raspberry pi, would this library achieve this and work on the pi? If so, how would I install it on my raspberry pi?

I'm new to reading github docs so I apologize if the answer is right in front of me.

Thanks,

aaroniza0

Byte-order is statically little-endian in types.py struct members

Hi,
unfortunately my XCP-slave device is still big-endian, and what has been a problem with CONNECT and has been fixed, now I see that it is a problem throughout the whole types.py.
Every type defined by the construct.Struct that has multi-byte fields, are defined with little-endian types, and therefore parsed incorrectly from a bytestream response from a big-endian slave-device.
As I know, there is no possibility to define fields with endianness to be evaluated runtime with constrcut, so right now I can only think of that we should define all structs for BE and LE case as well, and it should be chosen in the master service functions depending on the slave device byte order.
Or is there a better solution maybe?

deque instead of Queue

Hello,

I'm having a case were using queue.Queue results in packets lost (CarMaker simulation running at ~2.5x and acquiring many signals).

Using collections.deque alleviates this problem.

How to get daq data?

Hello,

I'm using static daq to get measurement
I can startStopSynch ECU to start daq
But how to get daq data from daqQueue or other method?

My master ID is 0x300, slave ID is 0x200
And my daq event list ID are 0x301, 0x302 and 0x303
image

I notice that daqQueue feed in processResponse function
But processResponse only trigger when receive 0x300, it does not trigger when daq start in can bus

Is there any other way to get data from daq?

My ECU currently not support dynamic daq

pypi

It would be very nice to have the package available on pypi

Slave byteorder is not used in master

I have a slave device with Motorola byte order, and all the master methods that use struct.pack/unpack, are hard-wired with '<' which means Intel. Therefore these do not work, for example setMta.

I suggest that the MasterBaseType should have slaveByteOrder and/or slaveByteOrderStructChar fields, and these should be updated when parsing the connect response:

response = self.transport.request(types.Command.CONNECT, 0x00)
result = types.ConnectResponse.parse(response)
...
self.slaveByteOrder = result.commModeBasic.byteOrder
if self.slaveByteOrder == 'MOTOROLA':
    self.slaveByteOrderStructChar = '>'
else:
    self.slaveByteOrderStructChar = '<'

and after this, the master methods can use this:

# in setMta:
addr = struct.pack("%sI" % self.slaveByteOrderStructChar, address)
...

Or am I missing something?
Thanks!

can interfaces not working

version: 0.18.46

I can`t initialize any can interface, the can transport module does not find any sublasses and returns an empty list

def registered_drivers():
    """
    Returns
    -------
    dict (name, class)
        Dictionary containing CAN driver names and classes of all
        available drivers (pyxcp supplied and user-defined).
    """
    sub_classes = CanInterfaceBase.__subclasses__()
    return OrderedDict(zip(([c.__name__ for c in sub_classes]), sub_classes))

I also noticed other issues:

def isExtendedIdentifier(identifier: int) -> bool:
    """Check for extendend CAN identifier.

    Parameters
    ----------
    identifier: int

    Returns
    -------
    bool
    """
    return (identifier & CAN_EXTENDED_ID) == CAN_EXTENDED_ID

IDs can be extended although they are smaller than 11bit
I think the only way to be sure is to use an additional config variable to set extended or normal IDs.

Also the SLAVE and MASTER ID seem to be used reversed:

    def transmit(self, payload):
        frame = Message(
            arbitration_id=self.parent.can_id_slave.id,
            is_extended_id=True if self.parent.can_id_slave.is_extended else False,
            is_fd=self.is_fd,
            data=payload,
        )
        self.bus.send(frame)

I think this should be the master ID

Configure SocketCAN for FD

Hello,
I'm trying to use pyxcp to connect to CAN-FD XCP slave. I'm using a raspberry pi as master, using socketCAN. I pass the parameter FD = True in the configuration file but it does not make a difference. The board's CAN interface is up and running and configured for CAN-FD at 500kb bit-rate and 2000000 data bit-rate. I can see the CAN XCP frames (connect) coming out as a regular CAN frame, with 8 data bytes (I need CAN-FD and 64 data bytes). Am I missing any parameter in my configuration?
Thanks
/RA

push and _block_downloader convenience method do not wait for response

I have started using the push function to write to longer array characteristics and have discovered that both the push and _block_downloader methods always use the 'download' method with the blockModeLength != None and the 'download_next, with last == False. This means that the transport layer is not waiting for the response at the end of the block. This is true even for short data blocks that can be sent in a single download. I think both methods need a last flag and to be used in much the same way that I use the program methods as I discussed in Issue #88 (flash.txt), in answer to your question about programming via XCP.

unreliable socket.fileno()

Hello all,

I've come across a very strange problem related to the value returned by socket.fileno. We use this to check if a socket connection was terminated on the slave side by comparing to -1 here, but it looks like this is not reliable.

I've come to this after investigating another issue were the CPU usage would go to 100%. I finally was able to track it down to the same while loop. The problem was that after the server was closed the socket fileno remained the same, causing the select call to return immediately. This basically created a very tight while loop that consumed all the CPU.

To demonstrate this I've made this change to the while loop

        while True:
            try:
                if close_event_set() or socket_fileno() == -1:
                    return
                t = perf_counter()
                sel = select(0.2)
                t = perf_counter()-t
                print('Select took',t)
                for _, events in sel:
                    if events & EVENT_READ:
                        if high_resolution_time:
                            recv_timestamp = time()
                        else:
                            recv_timestamp = timestamp_origin + perf_counter() - perf_counter_origin

                        if use_tcp:
                            _packets.append((sock_recv(RECV_SIZE), recv_timestamp))
                        else:
                            response, _ = sock_recv(Eth.MAX_DATAGRAM_SIZE)
                            _packets.append((response, recv_timestamp))
                            
                        if t < 0.001:
                            print(_packets[-1])
                print('Socket fileno = ', socket_fileno())
                sleep(0.2)
            except:
                self.status = 0  # disconnected
                break

and I've ran the test setup from the screen recording. When the CarMaker simulation is set to pause we can see the select call taking ~200ms. The the simulation is stopped and the application terminated, but the socket fileno remains unchanged and the select call returns immediately/.
socket_problem

What could we use to check for the socket termination?

[Question] Retrieve timestamp from frame

While looking at the documentation it mentions that after the identification and before the data fields there is a timestamp in the XCP message frame.

Is there a method inside the master that could achieve this? Or would we have to retrieve the raw data to access this value? This would be for DAQ and polling

I noticed that in the base transport layer, there is a timestamp, but is this the same one that I am referring to?

image

pc_pcan.py state config should be of type BusState

I just tested using the updated python-can binding with pyxcp. Works like magic, however I had to update the 'STATE' config to type BusState instead of string in pc_pcan.py in the transport to get mine to work at least.

Reception of ODTs in DTOs

My code is receiving ODTs from slave DAQ configuration.

I had to study the pyxcp code to understand that self.cro_callback can be set in order to get notifications on reception of DTOs.

Even though the "workaround" is to just assign a callback method to master.transport.cro_callback, it would be nicer to have a specific API in Master() class to decrease dependency on a specific pyxcp version.

What do you think?

Push in master.py is failing due to incorrect interface

pyxcp version affected: 0.18.52

While using the push function of master, the following problem occurs:

File "xxxx\lib\site-packages\pyxcp\master\master.py", line 605, in push callback=callback, File "xxxx\lib\site-packages\pyxcp\master\master.py", line 676, in _generalized_downloader block_downloader(block) File "xxxx\lib\site-packages\pyxcp\master\master.py", line 729, in _block_downloader dl_func(packet_data, remaining, last=True) File "xxxx\lib\site-packages\pyxcp\master\errorhandler.py", line 376, in inner res = executor(inst, func, arguments) File "xxxx\lib\site-packages\pyxcp\master\errorhandler.py", line 337, in __call__ raise UnrecoverableError("Don't know how to handle exception '{}'".format(repr(e))) from e pyxcp.master.errorhandler.UnrecoverableError: Don't know how to handle exception 'TypeError("download() got an unexpected keyword argument 'last'")'

I think the download() function in master.py is missing the last attribute (see program).

SeedAndKey DLL returned: ERR_COULD_NOT_LOAD_DLL

@christoph2
Hello everybody, I'm trying to run the example xcp_unlock and got this error SeedAndKey DLL returned ERR_COULD_NOT_LOAD_DLL
I've put the seed and key file as parameter but it was not found by the python application. Running in a debian 10 linux version, I tried with .so file and with .dll and got the same error

SeedAndKey DLL returned ERR_COULD_NOT_LOAD_DLL

This is my conf_socket_can file:

TRANSPORT = "CAN"
CAN_DRIVER = "SocketCAN"
CAN_USE_DEFAULT_LISTENER = true
CHANNEL = "can1"
CAN_ID_MASTER = 0x7FE
CAN_ID_SLAVE = 0x7FD
CAN_ID_BROADCAST = 256
CREATE_DAQ_TIMESTAMPS = false
FD = false
MAX_DLC_REQUIRED = true
MAX_CAN_FD_DLC = 32
PADDING_VALUE = 0
BITRATE = 1000000

Python 3.7.3
Debian 10 buster
armv7l GNU/Linux

Unable to connect after disconnect() in base.py

The helloxcp.py example works fine, but just once. When the script is run for a second time I get

ERROR:pyxcp.pyxcp.master.errorhandler:XcpTimeoutError

Seems like it does not close the connection entirely, but I am not sure.

How to collect and save the XCP data ?

Thanks for this useful and amazing work!

Hello, I'm a rookie in the vehicle industry. Recently, I started to collect and record xcp data. At the same time, I noticed that besides pyxcp, you also have an open source project called pyA2L. I would like to know if it is possible to read .a2l files via pyxcp and pyA2L while saving the received ECU data. If it is possible, can you give me some guidance on what should I do? Thank you very much!

Any OEM ECUs with open XCP?

Sorry for an offtopic question again but what kind of hardware+A2L combo can I get on a bench to see pyxcp traffic?

Memory usage increases over time

It appears that XCP is increasing memory usage over time.

I actually could find at least a couple of spots where allocation happens while never freeing:

  • self.evQueue.append(response) (line 292 of base.py)
  • self.servQueue.append(response) (line 295 of base.py,)
  • self.daqQueue.append (line 314 of base.py)

As far as I understand these queues are mostly / only used for testing only. Is that the case?

As a workaround in my application I can definitely deque them from time to time but it would be nicer to handle that internally / enable them only for debug.

_block_downloader needs to consider case where "remaining" branch not called

I didn't spot this in my original example but there is the use case for the _block_downloader where the data fits exactly in an integer number of packets. In this case the "remaining" branch is not called and the expected response is not waited for. So the calls to the dl_next and dl_next_func in the main for loop also need to consider setting the 'last' flag, something like:

    for index in packets:
        packet_data = data[offset : offset + max_packet_size]
        last = (remaining_block_size - max_packet_size) == 0:
        if index == 0:
            dl_func(packet_data, length, last)  # Transmit the complete length in the first CTO.
        else:
            dl_next_func(packet_data, remaining_block_size, last)
        offset += max_packet_size
        remaining_block_size -= max_packet_size
        delay(minSt)

XcpResponseError [ERR_ACCESS_LOCKED] - Seed and Key unlock process error

hello everyone I would like to share the error I am having in the seed and key unlock process, for some reason the ECU does not unlock any features, I validated that my Seed and Key file is working using a third party software such as INCA software and it worked . Now the same process using pyXCP I am having the following error when sending the unlock command:
XcpResponseError [ERR_ACCESS_LOCKED
L2 C4 [fe 25]

I am using a Debian 10 and .so seed and key file

Code I'm using to unlock the ECU

from pyxcp.cmdline import ArgumentParser
from pyxcp import types



def callout(master, args):
    if args.sk_dll:
        master.seedNKeyDLL = args.sk_dll


ap = ArgumentParser(callout)
ap.parser.add_argument(
    "-s",
    "--sk-dll",
    dest="sk_dll",
    help="Seed-and-Key .DLL name",
    type=str,
    default=None,
)

with ap.run() as x:
    x.connect()
    rps = x.getCurrentProtectionStatus()
    print("Protection before unlocking:", rps, end="\n\n")
    print(x.getStatus())




    result = x.cond_unlock("daq") ## ERROR HERE
    print("X.cond_unlock result: ", result)
    rps = x.getCurrentProtectionStatus()
    print("Protection after unlocking:", rps)

    x.disconnect()

Here is the error log from pyXCP

DEBUG:pyxcp.transport.Base:Python-CAN driver: socketcan - socketcan channel 'can1']
DEBUG:pyxcp.transport.Base:CONNECT
DEBUG:pyxcp.transport.Base:-> [ff 00]
DEBUG:pyxcp.transport.Base:<- L8 C0 [ff 05 c0 08 08 00 01 01]
DEBUG:pyxcp.transport.Base:GET_STATUS
DEBUG:pyxcp.transport.Base:-> [fd]
DEBUG:pyxcp.transport.Base:<- L6 C1 [ff 00 1d 00 00 00]
DEBUG:pyxcp.transport.Base:GET_SEED
DEBUG:pyxcp.transport.Base:-> [f8 00 04]
DEBUG:pyxcp.transport.Base:<- L6 C2 [ff 04 <MY SEED HERE>]
DEBUG:pyxcp.transport.Base:UNLOCK
DEBUG:pyxcp.transport.Base:-> [f7 04 <MY KEY HERE>]
DEBUG:pyxcp.transport.Base:<- L2 C3 [fe 25]
[ERROR (pyxcp.pyxcp.master.errorhandler)]: XcpResponseError [ERR_ACCESS_LOCKED]
[ERROR (pyxcp.pyxcp.master.errorhandler)]: XcpResponseError [ERR_ACCESS_LOCKED]
ERROR:pyxcp.pyxcp.master.errorhandler:XcpResponseError [ERR_ACCESS_LOCKED]
Try to handle error -- Service: UNLOCK Error-Code: ERR_ACCESS_LOCKED
ERROR:pyXCP:Traceback (most recent call last):
  File "xcp_unlock.py", line 50, in <module>
    result = x.cond_unlock("daq")
  File "/mnt/SD/pyxcp/env/lib/python3.7/site-packages/pyxcp/master/master.py", line 1772, in cond_unlock
    self.unlock(key_length, key)
  File "/mnt/SD/pyxcp/env/lib/python3.7/site-packages/pyxcp/master/errorhandler.py", line 376, in inner
    res = executor(inst, func, arguments)
  File "/mnt/SD/pyxcp/env/lib/python3.7/site-packages/pyxcp/master/errorhandler.py", line 346, in __call__
    preActions, actions, repeater = handler.actions(*getActions(inst.service, self.error_code))
  File "/mnt/SD/pyxcp/env/lib/python3.7/site-packages/pyxcp/master/errorhandler.py", line 258, in actions
    raise UnhandledError("Could not proceed due to unhandled error.")
pyxcp.master.errorhandler.UnhandledError: Could not proceed due to unhandled error.

Please if anyone can help I would be very grateful

DISCONNECT master command does never timeout but retries indefinitely

DISCONNECT master command does never timeout but retries indefinitely.

The standard says that DISCONNECT shall be retried max 2 times before giving up; SYNCH shall also be issued before as a pre-action.

So, I'd expect:
DISCONNECT -> disconnect timeout -> SYNC -> SYNC timeout -> SYNC timeout -> raise Timeout Exception.
Or, alternatively:
DISCONNECT -> disconnect timeout (retry=1) -> SYNC -> SYNC timeout (rety=1) -> SYNC timeout(retry=0) -> DISCONNECT -> disconnect timeout (retry=0) -> SYNC -> SYNC timeout (retry=1) -> SYNC timeout (retry=0) -> finally, raise Timeout Exception for DISCONNECT.

Please be aware that I am still not aware of many little details of the XCP protocol, so please correct me if I'm wrong.

Use-case: disconnect a slave which is potentially connected, just as a matter of fact to reset communication from a known state.

EDIT: as a hint, I believe there is some strange behavior in the Executor().call class and method. In particular, self.repeater is never ever invoked due to self.error_code never being set to None or so.
EDIT2: what I'm seeing on the canbus is the following sequence of master -> slave frames:
FE -> 2seconds -> FC -> 2 seconds -> FC -> 2 seconds -> FC -> 2 seconds -> FC .... forever. The slave doesn't answer because it is already disconnected.

pyxcp license

Hello Christoph,

as you probably know GPLv2 is incompatible with GPLv3 and LGPLv3. This make it impossible to incorporate pyxcp in an application together with other libraries. (see https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility)

More so in the CAN transport pyxcp imports python-can which is licensed under LGPLv3 (see

from can import Bus, CanError, Message
)

Would you consider switching to a more generally compatible license like GPLv2 or later or GPLv3 ?

Transport ETH socket bind

Hi All,

is it possible to add in transport/eth.py the possibility to bind the socket to concrete IP address defined in config?

For IPv6 when You have multiple IPs assigned to the ETH adapter, sometimes You need to pick up concrete IP.
pyxcp_transport_eth_py.zip

Best Regard,

Peter

pyxcp/master/master.py the connect method cannot be called more than once

For now Master.connect method do two things setup transport layer (transport.connect()) and also invoke XCP command connect but it will be really nice to have possibility to invoke only XCP command.

There can be for example bool argument setup_transport_layer:

def connect(self, mode=0x00, setup_transport_layer=True):
    if setup_transport_layer:
	    self.transport.connect()
    response = self.transport.request(types.Command.CONNECT, mode & 0xFF)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.