Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use PyXCP to calibrate and measure an ECU #184

Open
PCT-VF opened this issue Nov 26, 2024 · 6 comments
Open

Use PyXCP to calibrate and measure an ECU #184

PCT-VF opened this issue Nov 26, 2024 · 6 comments

Comments

@PCT-VF
Copy link

PCT-VF commented Nov 26, 2024

I have an A2L file that contains a list of variables and their corresponding 'ECU Addresses.' For example:
https://github.com/christoph2/pyA2L/blob/master/examples/example-a2l-file.a2l.
Now, I need to use CAN XCP to read/write the values of these variables based on their addresses. I have reviewed the examples of PyXCP, but they do not work. Could you help provide an example relevant to my requirements? Thank you very much.

@JavierCorado
Copy link

JavierCorado commented Nov 26, 2024

Here is a general guideline for reading and writing once you successfully stablished connecting with your slave:

For reading you have two options, polling and DAQ. If you want to read data through polling you can user the shortUpload and upload methods, the size of the XCP packet determines which one you should use (you can calculate the length of the variable with the data type inside the A2L).

For writing, just like in poll based reading you can use shortDownload and download methods (again you have to calculate the size of the XCP packet just like I mentioned above). Just make sure to pack the data with the corresponding length and data type (you can find this information inside the variable definition in the A2L file).

Note: Be aware if the signal is an array of values or a single value, this affects the length calculation.

@shirayr
Copy link

shirayr commented Nov 26, 2024

@JavierCorado Hi thank trying to use this solution for my case(#183)

but iam failing with initiate the argument parser:
ap = ArgumentParser()
with ap.run() as x:
x.connect()

iam requested to create the conf_file: pyxcp_conf.py

what should i put there if these are my configurations:
i use ethernet, UDP communication, IPV6 host
receive on:
Debug PC
IPv4: 192.168.X.X
IPv6: XXXXXXXXXXXXXXXX
UDP Port: 5555
VLANID: 2
MAC Address: XXXXXXXxX

send to ECU:
PH XCP Slave (KVS):
IPv6: XXXXXXXXXX
UDP Port: XXXX

can you share an example hoe to initiate https://github.com/christoph2/pyxcp/blob/master/pyxcp/cmdline.py ?

@christoph2
Copy link
Owner

Well, pyXCP s basically about XCP and pya2ldb is about A2L...
The interaction of these and other projects will be the task of asamint.

I've created a small example to show the basic procedure of running a DAQ list measurement (Tested with XCPlite).

Note: pya2ldb uses SQLAlchemy under the hood, so arbitrary complex queries are possible, but for the sake of simplicity the example code selects all MEASUREMENTs.

Tip: There is a small command-line utility xcp_fetch_a2l that can be used to fetch the correspondending A2L file.

import time

from pyxcp.cmdline import ArgumentParser
from pyxcp.daq_stim import DaqList, DaqRecorder

from pya2l import DB
from pya2l import model

A2L_FILE = "C_Demo" # No extension -- .a2l is assumed.

db = DB()
session = db.open_create(A2L_FILE)  # Import A2L or open existing .a2ldb

ASAM_TYPE_MAP = {
    "UBYTE": "U8",
    "SBYTE": "I8",
    "UWORD": "U16",
    "SWORD": "I16",
    "ULONG": "U32",
    "SLONG": "I32",
    "A_UINT64": "U64",
    "A_INT64": "I64",
    "FLOAT16_IEEE": "F16",
    "FLOAT32_IEEE": "F32",
    "FLOAT64_IEEE": "F64",
}        
    
measurements = []
for m in session.query(model.Measurement).order_by(model.Measurement.name).all():
    name = m.name
    address = m.ecu_address.address
    address_ext = m.ecu_address_extension.extension if m.ecu_address_extension else 0
    asam_type = m.datatype
    data_type = ASAM_TYPE_MAP.get(asam_type)

    # You may check here if the measurement should be used.
    measurements.append((name, address, address_ext, data_type, ))
    print(f"MEASUREMENT:  {name:<20s} address: 0x{address:08x}:{address_ext}  -- type: {asam_type!r}")


ap = ArgumentParser(description="DAQ test")

EVENT_CHANNEL = 0

daq_lists = [
    DaqList(
        "demo_measurement",
        EVENT_CHANNEL,
        False, # List is DAQ not STIM.
        True,  # Use DAQ timestamps if available.
        measurements,
    )
]

daq_parser = DaqRecorder(daq_lists, "demo_measurement", 1)

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

    x.cond_unlock("DAQ")  # DAQ resource is locked in many cases.

    print("setup DAQ lists.")
    daq_parser.setup()
    print("start DAQ lists.")
    daq_parser.start()

    time.sleep(5 * 60)  # Run for 5 minutes.

    print("Stop DAQ....")
    daq_parser.stop()
    print("finalize DAQ lists.\n")
    x.disconnect()

@christoph2
Copy link
Owner

Regarding basic setup:

First create a configuration file:

xcp-profile create -o pyxcp_conf.py

Then edit pyxcp_conf.py, the relevant lines in case of XCPonEth are:

c.Transport.layer="ETH"

c.Transport.Eth.port=5555
c.Transport.Eth.protocol="UDP"  # or TCP

c.Transport.Eth.host="localhost"  # name or IP of XCP slave

# c.General.seed_n_key_dll="SeedNKeyXcp.dll"   # optional name of Seed-and-Key .dll

A good starting point is the script xcp_info, which gathers some useful information (If a Seed-and-Key .dll is required, you'll notice here...)

@christoph2
Copy link
Owner

I forget to mention:
If the measurement was successful, one can use ex_arrow.py, ex_csv.py, ex_excel.py, ex_mdf.py, ex_sqlite.py to convert from the measurement file (demo_measurement.xmraw in this case) to common file formats.

The necessary dependencies like pyarrow, asammdf, ... are not installed by pyXCP.

@shirayr
Copy link

shirayr commented Nov 28, 2024

Hi thanks !!
2 questions:
1
my pyxcp_conf looks line:
c = get_config() # noqa
c.Transport.layer="ETH"

c.Transport.Eth.protocol="UDP" # or TCP
c.Transport.Eth.ipv6 = True
c.Transport.Eth.bind_to_address="fd53:........masterIPV6"
c.Transport.Eth.bind_to_port=5556

c.Transport.Eth.host = "FD53:......slave ip"
c.Transport.Eth.port=5556 - his is the master port? where should i insert the slave port??

  1. trying to run pyxcp/scripts/xcp_info.py , stuck on:
    \pyxcp\master\errorhandler.py
    executor = Executor()
    res = executor(inst, func, arguments)
    why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants