christoph2/pyxcp

How to use

mortenfc opened this issue · 12 comments

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.

Hi,
Go to pyxcp/examples and use python xcphello.py -h to get list of allowed arguments for given script.

To get the script running, I assume you need to use command like python xcphello.py -c conf_can_vector.toml where in configuration file you will specify transport layer and device details.
However it appears that this library is completely broken on Windows and will always crash on exception during initialization of CAN device - I have here Vector and PeakCAN and I was not able to get it running on neither.

Hi Jared,
Are your crashes reproduceable with python-can examples?
(pyxcp uses python-can under the hood).

I am running from PowerShell using Python 3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)] on win32 Should be stable file

send_one.py
Using send_one.py from python-can examples works fine on PeakCAN and Vector. I can see example message on the bus while using following setup:
bus = can.Bus(interface='vector', app_name='AppName', channel=0, bitrate=500000)
and
bus = can.Bus(interface='pcan', channel='PCAN_USBBUS1', bitrate=500000)
There seems to be some underlying problem with config parser itself.

Crash without conf file
First, when people runs any code from examples, it would be better to tell them that they are missing linked file, instead of crashing on exception like that:

PS D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples> python xcphello.py
Traceback (most recent call last):
  File "D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples\xcphello.py", line 27, in <module>
    with ap.run() as x:
         ^^^^^^^^
  File "C:\Users\...\Python311\Lib\site-packages\pyxcp\cmdline.py", line 58, in run
    raise AttributeError("TRANSPORT must be specified in config!")
AttributeError: TRANSPORT must be specified in config!

Crash on Vector
When I will try to run it with Vector config, I will get this error:

PS D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples> python xcphello.py -c conf_can_vector.toml
Traceback (most recent call last):
  File "D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples\xcphello.py", line 27, in <module>
    with ap.run() as x:
         ^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\cmdline.py", line 60, in run
    master = Master(transport, config=config)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\master\master.py", line 96, in __init__
    self.transport = createTransport(transportName, config)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\transport\base.py", line 318, in createTransport
    return transportClass(*args, **kws)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\transport\can.py", line 309, in __init__
    self.canInterface.loadConfig(config)
  File "C:\...\Python311\Lib\site-packages\pyxcp\transport\can.py", line 250, in loadConfig
    self.config = Configuration(self.PARAMETER_MAP or {}, config or {})
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\config.py", line 44, in __init__
    raise TypeError(f"Parameter {key:s} requires {tp:s}")
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported format string passed to type.__format__

using this TOML file:

TRANSPORT = "CAN"
CAN_DRIVER = "Vector"
APP_NAME = "AppName"
CAN_USE_DEFAULT_LISTENER = true
CHANNEL = "1"
CAN_ID_MASTER = 2
CAN_ID_SLAVE = 1
CAN_ID_BROADCAST = 256
MAX_DLC_REQUIRED = false
CREATE_DAQ_TIMESTAMPS = false
POLL_INTERVAL = 0.01
SERIAL = "None"
RX_QUEUE_SIZE = 16384
FD = false
DATA_BITRATE = "None"

I needed to expand the TOML file, otherwise the crash is even more spectacular with python-can complaining about missing DATA_BITRATE which is not obvious at all from that massive stack. I would probably recommend using the file above with fixed format so people are not struggling with examples.

Crash on PeakCAN
Here the error appears to be the same. I have modified conf_can_user.toml file to use PeakCAN. The TOML file is as follows:

TRANSPORT = "CAN"
CAN_DRIVER = "PCan"
CAN_USE_DEFAULT_LISTENER = true
CHANNEL = "0"
CAN_ID_MASTER = 257
CAN_ID_SLAVE = 258
CAN_ID_BROADCAST = 256
MAX_DLC_REQUIRED = false
BITRATE = 500000
BTL_CYCLES = 16
SAMPLE_RATE = 1
SAMPLE_POINT = 87.5
SJW = 2
TSEG1 = 5
TSEG2 = 2
CREATE_DAQ_TIMESTAMPS = false
STATE = "ACTIVE"

Then I will get same traceback:

PS D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples> python xcphello.py -c conf_can_user.toml
Traceback (most recent call last):
  File "D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples\xcphello.py", line 27, in <module>
    with ap.run() as x:
         ^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\cmdline.py", line 60, in run
    master = Master(transport, config=config)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\master\master.py", line 96, in __init__
    self.transport = createTransport(transportName, config)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\transport\base.py", line 318, in createTransport
    return transportClass(*args, **kws)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\transport\can.py", line 309, in __init__
    self.canInterface.loadConfig(config)
  File "C:\...\Python311\Lib\site-packages\pyxcp\transport\can.py", line 250, in loadConfig
    self.config = Configuration(self.PARAMETER_MAP or {}, config or {})
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\...\Python311\Lib\site-packages\pyxcp\config.py", line 44, in __init__
    raise TypeError(f"Parameter {key:s} requires {tp:s}")
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported format string passed to EnumType.__format__

Hi Jared,

  • The error-message/exception itself was faulty, this is fixed now.
  • In case of a missing configuration file the user now gets a more reasonable error message "Configuration file must be specified! (option: -c < file >)"
  • STATE = "ACTIVE" doesn't work, because STATE is of type enum, which is currently not supported by the configuration system (s. below), on the other hand pyxcp would be pretty useless in passive-/busmonitor-mode...
  • The lines SERIAL = "None" and DATA_BITRATE = "None" won't work as expected (TOML currently has no notion of nil or null values) -- DATA_BITRATE is only relevant for FD applications, if you pass a string parameter or if one would be able to pass None, another issue would arose...
  File "C:\Users\Chris\AppData\Local\Programs\Python\Python310\lib\site-packages\can\util.py", line 220, in _create_bus_config
    config["data_bitrate"] = int(config["data_bitrate"])
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType

😨

Note: I was very busy in the last months, but at the end of the last year I started working on a completely new configuration system, based on traitlets -- well-known from IPython and Jupyter, hope I can continue soon on this topic.

Note #2: there's some confusion about master-/slave-IDs, fixing this issue would be a breaking change.

Following the updated configuration files:

TRANSPORT = "CAN"
CAN_DRIVER = "Vector"
APP_NAME = "AppName"
CAN_USE_DEFAULT_LISTENER = true
CHANNEL = "1"
CAN_ID_MASTER = 2
CAN_ID_SLAVE = 1
CAN_ID_BROADCAST = 256
MAX_DLC_REQUIRED = false
CREATE_DAQ_TIMESTAMPS = false
POLL_INTERVAL = 0.01
RX_QUEUE_SIZE = 16384
FD = false
TRANSPORT = "CAN"
CAN_DRIVER = "PCan"
CAN_USE_DEFAULT_LISTENER = true
CHANNEL = "0"
CAN_ID_MASTER = 257
CAN_ID_SLAVE = 258
CAN_ID_BROADCAST = 256
MAX_DLC_REQUIRED = false
BITRATE = 500000
BTL_CYCLES = 16
SAMPLE_RATE = 1
SAMPLE_POINT = 87.5
SJW = 2
TSEG1 = 5
TSEG2 = 2
CREATE_DAQ_TIMESTAMPS = false

Hi Christoph
After updating to latest pyxcp version I was able to get it running with following setup:
Vector
TOML file:

TRANSPORT = "CAN"
CAN_DRIVER = "Vector"
APP_NAME = "AppName"
CAN_USE_DEFAULT_LISTENER = true
CHANNEL = "0"
CAN_ID_MASTER = 0x9abc1234
CAN_ID_SLAVE = 0x123
CAN_ID_BROADCAST = 256
MAX_DLC_REQUIRED = false
CREATE_DAQ_TIMESTAMPS = false
POLL_INTERVAL = 0.01
RX_QUEUE_SIZE = 16384
BITRATE = 500000
FD = false

I needed to add BITRATE = 500000 to make it running, because python-can probably ignores default setup on Vector Hardware Config, but I am not sure about that
Runs:

PS D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples> python xcphello.py -c conf_can_vector.toml
Slave Properties:
=================
ID: 'xxxx'
{'addressGranularity': EnumIntegerString.new(0, 'BYTE'),
 'byteOrder': EnumIntegerString.new(0, 'INTEL'),
 'maxCto': 8,
 'maxDto': 8,
 'maxWriteDaqMultipleElements': 0,
 'optionalCommMode': False,
 'pgmProcessor': {},
 'protocolLayerVersion': 1,
 'slaveBlockMode': False,
 'supportsCalpag': False,
 'supportsDaq': False,
 'supportsPgm': False,
 'supportsStim': False,
 'transportLayerVersion': 1}

PeakCAN
TOML file

TRANSPORT = "CAN"
CAN_DRIVER = "PCan"
CAN_USE_DEFAULT_LISTENER = true
CHANNEL = "PCAN_USBBUS1"
CAN_ID_MASTER = 0x9abc1234
CAN_ID_SLAVE = 0x123
CAN_ID_BROADCAST = 256
MAX_DLC_REQUIRED = false
BITRATE = 500000
CREATE_DAQ_TIMESTAMPS = false

