pyxcp 0.25.4__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyxcp/__init__.py +20 -0
- pyxcp/aml/EtasCANMonitoring.a2l +82 -0
- pyxcp/aml/EtasCANMonitoring.aml +67 -0
- pyxcp/aml/XCP_Common.aml +408 -0
- pyxcp/aml/XCPonCAN.aml +78 -0
- pyxcp/aml/XCPonEth.aml +33 -0
- pyxcp/aml/XCPonFlx.aml +113 -0
- pyxcp/aml/XCPonSxI.aml +66 -0
- pyxcp/aml/XCPonUSB.aml +106 -0
- pyxcp/aml/ifdata_CAN.a2l +20 -0
- pyxcp/aml/ifdata_Eth.a2l +11 -0
- pyxcp/aml/ifdata_Flx.a2l +94 -0
- pyxcp/aml/ifdata_SxI.a2l +13 -0
- pyxcp/aml/ifdata_USB.a2l +81 -0
- pyxcp/asam/__init__.py +0 -0
- pyxcp/asam/types.py +131 -0
- pyxcp/asamkeydll.c +116 -0
- pyxcp/asamkeydll.exe +0 -0
- pyxcp/asamkeydll.sh +2 -0
- pyxcp/checksum.py +732 -0
- pyxcp/cmdline.py +71 -0
- pyxcp/config/__init__.py +1257 -0
- pyxcp/config/legacy.py +120 -0
- pyxcp/constants.py +47 -0
- pyxcp/cpp_ext/__init__.py +0 -0
- pyxcp/cpp_ext/aligned_buffer.hpp +168 -0
- pyxcp/cpp_ext/bin.hpp +105 -0
- pyxcp/cpp_ext/blockmem.hpp +58 -0
- pyxcp/cpp_ext/cpp_ext.cp310-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/cpp_ext.cp311-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/cpp_ext.cp312-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/cpp_ext.cp313-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/daqlist.hpp +374 -0
- pyxcp/cpp_ext/event.hpp +67 -0
- pyxcp/cpp_ext/extension_wrapper.cpp +131 -0
- pyxcp/cpp_ext/framing.hpp +360 -0
- pyxcp/cpp_ext/helper.hpp +280 -0
- pyxcp/cpp_ext/mcobject.hpp +248 -0
- pyxcp/cpp_ext/sxi_framing.hpp +332 -0
- pyxcp/cpp_ext/tsqueue.hpp +46 -0
- pyxcp/daq_stim/__init__.py +291 -0
- pyxcp/daq_stim/optimize/__init__.py +67 -0
- pyxcp/daq_stim/optimize/binpacking.py +41 -0
- pyxcp/daq_stim/scheduler.cpp +62 -0
- pyxcp/daq_stim/scheduler.hpp +75 -0
- pyxcp/daq_stim/stim.cp310-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cp311-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cp312-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cp313-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cpp +13 -0
- pyxcp/daq_stim/stim.hpp +604 -0
- pyxcp/daq_stim/stim_wrapper.cpp +50 -0
- pyxcp/dllif.py +100 -0
- pyxcp/errormatrix.py +878 -0
- pyxcp/examples/conf_can.toml +19 -0
- pyxcp/examples/conf_can_user.toml +16 -0
- pyxcp/examples/conf_can_vector.json +11 -0
- pyxcp/examples/conf_can_vector.toml +11 -0
- pyxcp/examples/conf_eth.toml +9 -0
- pyxcp/examples/conf_nixnet.json +20 -0
- pyxcp/examples/conf_socket_can.toml +12 -0
- pyxcp/examples/run_daq.py +165 -0
- pyxcp/examples/xcp_policy.py +60 -0
- pyxcp/examples/xcp_read_benchmark.py +38 -0
- pyxcp/examples/xcp_skel.py +48 -0
- pyxcp/examples/xcp_unlock.py +36 -0
- pyxcp/examples/xcp_user_supplied_driver.py +43 -0
- pyxcp/examples/xcphello.py +65 -0
- pyxcp/examples/xcphello_recorder.py +107 -0
- pyxcp/master/__init__.py +10 -0
- pyxcp/master/errorhandler.py +677 -0
- pyxcp/master/master.py +2641 -0
- pyxcp/py.typed +0 -0
- pyxcp/recorder/.idea/.gitignore +8 -0
- pyxcp/recorder/.idea/misc.xml +4 -0
- pyxcp/recorder/.idea/modules.xml +8 -0
- pyxcp/recorder/.idea/recorder.iml +6 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +7 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/index.pb +7 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +0 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/index.pb +7 -0
- pyxcp/recorder/.idea/vcs.xml +10 -0
- pyxcp/recorder/__init__.py +96 -0
- pyxcp/recorder/build_clang.cmd +1 -0
- pyxcp/recorder/build_clang.sh +2 -0
- pyxcp/recorder/build_gcc.cmd +1 -0
- pyxcp/recorder/build_gcc.sh +2 -0
- pyxcp/recorder/build_gcc_arm.sh +2 -0
- pyxcp/recorder/converter/__init__.py +444 -0
- pyxcp/recorder/lz4.c +2829 -0
- pyxcp/recorder/lz4.h +879 -0
- pyxcp/recorder/lz4hc.c +2041 -0
- pyxcp/recorder/lz4hc.h +413 -0
- pyxcp/recorder/mio.hpp +1714 -0
- pyxcp/recorder/reader.hpp +138 -0
- pyxcp/recorder/reco.py +278 -0
- pyxcp/recorder/recorder.rst +0 -0
- pyxcp/recorder/rekorder.cp310-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cp311-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cp312-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cp313-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cpp +59 -0
- pyxcp/recorder/rekorder.hpp +274 -0
- pyxcp/recorder/setup.py +41 -0
- pyxcp/recorder/test_reko.py +34 -0
- pyxcp/recorder/unfolder.hpp +1354 -0
- pyxcp/recorder/wrap.cpp +184 -0
- pyxcp/recorder/writer.hpp +302 -0
- pyxcp/scripts/__init__.py +0 -0
- pyxcp/scripts/pyxcp_probe_can_drivers.py +20 -0
- pyxcp/scripts/xcp_examples.py +64 -0
- pyxcp/scripts/xcp_fetch_a2l.py +40 -0
- pyxcp/scripts/xcp_id_scanner.py +18 -0
- pyxcp/scripts/xcp_info.py +159 -0
- pyxcp/scripts/xcp_profile.py +26 -0
- pyxcp/scripts/xmraw_converter.py +31 -0
- pyxcp/stim/__init__.py +0 -0
- pyxcp/tests/test_asam_types.py +24 -0
- pyxcp/tests/test_binpacking.py +186 -0
- pyxcp/tests/test_can.py +1324 -0
- pyxcp/tests/test_checksum.py +95 -0
- pyxcp/tests/test_daq.py +193 -0
- pyxcp/tests/test_daq_opt.py +426 -0
- pyxcp/tests/test_frame_padding.py +156 -0
- pyxcp/tests/test_framing.py +262 -0
- pyxcp/tests/test_master.py +2116 -0
- pyxcp/tests/test_transport.py +177 -0
- pyxcp/tests/test_utils.py +30 -0
- pyxcp/timing.py +60 -0
- pyxcp/transport/__init__.py +13 -0
- pyxcp/transport/base.py +484 -0
- pyxcp/transport/base_transport.hpp +0 -0
- pyxcp/transport/can.py +660 -0
- pyxcp/transport/eth.py +254 -0
- pyxcp/transport/hdf5_policy.py +129 -0
- pyxcp/transport/sxi.py +209 -0
- pyxcp/transport/transport_ext.cp310-win_amd64.pyd +0 -0
- pyxcp/transport/transport_ext.cp311-win_amd64.pyd +0 -0
- pyxcp/transport/transport_ext.cp312-win_amd64.pyd +0 -0
- pyxcp/transport/transport_ext.cp313-win_amd64.pyd +0 -0
- pyxcp/transport/transport_ext.hpp +214 -0
- pyxcp/transport/transport_wrapper.cpp +249 -0
- pyxcp/transport/usb_transport.py +229 -0
- pyxcp/types.py +987 -0
- pyxcp/utils/__init__.py +127 -0
- pyxcp/utils/cli.py +78 -0
- pyxcp/vector/__init__.py +0 -0
- pyxcp/vector/map.py +82 -0
- pyxcp-0.25.4.dist-info/METADATA +341 -0
- pyxcp-0.25.4.dist-info/RECORD +157 -0
- pyxcp-0.25.4.dist-info/WHEEL +4 -0
- pyxcp-0.25.4.dist-info/entry_points.txt +9 -0
- pyxcp-0.25.4.dist-info/licenses/LICENSE +165 -0
pyxcp/utils/__init__.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import datetime
|
|
3
|
+
import functools
|
|
4
|
+
import operator
|
|
5
|
+
import sys
|
|
6
|
+
from binascii import hexlify
|
|
7
|
+
from enum import IntEnum
|
|
8
|
+
from time import perf_counter, sleep
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
import chardet
|
|
12
|
+
import pytz
|
|
13
|
+
|
|
14
|
+
from pyxcp.cpp_ext.cpp_ext import TimestampInfo
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def hexDump(arr: Union[bytes | bytearray]):
|
|
18
|
+
if isinstance(arr, (bytes, bytearray)):
|
|
19
|
+
size = len(arr)
|
|
20
|
+
try:
|
|
21
|
+
arr = arr.hex()
|
|
22
|
+
except BaseException: # noqa: B036
|
|
23
|
+
arr = hexlify(arr).decode("ascii")
|
|
24
|
+
return "[{}]".format(" ".join([arr[i * 2 : (i + 1) * 2] for i in range(size)]))
|
|
25
|
+
elif isinstance(arr, (list, tuple)):
|
|
26
|
+
arr = bytes(arr)
|
|
27
|
+
size = len(arr)
|
|
28
|
+
try:
|
|
29
|
+
arr = arr.hex()
|
|
30
|
+
except BaseException: # noqa: B036
|
|
31
|
+
arr = hexlify(arr).decode("ascii")
|
|
32
|
+
return "[{}]".format(" ".join([arr[i * 2 : (i + 1) * 2] for i in range(size)]))
|
|
33
|
+
else:
|
|
34
|
+
return "[{}]".format(" ".join([f"{x:02x}" for x in arr]))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def seconds_to_nanoseconds(value: float) -> int:
|
|
38
|
+
return int(value * 1_000_000_000)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def slicer(iterable, sliceLength, converter=None):
|
|
42
|
+
if converter is None:
|
|
43
|
+
converter = type(iterable)
|
|
44
|
+
length = len(iterable)
|
|
45
|
+
return [converter(iterable[item : item + sliceLength]) for item in range(0, length, sliceLength)]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def functools_reduce_iconcat(a):
|
|
49
|
+
return functools.reduce(operator.iconcat, a, [])
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def flatten(*args):
|
|
53
|
+
"""Flatten a list of lists into a single list.
|
|
54
|
+
|
|
55
|
+
s. https://stackoverflow.com/questions/952914/how-do-i-make-a-flat-list-out-of-a-list-of-lists
|
|
56
|
+
"""
|
|
57
|
+
return functools.reduce(operator.iconcat, args, [])
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def getPythonVersion():
|
|
61
|
+
return sys.version_info
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def decode_bytes(byte_str: bytes) -> str:
|
|
65
|
+
"""Decode bytes with the help of chardet"""
|
|
66
|
+
encoding = chardet.detect(byte_str).get("encoding")
|
|
67
|
+
if not encoding:
|
|
68
|
+
return byte_str.decode("ascii", "ignore")
|
|
69
|
+
else:
|
|
70
|
+
return byte_str.decode(encoding)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
PYTHON_VERSION = getPythonVersion()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def short_sleep():
|
|
77
|
+
sleep(0.0005)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def delay(amount: float):
|
|
81
|
+
"""Performe a busy-wait delay, which is much more precise than `time.sleep`"""
|
|
82
|
+
|
|
83
|
+
start = perf_counter()
|
|
84
|
+
while perf_counter() < start + amount:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class CurrentDatetime(TimestampInfo):
|
|
89
|
+
def __init__(self, timestamp_ns: int):
|
|
90
|
+
TimestampInfo.__init__(self, timestamp_ns)
|
|
91
|
+
timezone = pytz.timezone(self.timezone)
|
|
92
|
+
dt = datetime.datetime.fromtimestamp(timestamp_ns / 1_000_000_000.0)
|
|
93
|
+
self.utc_offset = int(timezone.utcoffset(dt).total_seconds() / 60)
|
|
94
|
+
self.dst_offset = int(timezone.dst(dt).total_seconds() / 60)
|
|
95
|
+
|
|
96
|
+
def __str__(self):
|
|
97
|
+
return f"""CurrentDatetime(
|
|
98
|
+
datetime="{datetime.datetime.fromtimestamp(self.timestamp_ns / 1_000_000_000.0)!s}",
|
|
99
|
+
timezone="{self.timezone}",
|
|
100
|
+
timestamp_ns={self.timestamp_ns},
|
|
101
|
+
utc_offset={self.utc_offset},
|
|
102
|
+
dst_offset={self.dst_offset}
|
|
103
|
+
)"""
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def enum_from_str(enum_class: IntEnum, enumerator: str) -> IntEnum:
|
|
107
|
+
"""Create an `IntEnum` instance from an enumerator `str`.
|
|
108
|
+
|
|
109
|
+
Parameters
|
|
110
|
+
----------
|
|
111
|
+
enum_class: IntEnum
|
|
112
|
+
|
|
113
|
+
enumerator: str
|
|
114
|
+
|
|
115
|
+
Examples
|
|
116
|
+
--------
|
|
117
|
+
|
|
118
|
+
class Color(enum.IntEnum):
|
|
119
|
+
RED = 0
|
|
120
|
+
GREEN = 1
|
|
121
|
+
BLUE = 2
|
|
122
|
+
|
|
123
|
+
color: Color = enum_from_str(Color, "GREEN")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
return enum_class(enum_class.__members__.get(enumerator))
|
pyxcp/utils/cli.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Reusable command-line parser utilities.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import sys
|
|
10
|
+
from collections.abc import Sequence
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class StrippingParser:
|
|
14
|
+
"""Base class for parsers that can strip recognized arguments from sys.argv.
|
|
15
|
+
|
|
16
|
+
This is useful when multiple argument parsers are used in a single process (chained),
|
|
17
|
+
and downstream parsers should not see arguments already handled by an
|
|
18
|
+
upstream parser.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, parser: argparse.ArgumentParser) -> None:
|
|
22
|
+
"""Initialize with an existing ArgumentParser instance."""
|
|
23
|
+
self._parser = parser
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def parser(self) -> argparse.ArgumentParser:
|
|
27
|
+
"""Return the underlying ArgumentParser instance."""
|
|
28
|
+
return self._parser
|
|
29
|
+
|
|
30
|
+
def parse_known(self, argv: Sequence[str] | None = None) -> tuple[argparse.Namespace, list[str]]:
|
|
31
|
+
"""Parse known args from ``argv`` and return (namespace, remaining).
|
|
32
|
+
|
|
33
|
+
Does not mutate ``sys.argv``.
|
|
34
|
+
"""
|
|
35
|
+
if argv is None:
|
|
36
|
+
argv = sys.argv[1:]
|
|
37
|
+
namespace, remaining = self._parser.parse_known_args(argv)
|
|
38
|
+
|
|
39
|
+
# Emulate standard -h/--help behavior if "help" is in the namespace
|
|
40
|
+
if getattr(namespace, "help", False):
|
|
41
|
+
# Print help and exit similarly to ArgumentParser
|
|
42
|
+
# We need a temporary full parser to render standard help including program name
|
|
43
|
+
full = argparse.ArgumentParser(description=self._parser.description)
|
|
44
|
+
for action in self._parser._actions:
|
|
45
|
+
if action.option_strings and action.dest == "help":
|
|
46
|
+
continue
|
|
47
|
+
full._add_action(action)
|
|
48
|
+
full.print_help()
|
|
49
|
+
sys.exit(0)
|
|
50
|
+
|
|
51
|
+
return namespace, list(remaining)
|
|
52
|
+
|
|
53
|
+
def strip_from_argv(self, argv: list[str] | None = None) -> None:
|
|
54
|
+
"""Remove this parser's recognized options from ``sys.argv`` in-place.
|
|
55
|
+
|
|
56
|
+
If ``argv`` is provided, it is treated as a mutable list whose content
|
|
57
|
+
will be replaced with the stripped version (first element preserved as
|
|
58
|
+
program name). If omitted, ``sys.argv`` is modified.
|
|
59
|
+
"""
|
|
60
|
+
arg_list = argv if argv is not None else sys.argv
|
|
61
|
+
if not arg_list:
|
|
62
|
+
return
|
|
63
|
+
_, remaining = self.parse_known(arg_list[1:])
|
|
64
|
+
# Rebuild argv with program name + remaining
|
|
65
|
+
prog = arg_list[0]
|
|
66
|
+
arg_list[:] = [prog] + remaining
|
|
67
|
+
|
|
68
|
+
def parse_and_strip(self, argv: list[str] | None = None) -> argparse.Namespace:
|
|
69
|
+
"""Parse options and strip them from argv; returns the parsed namespace."""
|
|
70
|
+
arg_list = argv if argv is not None else sys.argv
|
|
71
|
+
if not arg_list:
|
|
72
|
+
# Fallback for empty list
|
|
73
|
+
return self.parse_known([])[0]
|
|
74
|
+
namespace, remaining = self.parse_known(arg_list[1:])
|
|
75
|
+
# mutate
|
|
76
|
+
prog = arg_list[0]
|
|
77
|
+
arg_list[:] = [prog] + remaining
|
|
78
|
+
return namespace
|
pyxcp/vector/__init__.py
ADDED
|
File without changes
|
pyxcp/vector/map.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
MAP_NAMES = {
|
|
4
|
+
1: "BorlandC 16 Bit",
|
|
5
|
+
2: "M166",
|
|
6
|
+
3: "Watcom",
|
|
7
|
+
4: "HiTech HC05",
|
|
8
|
+
6: "IEEE",
|
|
9
|
+
7: "Cosmic",
|
|
10
|
+
8: "SDS",
|
|
11
|
+
9: "Fujitsu Softune 1(.mp1)",
|
|
12
|
+
10: "GNU",
|
|
13
|
+
11: "Keil 16x",
|
|
14
|
+
12: "BorlandC 32 Bit",
|
|
15
|
+
13: "Keil 16x (static)",
|
|
16
|
+
14: "Keil 8051",
|
|
17
|
+
15: "ISI",
|
|
18
|
+
16: "Hiware HC12",
|
|
19
|
+
17: "TI TMS470",
|
|
20
|
+
18: "Archimedes",
|
|
21
|
+
19: "COFF",
|
|
22
|
+
20: "IAR",
|
|
23
|
+
21: "VisualDSP",
|
|
24
|
+
22: "GNU 16x",
|
|
25
|
+
23: "GNU VxWorks",
|
|
26
|
+
24: "GNU 68k",
|
|
27
|
+
25: "DiabData",
|
|
28
|
+
26: "VisualDSP DOS",
|
|
29
|
+
27: "HEW SH7055",
|
|
30
|
+
28: "Metrowerks",
|
|
31
|
+
29: "Microsoft standard",
|
|
32
|
+
30: "ELF/DWARF 16 Bit",
|
|
33
|
+
31: "ELF/DWARF 32 Bit",
|
|
34
|
+
32: "Fujitsu Softune 3..8(.mps)",
|
|
35
|
+
33: "Microware Hawk",
|
|
36
|
+
34: "TI C6711",
|
|
37
|
+
35: "Hitachi H8S",
|
|
38
|
+
36: "IAR HC12",
|
|
39
|
+
37: "Greenhill Multi 2000",
|
|
40
|
+
38: "LN308(MITSUBISHI) for M16C/80",
|
|
41
|
+
39: "COFF settings auto detected",
|
|
42
|
+
40: "NEC CC78K/0 v35",
|
|
43
|
+
41: "Microsoft extended",
|
|
44
|
+
42: "ICCAVR",
|
|
45
|
+
43: "Omf96 (.m96)",
|
|
46
|
+
44: "COFF/DWARF",
|
|
47
|
+
45: "OMF96 Binary (Tasking C196)",
|
|
48
|
+
46: "OMF166 Binary (Keil C166)",
|
|
49
|
+
47: "Microware Hawk Plug&Play ASCII",
|
|
50
|
+
48: "UBROF Binary (IAR)",
|
|
51
|
+
49: "Renesas M32R/M32192 ASCII",
|
|
52
|
+
50: "OMF251 Binary (Keil C251)",
|
|
53
|
+
51: "Microsoft standard VC8",
|
|
54
|
+
52: "Microsoft VC8 Release Build (MATLAB DLL)",
|
|
55
|
+
53: "Microsoft VC8 Debug Build (MATLAB DLL)",
|
|
56
|
+
54: "Microsoft VC8 Debug file (pdb)",
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
3.0 Automatic detection sequence
|
|
61
|
+
|
|
62
|
+
- The master (CANape) sends the command GET_ID with the idType = 219 (0xDB hex) to the ECU
|
|
63
|
+
- The ECU sets the MTA (memory transfer address) pointer to the first byte of the data block containing the
|
|
64
|
+
MAP file identification and returns the number of bytes which need to be uploaded to the master as well as
|
|
65
|
+
the counter which defines the appropriate memory segment
|
|
66
|
+
- The master requests the specified number of bytes from the ECU by sending UPLOAD commands
|
|
67
|
+
- The master looks for the appropriate MAP file in the MAP file directory and updates the addresses in the
|
|
68
|
+
a2l file accordingly
|
|
69
|
+
|
|
70
|
+
Command sequence GET_ID
|
|
71
|
+
|
|
72
|
+
Id of the MAP format
|
|
73
|
+
|
|
74
|
+
Counter
|
|
75
|
+
|
|
76
|
+
MAP name
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def mapfile_name(name, counter, fmt):
|
|
82
|
+
return f"{fmt:2d}{counter:d}{name:s}.map"
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyxcp
|
|
3
|
+
Version: 0.25.4
|
|
4
|
+
Summary: Universal Calibration Protocol for Python
|
|
5
|
+
License: LGPLv3
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: automotive,ecu,xcp,asam,autosar
|
|
8
|
+
Author: Christoph Schueler
|
|
9
|
+
Author-email: cpu.gems@googlemail.com
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
|
|
14
|
+
Classifier: License :: Other/Proprietary License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Requires-Dist: bandit (>=1.7.8,<2.0.0)
|
|
24
|
+
Requires-Dist: chardet (>=5.2.0,<6.0.0)
|
|
25
|
+
Requires-Dist: construct (>=2.10.68,<3.0.0)
|
|
26
|
+
Requires-Dist: line-profiler-pycharm (>=1.1.0,<2.0.0)
|
|
27
|
+
Requires-Dist: mako (>=1.2.4,<2.0.0)
|
|
28
|
+
Requires-Dist: pydantic (>=2.5,<3)
|
|
29
|
+
Requires-Dist: pyserial (>=3.5,<4.0)
|
|
30
|
+
Requires-Dist: python-can (>=4.2.2,<5.0.0)
|
|
31
|
+
Requires-Dist: pytz (>=2025.2,<2026.0)
|
|
32
|
+
Requires-Dist: pyusb (>=1.2.1,<2.0.0)
|
|
33
|
+
Requires-Dist: rich (>=14.0.0,<15.0.0)
|
|
34
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
35
|
+
Requires-Dist: tomlkit (>=0.13.3,<0.14.0)
|
|
36
|
+
Requires-Dist: traitlets (<=5.11.2)
|
|
37
|
+
Requires-Dist: uptime (>=3.0.1,<4.0.0)
|
|
38
|
+
Project-URL: Homepage, https://github.com/christoph2/pyxcp
|
|
39
|
+
Description-Content-Type: text/x-rst
|
|
40
|
+
|
|
41
|
+
Readme
|
|
42
|
+
======
|
|
43
|
+
|
|
44
|
+
.. image:: pyxcp_social.svg
|
|
45
|
+
:align: center
|
|
46
|
+
|
|
47
|
+
Reliable Python tooling for the ASAM MCD-1 XCP protocol (measurement,
|
|
48
|
+
calibration, flashing) with multiple transports (CAN, Ethernet, USB,
|
|
49
|
+
Serial) and handy CLI utilities.
|
|
50
|
+
|
|
51
|
+
|PyPI| |Python Versions| |License: LGPL v3+| |Code style: black|
|
|
52
|
+
|
|
53
|
+
``pyXCP`` is a production-ready Python library for communicating with
|
|
54
|
+
XCP-enabled devices, most commonly automotive ECUs. Use it to take
|
|
55
|
+
measurements, adjust parameters (calibration), stream DAQ/STIM, and
|
|
56
|
+
program devices during development.
|
|
57
|
+
|
|
58
|
+
Highlights:
|
|
59
|
+
|
|
60
|
+
- Transports: Ethernet (TCP/IP), CAN, USB, Serial (SxI)
|
|
61
|
+
- Cross-platform: Windows, Linux, macOS
|
|
62
|
+
- Rich CLI tools for common XCP tasks
|
|
63
|
+
- Extensible architecture and layered design
|
|
64
|
+
|
|
65
|
+
--------------
|
|
66
|
+
|
|
67
|
+
Installation
|
|
68
|
+
------------
|
|
69
|
+
|
|
70
|
+
The easiest way is from PyPI:
|
|
71
|
+
|
|
72
|
+
.. code:: shell
|
|
73
|
+
|
|
74
|
+
pip install pyxcp
|
|
75
|
+
|
|
76
|
+
To install from the main branch:
|
|
77
|
+
|
|
78
|
+
.. code:: shell
|
|
79
|
+
|
|
80
|
+
pip install git+https://github.com/christoph2/pyxcp.git
|
|
81
|
+
|
|
82
|
+
Requirements
|
|
83
|
+
~~~~~~~~~~~~
|
|
84
|
+
|
|
85
|
+
- Python >= 3.10
|
|
86
|
+
- Building from source requires a working C/C++ toolchain (native
|
|
87
|
+
extensions are used for performance). Wheels are provided for common
|
|
88
|
+
platforms and Python versions; if a wheel is not available, pip will
|
|
89
|
+
build from source.
|
|
90
|
+
- An XCP slave device (or simulator)
|
|
91
|
+
|
|
92
|
+
Quick start
|
|
93
|
+
-----------
|
|
94
|
+
|
|
95
|
+
The tutorial walks you through typical tasks end-to-end: see `tutorial <tutorial.rst>`_.
|
|
96
|
+
|
|
97
|
+
Minimal example using the built-in argument parser and context manager:
|
|
98
|
+
|
|
99
|
+
.. code:: python
|
|
100
|
+
|
|
101
|
+
from pyxcp.cmdline import ArgumentParser
|
|
102
|
+
|
|
103
|
+
ap = ArgumentParser(description="pyXCP hello world")
|
|
104
|
+
|
|
105
|
+
with ap.run() as x:
|
|
106
|
+
x.connect()
|
|
107
|
+
identifier = x.identifier(0x01)
|
|
108
|
+
print(f"ID: {identifier!r}")
|
|
109
|
+
print(x.slaveProperties)
|
|
110
|
+
x.disconnect()
|
|
111
|
+
|
|
112
|
+
Configuration
|
|
113
|
+
~~~~~~~~~~~~~
|
|
114
|
+
|
|
115
|
+
``pyXCP`` supports a
|
|
116
|
+
`traitlets <https://github.com/ipython/traitlets>`__\-based configuration system.
|
|
117
|
+
|
|
118
|
+
- Recommended Python config example and generator: `tutorial <tutorial.rst>`__ and `configuration <configuration.rst>`__
|
|
119
|
+
- Legacy TOML examples remain available for compatibility.
|
|
120
|
+
|
|
121
|
+
Command‑line tools
|
|
122
|
+
~~~~~~~~~~~~~~~~~~
|
|
123
|
+
|
|
124
|
+
Installed entry points (see pyproject.toml):
|
|
125
|
+
|
|
126
|
+
- xcp-info — print capabilities and properties
|
|
127
|
+
- xcp-id-scanner — scan for slave identifiers
|
|
128
|
+
- xcp-fetch-a2l — retrieve A2L from target (if supported)
|
|
129
|
+
- xcp-profile — generate/convert config files
|
|
130
|
+
- xcp-examples — launch assorted demos/examples
|
|
131
|
+
- xmraw-converter — convert recorder .xmraw data
|
|
132
|
+
- pyxcp-probe-can-drivers — list available CAN interfaces
|
|
133
|
+
|
|
134
|
+
Run any tool with -h for options.
|
|
135
|
+
|
|
136
|
+
Features
|
|
137
|
+
--------
|
|
138
|
+
|
|
139
|
+
- Multiple transport layers: Ethernet (TCP), CAN, USB, SxI (serial/UART)
|
|
140
|
+
- Data Acquisition (DAQ) and Stimulation (STIM)
|
|
141
|
+
- Calibration (read/write parameters)
|
|
142
|
+
- Flashing/programming workflows
|
|
143
|
+
- A2L (ASAM MCD‑2 MC) support
|
|
144
|
+
- Recorder utilities and converters (see `recorder <recorder.rst>`__)
|
|
145
|
+
- Extensible architecture for custom transports
|
|
146
|
+
|
|
147
|
+
Documentation
|
|
148
|
+
-------------
|
|
149
|
+
|
|
150
|
+
- Getting started tutorial: `tutorial <tutorial.rst>`__
|
|
151
|
+
- Configuration: `configuration <configuration.rst>`__
|
|
152
|
+
- CAN driver setup and troubleshooting: `howto_can_driver <howto_can_driver.rst>`__
|
|
153
|
+
- Recorder: `recorder <recorder.rst>`__
|
|
154
|
+
- Troubleshooting: `troubleshooting <troubleshooting.rst>`__
|
|
155
|
+
- Troubleshooting matrix (common errors, root causes, fixes):
|
|
156
|
+
`troubleshooting_matrix <troubleshooting_matrix.rst>`__
|
|
157
|
+
|
|
158
|
+
To build the Sphinx documentation locally:
|
|
159
|
+
|
|
160
|
+
1. Install doc requirements:
|
|
161
|
+
``pip install -r docs/requirements.txt``
|
|
162
|
+
2. Build:
|
|
163
|
+
``sphinx-build -b html docs docs/_build/html``
|
|
164
|
+
3. Open
|
|
165
|
+
``docs/_build/html/index.html``
|
|
166
|
+
|
|
167
|
+
Compatibility
|
|
168
|
+
-------------
|
|
169
|
+
|
|
170
|
+
- Operating systems: Windows, Linux, macOS
|
|
171
|
+
- Python: 3.10 - 3.14, CPython wheels where available
|
|
172
|
+
- CAN backends: python-can compatible drivers (see `howto_can_driver <howto_can_driver.rst>`__)
|
|
173
|
+
|
|
174
|
+
Contributing
|
|
175
|
+
------------
|
|
176
|
+
|
|
177
|
+
Contributions are welcome! Please: - Read `CODE_OF_CONDUCT <../CODE_OF_CONDUCT.md>`__ - Open an
|
|
178
|
+
issue or discussion before large changes - Use
|
|
179
|
+
`pre-commit <https://github.com/pre-commit/pre-commit>`__ to run linters
|
|
180
|
+
and tests locally
|
|
181
|
+
|
|
182
|
+
License
|
|
183
|
+
-------
|
|
184
|
+
|
|
185
|
+
GNU Lesser General Public License v3 or later (LGPLv3+). See LICENSE for
|
|
186
|
+
details.
|
|
187
|
+
|
|
188
|
+
References
|
|
189
|
+
----------
|
|
190
|
+
|
|
191
|
+
- ASAM MCD‑1 XCP standard:
|
|
192
|
+
https://www.asam.net/standards/detail/mcd-1-xcp/
|
|
193
|
+
|
|
194
|
+
About ASAM MCD‑1 XCP
|
|
195
|
+
--------------------
|
|
196
|
+
|
|
197
|
+
XCP (Universal Measurement and Calibration Protocol) is an ASAM standard
|
|
198
|
+
defining a vendor‑neutral protocol to access internal data of electronic
|
|
199
|
+
control units (ECUs) for measurement, calibration (parameter tuning),
|
|
200
|
+
and programming. XCP decouples the protocol from the physical transport,
|
|
201
|
+
so the same command set can be carried over different buses such as CAN,
|
|
202
|
+
FlexRay, Ethernet, USB, or Serial.
|
|
203
|
+
|
|
204
|
+
- Roles: An XCP Master (this library) communicates with an XCP Slave
|
|
205
|
+
(your device/ECU or simulator).
|
|
206
|
+
- Layered concept: XCP defines an application layer and transport
|
|
207
|
+
layers. ``pyXCP`` implements the application layer and multiple transport
|
|
208
|
+
bindings.
|
|
209
|
+
- Use cases:
|
|
210
|
+
|
|
211
|
+
- Measurement: Read variables from the ECU in real‑time, including
|
|
212
|
+
high‑rate DAQ streaming.
|
|
213
|
+
- Calibration: Read/write parameters (calibration data) in RAM/flash.
|
|
214
|
+
- Programming: Download new program/data to flash (where the slave
|
|
215
|
+
supports it).
|
|
216
|
+
|
|
217
|
+
For the authoritative description, see the ASAM page:
|
|
218
|
+
https://www.asam.net/standards/detail/mcd-1-xcp/
|
|
219
|
+
|
|
220
|
+
XCP in a nutshell
|
|
221
|
+
-----------------
|
|
222
|
+
|
|
223
|
+
- Connect/Session: The master establishes a connection, negotiates
|
|
224
|
+
capabilities/features, and optionally unlocks protected functions via
|
|
225
|
+
seed & key.
|
|
226
|
+
- Addressing: Memory is accessed via absolute or segment‑relative
|
|
227
|
+
addresses. Addressing modes are described in the associated A2L file
|
|
228
|
+
(ASAM MCD‑2 MC), which maps symbolic names to addresses, data types,
|
|
229
|
+
and conversion rules.
|
|
230
|
+
- Events: The slave exposes events (e.g., “1 ms task”, “Combustion
|
|
231
|
+
cycle”), which trigger DAQ sampling. The master assigns signals (ODTs)
|
|
232
|
+
to these events for time‑aligned acquisition.
|
|
233
|
+
- DAQ/STIM: DAQ = Data Acquisition (slave → master), STIM = Stimulation
|
|
234
|
+
(master → slave). Both use event‑driven lists for deterministic
|
|
235
|
+
timing.
|
|
236
|
+
- Timestamps: DAQ may carry timestamps from the slave for precise time
|
|
237
|
+
correlation.
|
|
238
|
+
- Security: Access to sensitive commands (e.g., programming,
|
|
239
|
+
calibration) can be protected by a seed & key algorithm negotiated at
|
|
240
|
+
runtime.
|
|
241
|
+
- Checksums: XCP defines checksum services useful for verifying memory
|
|
242
|
+
regions (e.g., after flashing).
|
|
243
|
+
|
|
244
|
+
Relation to A2L (ASAM MCD‑2 MC)
|
|
245
|
+
-------------------------------
|
|
246
|
+
|
|
247
|
+
While XCP defines the protocol, the A2L file describes the measurement
|
|
248
|
+
and calibration objects (characteristics, measurements), data types,
|
|
249
|
+
conversion rules, and memory layout. In practice, you use ``pyXCP`` together
|
|
250
|
+
with an A2L to: - Resolve symbolic names to addresses and data types. -
|
|
251
|
+
Configure DAQ lists from human‑readable signal names. - Interpret raw
|
|
252
|
+
values using the appropriate conversion methods.
|
|
253
|
+
|
|
254
|
+
``pyXCP`` provides utilities to fetch A2L data when supported by the slave
|
|
255
|
+
and to work with A2L‑described objects. See also
|
|
256
|
+
`pya2ldb <https://github.com/christoph2/pya2l>`__!
|
|
257
|
+
|
|
258
|
+
Transports and addressing
|
|
259
|
+
-------------------------
|
|
260
|
+
|
|
261
|
+
XCP is transport‑agnostic. ``pyXCP`` supports multiple transports and
|
|
262
|
+
addressing schemes: - CAN (XCP on CAN): Robust and ubiquitous in
|
|
263
|
+
vehicles; limited payload and bandwidth; suited for many calibration
|
|
264
|
+
tasks and moderate DAQ rates. - Ethernet (XCP on TCP/UDP): High
|
|
265
|
+
bandwidth with low latency; well suited for rich DAQ and programming
|
|
266
|
+
workflows. - USB: High throughput for lab setups; requires device
|
|
267
|
+
support. - Serial/SxI: Simple point‑to‑point links for embedded targets
|
|
268
|
+
and simulators.
|
|
269
|
+
|
|
270
|
+
The exact capabilities (e.g., max CTO/DTO, checksum types, timestamping)
|
|
271
|
+
are negotiated at connect time and depend on the slave and transport.
|
|
272
|
+
|
|
273
|
+
Supported features (overview)
|
|
274
|
+
-----------------------------
|
|
275
|
+
|
|
276
|
+
The scope of features depends on the connected slave. At the library
|
|
277
|
+
level, ``pyXCP`` provides: - Session management: CONNECT/DISCONNECT,
|
|
278
|
+
GET_STATUS/SLAVE_PROPERTIES, communication mode setup, error handling. -
|
|
279
|
+
Memory access: Upload/short upload, Download/Download Next,
|
|
280
|
+
verifications, optional paged memory where supported. - DAQ/STIM:
|
|
281
|
+
Configuration of DAQ lists/ODTs, event assignment, data streaming,
|
|
282
|
+
timestamp handling when available. - Programming helpers: Building
|
|
283
|
+
blocks for program/erase/write flows (exact sequence per slave’s flash
|
|
284
|
+
algorithm and A2L description). - Security/Seed & Key: Pluggable
|
|
285
|
+
seed‑to‑key resolution including 32↔64‑bit bridge on Windows. -
|
|
286
|
+
Utilities: Identifier scanning, A2L helpers, recorder and converters.
|
|
287
|
+
|
|
288
|
+
Refer to `tutorial <tutorial.rst>`__ and `configuration <configuration.rst>`__ for feature usage,
|
|
289
|
+
and xcp-info for a capability dump of your target.
|
|
290
|
+
|
|
291
|
+
Compliance and versions
|
|
292
|
+
-----------------------
|
|
293
|
+
|
|
294
|
+
``pyXCP`` aims to be compatible with commonly used parts of ASAM MCD‑1 XCP.
|
|
295
|
+
Specific optional features are enabled when a slave advertises them
|
|
296
|
+
during CONNECT. Because implementations vary across vendors and ECU
|
|
297
|
+
projects, always consult your A2L and use xcp-info to confirm negotiated
|
|
298
|
+
options (e.g., checksum type, timestamp unit, max DTO size, address
|
|
299
|
+
granularity).
|
|
300
|
+
|
|
301
|
+
If you rely on a particular XCP feature/profile not mentioned here,
|
|
302
|
+
please open an issue with details about your slave and A2L so we can
|
|
303
|
+
clarify support and—if feasible—add coverage.
|
|
304
|
+
|
|
305
|
+
Safety, performance, and limitations
|
|
306
|
+
------------------------------------
|
|
307
|
+
|
|
308
|
+
- Safety‑critical systems: XCP is a development and testing protocol. Do
|
|
309
|
+
not enable measurement/calibration on safety‑critical systems in the
|
|
310
|
+
field unless your system‑level safety case covers it.
|
|
311
|
+
- Performance: Achievable DAQ rates depend on transport bandwidth, ECU
|
|
312
|
+
event rates, DTO sizes, and host processing. Ethernet typically yields
|
|
313
|
+
the highest throughput.
|
|
314
|
+
- Latency/jitter: Event scheduling in the slave and OS scheduling on the
|
|
315
|
+
host can affect determinism. Use timestamps to correlate data
|
|
316
|
+
precisely.
|
|
317
|
+
- Access control: Seed & key protects sensitive functions; your
|
|
318
|
+
organization’s policy should govern algorithm distribution and access.
|
|
319
|
+
|
|
320
|
+
Further resources
|
|
321
|
+
-----------------
|
|
322
|
+
|
|
323
|
+
- ASAM MCD‑1 XCP standard (overview and membership):
|
|
324
|
+
https://www.asam.net/standards/detail/mcd-1-xcp/
|
|
325
|
+
- ASAM MCD‑2 MC (A2L) for object descriptions:
|
|
326
|
+
https://www.asam.net/standards/detail/mcd-2-mc/
|
|
327
|
+
- Introduction to DAQ/STIM concepts (ASAM publications and vendor docs)
|
|
328
|
+
- Related: CCP (legacy predecessor to XCP), ASAM MDF for measurement
|
|
329
|
+
data storage
|
|
330
|
+
|
|
331
|
+
.. |CI| image:: https://github.com/christoph2/pyxcp/workflows/Python%20application/badge.svg
|
|
332
|
+
:target: https://github.com/christoph2/pyxcp/actions
|
|
333
|
+
.. |PyPI| image:: https://img.shields.io/pypi/v/pyxcp.svg
|
|
334
|
+
:target: https://pypi.org/project/pyxcp/
|
|
335
|
+
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pyxcp.svg
|
|
336
|
+
:target: https://pypi.org/project/pyxcp/
|
|
337
|
+
.. |License: LGPL v3+| image:: https://img.shields.io/badge/License-LGPL%20v3%2B-blue.svg
|
|
338
|
+
:target: https://www.gnu.org/licenses/lgpl-3.0
|
|
339
|
+
.. |Code style: black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
|
340
|
+
:target: https://github.com/psf/black
|
|
341
|
+
|