Here I can remove all the timing parameters, but channel needs to specify USB as per python-can example.

PS D:\Workdir\PyXCP\pyxcp-master\pyxcp\examples> python xcphello.py -c conf_can_user.toml
Slave Properties:
=================
ID: 'xxxx'
{'addressGranularity': EnumIntegerString.new(2, 'DWORD'),
 'byteOrder': EnumIntegerString.new(0, 'INTEL'),
 'maxCto': 8,
 'maxDto': 8,
 'maxWriteDaqMultipleElements': 0,
 'optionalCommMode': False,
 'pgmProcessor': {},
 'protocolLayerVersion': 1,
 'slaveBlockMode': True,
 'supportsCalpag': False,
 'supportsDaq': False,
 'supportsPgm': False,
 'supportsStim': False,
 'transportLayerVersion': 1}

Than you for your help.

IMG-5620
Hi jared52005, I'm working on my senior design project that involves reading an es420 thermo module, I tried using the xcphello.py file with your toml configuration and I got the above error. Is there anyway to get around this? I renamed the file as es420Controller because that is the device I'm trying to read with a raspberry pi 4. Also, would I need to change the CAN_ID_MASTER and CAN_ID_SLAVE values? If so, how would I know what values to set them to?

This is the device I'm trying to read off of with a raspberry pi: https://www.etas.com/en/products/es420_thermo_module_8_ch.php

Any help is appreciated.

Thanks,

aaroniza0

Regarding your error message:
Have you cloned the GH repo or are you using pip?

decode_bytes() is definitly available in the latest repo version.

The ETAS user manual is unclear about the configuration, but I'm pretty sure it is predefined.
A little script gives us some overview:

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

from pprint import pprint

from pyxcp.cmdline import ArgumentParser

ap = ArgumentParser(description="pyXCP DAQ info")

with ap.run() as x:
    x.connect()
    if x.slaveProperties.optionalCommMode:
        x.getCommModeInfo()

    # x.cond_unlock()  # DAQ resource may be locked, e.g. Vector examples 
                      # add something like 
                      #   SEED_N_KEY_DLL="SeedNKeyXcp.dll"
                      # to your configuration file.
    
    daq_info = x.getDaqInfo()
    pprint(daq_info)    # Print DAQ overview.
    
    print("=" * 80)
    num_predefined = daq_info["processor"]["minDaq"]
    if num_predefined > 0:
        print(f"{num_predefined} PREDEFINED DAQ lists:\n")
        try:
            for idx in range(num_predefined):
                list_info = x.getDaqListInfo(idx) # optional command, but makes sense if cfg. is non-dynamic.
                print(f"{idx}: {list_info}")
        except Exception as e:
            print(f'optional command "GET_DAQ_LIST_INFO" not supported: "{repr(e)}"')
    else:
        print("No PREDEFINED DAQ lists.")
    num_predefined=3

    x.disconnect()

Hello, thank you for responding!!

I used pip to install pyxcp, should I be cloning the entire master branch to my raspberry pi?

Also, to run this script should I just enter python filename.py in the command line?

Lastly, is there any way I can communicate with you faster on this?

Thanks,

aaroniza0

Update: My team cloned the master branch to the the pi and tried running the code you sent over, renamed as Daqcode.py, with the default toml file. This is the output from that code. Any suggestions?
image

Hello,
Sorry for the late reply, but I'm really busy this week.

Well, there isn't a one and only default configuration file, but it looks like, you're using conf_can_vector.toml.
If this is intentional, i.e. you need to work with a Vector interface on Linux:
the underlying library canlib has no native Linux support for Vector hardware -- not even sure, if they are shipping Linux drivers...

Linux-CAN communication in most cases works with SocketCAN, in this case install your vendor's drivers and start with conf_socket_can.toml.
But there's some extra command-line action required.

The following sequence works identically with Raspberry PI/CAN Hat and BeagleBone Black/Comms Cape A2

sudo modprobe can
sudo modprobe can_raw
sudo ip link set can0 type can bitrate 500000 restart-ms 100
sudo ip link set up can0

No worries! We used conf_can_vector.toml because we weren't sure what to use, can we just run the python script you sent and expect an output without adding the configuration file? Also, is there a difference between performing pip install pyxcp and cloning the master branch to the raspberry pi?

pyXCP has support for various transport-layers (CAN, ETH, USB, SXI) and within such a layer there are parameters without reasonable defaults, e.g. IP address if one is using TCP or UDP. So a configuration file is strictly required.

I think it's currently better to clone the repo if you run on Linux.