pyxcp 0.21.10__cp38-cp38-win_amd64.whl → 0.22.23__cp38-cp38-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.
Potentially problematic release.
This version of pyxcp might be problematic. Click here for more details.
- pyxcp/__init__.py +12 -20
- pyxcp/aml/EtasCANMonitoring.a2l +82 -83
- pyxcp/aml/XCP_Common.aml +0 -1
- pyxcp/aml/XCPonUSB.aml +1 -1
- pyxcp/aml/ifdata_CAN.a2l +0 -1
- pyxcp/aml/ifdata_Eth.a2l +0 -1
- pyxcp/aml/ifdata_Flx.a2l +0 -1
- pyxcp/aml/ifdata_SxI.a2l +0 -1
- pyxcp/aml/ifdata_USB.a2l +0 -1
- pyxcp/asam/types.py +4 -4
- pyxcp/asamkeydll.c +0 -1
- pyxcp/checksum.py +0 -1
- pyxcp/cmdline.py +32 -50
- pyxcp/config/__init__.py +1100 -0
- pyxcp/config/legacy.py +120 -0
- pyxcp/constants.py +12 -13
- pyxcp/cpp_ext/__init__.py +0 -0
- pyxcp/cpp_ext/bin.hpp +104 -0
- pyxcp/cpp_ext/blockmem.hpp +58 -0
- pyxcp/cpp_ext/cpp_ext.cp38-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/daqlist.hpp +200 -0
- pyxcp/cpp_ext/event.hpp +67 -0
- pyxcp/cpp_ext/extension_wrapper.cpp +96 -0
- pyxcp/cpp_ext/helper.hpp +280 -0
- pyxcp/cpp_ext/mcobject.hpp +246 -0
- pyxcp/cpp_ext/tsqueue.hpp +46 -0
- pyxcp/daq_stim/__init__.py +228 -0
- pyxcp/daq_stim/optimize/__init__.py +67 -0
- pyxcp/daq_stim/optimize/binpacking.py +41 -0
- pyxcp/daq_stim/scheduler.cpp +28 -0
- pyxcp/daq_stim/scheduler.hpp +75 -0
- pyxcp/daq_stim/stim.cp38-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 +48 -0
- pyxcp/dllif.py +21 -18
- pyxcp/errormatrix.py +5 -3
- pyxcp/examples/conf_can.toml +4 -2
- pyxcp/examples/conf_can_vector.json +9 -9
- pyxcp/examples/conf_can_vector.toml +4 -2
- pyxcp/examples/conf_eth.toml +5 -2
- pyxcp/examples/conf_nixnet.json +18 -18
- pyxcp/examples/conf_sxi.json +7 -7
- pyxcp/examples/ex_arrow.py +109 -0
- pyxcp/examples/ex_csv.py +85 -0
- pyxcp/examples/ex_excel.py +95 -0
- pyxcp/examples/ex_mdf.py +124 -0
- pyxcp/examples/ex_sqlite.py +128 -0
- pyxcp/examples/run_daq.py +148 -0
- pyxcp/examples/xcp_policy.py +6 -7
- pyxcp/examples/xcp_read_benchmark.py +8 -6
- pyxcp/examples/xcp_skel.py +0 -2
- pyxcp/examples/xcp_unlock.py +1 -1
- pyxcp/examples/xcp_user_supplied_driver.py +1 -2
- pyxcp/examples/xcphello.py +6 -3
- pyxcp/examples/xcphello_recorder.py +4 -4
- pyxcp/master/__init__.py +1 -2
- pyxcp/master/errorhandler.py +107 -74
- pyxcp/master/master.py +201 -119
- pyxcp/py.typed +0 -0
- pyxcp/recorder/__init__.py +27 -6
- pyxcp/recorder/converter/__init__.py +37 -0
- pyxcp/recorder/lz4.c +129 -51
- pyxcp/recorder/lz4.h +45 -28
- pyxcp/recorder/lz4hc.c +560 -156
- pyxcp/recorder/lz4hc.h +1 -1
- pyxcp/recorder/mio.hpp +721 -767
- pyxcp/recorder/reader.hpp +139 -0
- pyxcp/recorder/reco.py +5 -8
- pyxcp/recorder/rekorder.cp38-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cpp +18 -22
- pyxcp/recorder/rekorder.hpp +200 -587
- pyxcp/recorder/setup.py +11 -10
- pyxcp/recorder/test_reko.py +2 -3
- pyxcp/recorder/unfolder.hpp +1332 -0
- pyxcp/recorder/wrap.cpp +171 -9
- pyxcp/recorder/writer.hpp +302 -0
- pyxcp/scripts/pyxcp_probe_can_drivers.py +0 -2
- pyxcp/scripts/xcp_examples.py +64 -0
- pyxcp/scripts/xcp_fetch_a2l.py +15 -10
- pyxcp/scripts/xcp_id_scanner.py +2 -6
- pyxcp/scripts/xcp_info.py +101 -63
- pyxcp/scripts/xcp_profile.py +27 -0
- pyxcp/stim/__init__.py +0 -0
- pyxcp/tests/test_asam_types.py +2 -2
- pyxcp/tests/test_binpacking.py +186 -0
- pyxcp/tests/test_can.py +1132 -38
- pyxcp/tests/test_checksum.py +2 -1
- pyxcp/tests/test_daq.py +193 -0
- pyxcp/tests/test_frame_padding.py +6 -3
- pyxcp/tests/test_master.py +42 -31
- pyxcp/tests/test_transport.py +12 -12
- pyxcp/tests/test_utils.py +2 -5
- pyxcp/timing.py +0 -2
- pyxcp/transport/__init__.py +9 -9
- pyxcp/transport/base.py +149 -127
- pyxcp/transport/base_transport.hpp +0 -0
- pyxcp/transport/can.py +194 -167
- pyxcp/transport/eth.py +80 -82
- pyxcp/transport/sxi.py +106 -60
- pyxcp/transport/transport_wrapper.cpp +0 -0
- pyxcp/transport/usb_transport.py +65 -83
- pyxcp/types.py +69 -20
- pyxcp/utils.py +47 -16
- pyxcp/vector/map.py +1 -3
- {pyxcp-0.21.10.dist-info → pyxcp-0.22.23.dist-info}/METADATA +27 -22
- pyxcp-0.22.23.dist-info/RECORD +128 -0
- {pyxcp-0.21.10.dist-info → pyxcp-0.22.23.dist-info}/WHEEL +1 -1
- {pyxcp-0.21.10.dist-info → pyxcp-0.22.23.dist-info}/entry_points.txt +2 -0
- pyxcp/config.py +0 -57
- pyxcp/cxx/asynchiofactory.hpp +0 -24
- pyxcp/cxx/blocking_client.cpp +0 -44
- pyxcp/cxx/blocking_socket.cpp +0 -43
- pyxcp/cxx/blocking_socket.hpp +0 -558
- pyxcp/cxx/concurrent_queue.hpp +0 -60
- pyxcp/cxx/eth.hpp +0 -57
- pyxcp/cxx/exceptions.hpp +0 -30
- pyxcp/cxx/iasyncioservice.hpp +0 -31
- pyxcp/cxx/iresource.hpp +0 -17
- pyxcp/cxx/isocket.hpp +0 -22
- pyxcp/cxx/linux/epoll.cpp +0 -51
- pyxcp/cxx/linux/epoll.hpp +0 -87
- pyxcp/cxx/linux/lit_tester.cpp +0 -19
- pyxcp/cxx/linux/socket.hpp +0 -234
- pyxcp/cxx/linux/timeout.hpp +0 -81
- pyxcp/cxx/memoryblock.hpp +0 -42
- pyxcp/cxx/pool.hpp +0 -81
- pyxcp/cxx/poolmgr.cpp +0 -6
- pyxcp/cxx/poolmgr.hpp +0 -31
- pyxcp/cxx/test_queue.cpp +0 -69
- pyxcp/cxx/timestamp.hpp +0 -84
- pyxcp/cxx/utils.cpp +0 -38
- pyxcp/cxx/utils.hpp +0 -29
- pyxcp/cxx/win/iocp.cpp +0 -242
- pyxcp/cxx/win/iocp.hpp +0 -42
- pyxcp/cxx/win/perhandledata.hpp +0 -24
- pyxcp/cxx/win/periodata.hpp +0 -97
- pyxcp/cxx/win/socket.hpp +0 -185
- pyxcp/cxx/win/timeout.hpp +0 -83
- pyxcp/examples/conf_can.json +0 -20
- pyxcp/examples/conf_eth.json +0 -8
- pyxcp/logger.py +0 -67
- pyxcp/tests/test_config.py +0 -62
- pyxcp/transport/candriver/__init__.py +0 -2
- pyxcp/transport/candriver/pc_canalystii.py +0 -27
- pyxcp/transport/candriver/pc_etas.py +0 -25
- pyxcp/transport/candriver/pc_gsusb.py +0 -23
- pyxcp/transport/candriver/pc_iscan.py +0 -23
- pyxcp/transport/candriver/pc_ixxat.py +0 -27
- pyxcp/transport/candriver/pc_kvaser.py +0 -39
- pyxcp/transport/candriver/pc_neovi.py +0 -31
- pyxcp/transport/candriver/pc_nican.py +0 -23
- pyxcp/transport/candriver/pc_nixnet.py +0 -23
- pyxcp/transport/candriver/pc_pcan.py +0 -25
- pyxcp/transport/candriver/pc_seeed.py +0 -28
- pyxcp/transport/candriver/pc_serial.py +0 -27
- pyxcp/transport/candriver/pc_slcan.py +0 -29
- pyxcp/transport/candriver/pc_socketcan.py +0 -23
- pyxcp/transport/candriver/pc_systec.py +0 -29
- pyxcp/transport/candriver/pc_usb2can.py +0 -30
- pyxcp/transport/candriver/pc_vector.py +0 -34
- pyxcp/transport/candriver/python_can.py +0 -101
- pyxcp/transport/cxx_ext/CMakeLists.txt +0 -51
- pyxcp/transport/cxx_ext/setup.py +0 -49
- pyxcp/transport/cxx_ext/tests/test_basic_socket.cpp +0 -39
- pyxcp/transport/cxx_ext/tests/test_pool.cpp +0 -39
- pyxcp/transport/cxx_ext/tests/test_timestamp.cpp +0 -27
- pyxcp-0.21.10.dist-info/RECORD +0 -147
- rekorder.cp38-win_amd64.pyd +0 -0
- {pyxcp-0.21.10.dist-info/licenses → pyxcp-0.22.23.dist-info}/LICENSE +0 -0
pyxcp/transport/usb_transport.py
CHANGED
|
@@ -1,55 +1,57 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
2
|
import struct
|
|
4
3
|
import threading
|
|
5
4
|
from array import array
|
|
6
5
|
from collections import deque
|
|
7
|
-
from
|
|
8
|
-
from time import sleep
|
|
9
|
-
from time import time
|
|
6
|
+
from typing import Optional
|
|
10
7
|
|
|
11
|
-
import usb.backend.libusb1 as libusb1
|
|
12
8
|
import usb.backend.libusb0 as libusb0
|
|
9
|
+
import usb.backend.libusb1 as libusb1
|
|
13
10
|
import usb.backend.openusb as openusb
|
|
14
11
|
import usb.core
|
|
15
12
|
import usb.util
|
|
13
|
+
from usb.core import USBError, USBTimeoutError
|
|
16
14
|
|
|
17
15
|
from pyxcp.transport.base import BaseTransport
|
|
18
|
-
from pyxcp.utils import
|
|
16
|
+
from pyxcp.utils import short_sleep
|
|
17
|
+
|
|
19
18
|
|
|
20
19
|
RECV_SIZE = 16384
|
|
20
|
+
FIVE_MS = 5_000_000 # Five milliseconds in nanoseconds.
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class Usb(BaseTransport):
|
|
24
24
|
""""""
|
|
25
25
|
|
|
26
|
-
PARAMETER_MAP = {
|
|
27
|
-
# Type Req'd Default
|
|
28
|
-
"serial_number": (str, True, ""),
|
|
29
|
-
"configuration_number": (int, True, 1),
|
|
30
|
-
"interface_number": (int, True, 2),
|
|
31
|
-
"command_endpoint_number": (int, True, 0),
|
|
32
|
-
"reply_endpoint_number": (int, True, 1),
|
|
33
|
-
"vendor_id": (int, False, 0),
|
|
34
|
-
"product_id": (int, False, 0),
|
|
35
|
-
"library": (str, False, "") # absolute path to USB shared library
|
|
36
|
-
}
|
|
37
26
|
HEADER = struct.Struct("<2H")
|
|
38
27
|
HEADER_SIZE = HEADER.size
|
|
39
28
|
|
|
40
|
-
def __init__(self, config=None, policy=None):
|
|
41
|
-
super(
|
|
42
|
-
self.
|
|
43
|
-
self.serial_number = self.config.
|
|
44
|
-
self.vendor_id = self.config.
|
|
45
|
-
self.product_id = self.config.
|
|
46
|
-
self.configuration_number = self.config.
|
|
47
|
-
self.interface_number = self.config.
|
|
48
|
-
self.
|
|
49
|
-
self.
|
|
29
|
+
def __init__(self, config=None, policy=None, transport_layer_interface: Optional[usb.core.Device] = None):
|
|
30
|
+
super().__init__(config, policy, transport_layer_interface)
|
|
31
|
+
self.load_config(config)
|
|
32
|
+
self.serial_number: str = self.config.serial_number
|
|
33
|
+
self.vendor_id: int = self.config.vendor_id
|
|
34
|
+
self.product_id: int = self.config.product_id
|
|
35
|
+
self.configuration_number: int = self.config.configuration_number
|
|
36
|
+
self.interface_number: int = self.config.interface_number
|
|
37
|
+
self.library: str = self.config.library
|
|
38
|
+
self.header_format: str = self.config.header_format
|
|
50
39
|
self.library = self.config.get("library")
|
|
51
40
|
self.device = None
|
|
52
41
|
|
|
42
|
+
## IN-EP (RES/ERR, DAQ, and EV/SERV) Parameters.
|
|
43
|
+
self.in_ep_number: int = self.config.in_ep_number
|
|
44
|
+
self.in_ep_transfer_type = self.config.in_ep_transfer_type
|
|
45
|
+
self.in_ep_max_packet_size: int = self.config.in_ep_max_packet_size
|
|
46
|
+
self.in_ep_polling_interval: int = self.config.in_ep_polling_interval
|
|
47
|
+
self.in_ep_message_packing = self.config.in_ep_message_packing
|
|
48
|
+
self.in_ep_alignment = self.config.in_ep_alignment
|
|
49
|
+
self.in_ep_recommended_host_bufsize: int = self.config.in_ep_recommended_host_bufsize
|
|
50
|
+
|
|
51
|
+
## OUT-EP (CMD and STIM) Parameters.
|
|
52
|
+
self.out_ep_number: int = self.config.out_ep_number
|
|
53
|
+
|
|
54
|
+
self.device: Optional[usb.core.Device] = None
|
|
53
55
|
self.status = 0
|
|
54
56
|
|
|
55
57
|
self._packet_listener = threading.Thread(
|
|
@@ -86,10 +88,10 @@ class Usb(BaseTransport):
|
|
|
86
88
|
if device.serial_number.strip().strip("\0").lower() == self.serial_number.lower():
|
|
87
89
|
self.device = device
|
|
88
90
|
break
|
|
89
|
-
except
|
|
91
|
+
except (USBError, USBTimeoutError):
|
|
90
92
|
continue
|
|
91
93
|
else:
|
|
92
|
-
raise Exception("
|
|
94
|
+
raise Exception(f"XCPonUSB - device with serial {self.serial_number!r} not found")
|
|
93
95
|
|
|
94
96
|
current_configuration = self.device.get_active_configuration()
|
|
95
97
|
if current_configuration.bConfigurationValue != self.configuration_number:
|
|
@@ -98,14 +100,14 @@ class Usb(BaseTransport):
|
|
|
98
100
|
|
|
99
101
|
interface = cfg[(self.interface_number, 0)]
|
|
100
102
|
|
|
101
|
-
self.
|
|
102
|
-
self.
|
|
103
|
+
self.out_ep = interface[self.out_ep_number]
|
|
104
|
+
self.in_ep = interface[self.in_ep_number]
|
|
103
105
|
|
|
104
|
-
self.
|
|
106
|
+
self.start_listener()
|
|
105
107
|
self.status = 1 # connected
|
|
106
108
|
|
|
107
|
-
def
|
|
108
|
-
super().
|
|
109
|
+
def start_listener(self):
|
|
110
|
+
super().start_listener()
|
|
109
111
|
if self._packet_listener.is_alive():
|
|
110
112
|
self._packet_listener.join()
|
|
111
113
|
self._packet_listener = threading.Thread(target=self._packet_listen)
|
|
@@ -113,83 +115,68 @@ class Usb(BaseTransport):
|
|
|
113
115
|
|
|
114
116
|
def close(self):
|
|
115
117
|
"""Close the transport-layer connection and event-loop."""
|
|
116
|
-
self.
|
|
118
|
+
self.finish_listener()
|
|
117
119
|
if self.listener.is_alive():
|
|
118
120
|
self.listener.join()
|
|
119
121
|
if self._packet_listener.is_alive():
|
|
120
122
|
self._packet_listener.join()
|
|
121
|
-
self.
|
|
123
|
+
self.close_connection()
|
|
122
124
|
|
|
123
125
|
def _packet_listen(self):
|
|
124
|
-
|
|
125
|
-
close_event_set = self.closeEvent.isSet
|
|
126
|
-
|
|
126
|
+
close_event_set = self.closeEvent.is_set
|
|
127
127
|
_packets = self._packets
|
|
128
|
-
read = self.
|
|
129
|
-
|
|
128
|
+
read = self.in_ep.read
|
|
130
129
|
buffer = array("B", bytes(RECV_SIZE))
|
|
131
130
|
buffer_view = memoryview(buffer)
|
|
132
|
-
|
|
133
131
|
while True:
|
|
134
132
|
try:
|
|
135
133
|
if close_event_set():
|
|
136
134
|
return
|
|
137
|
-
|
|
138
135
|
try:
|
|
139
|
-
recv_timestamp =
|
|
136
|
+
recv_timestamp = self.timestamp.value
|
|
140
137
|
read_count = read(buffer, 100) # 100ms timeout
|
|
141
138
|
if read_count != RECV_SIZE:
|
|
142
139
|
_packets.append((buffer_view[:read_count].tobytes(), recv_timestamp))
|
|
143
140
|
else:
|
|
144
141
|
_packets.append((buffer.tobytes(), recv_timestamp))
|
|
145
|
-
except
|
|
142
|
+
except (USBError, USBTimeoutError):
|
|
146
143
|
# print(format_exc())
|
|
147
|
-
|
|
144
|
+
short_sleep()
|
|
148
145
|
continue
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
except BaseException: # noqa: B036
|
|
147
|
+
# Note: catch-all only permitted if the intention is re-raising.
|
|
151
148
|
self.status = 0 # disconnected
|
|
152
149
|
break
|
|
153
150
|
|
|
154
151
|
def listen(self):
|
|
155
152
|
HEADER_UNPACK_FROM = self.HEADER.unpack_from
|
|
156
153
|
HEADER_SIZE = self.HEADER_SIZE
|
|
157
|
-
|
|
158
154
|
popleft = self._packets.popleft
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
close_event_set = self.closeEvent.isSet
|
|
162
|
-
|
|
155
|
+
process_response = self.process_response
|
|
156
|
+
close_event_set = self.closeEvent.is_set
|
|
163
157
|
_packets = self._packets
|
|
164
|
-
length
|
|
165
|
-
|
|
166
|
-
data = bytearray(b"")
|
|
167
|
-
|
|
168
|
-
last_sleep = perf_counter()
|
|
158
|
+
length: Optional[int] = None
|
|
159
|
+
counter: int = 0
|
|
160
|
+
data: bytearray = bytearray(b"")
|
|
161
|
+
last_sleep: int = self.timestamp.value
|
|
169
162
|
|
|
170
163
|
while True:
|
|
171
164
|
if close_event_set():
|
|
172
165
|
return
|
|
173
|
-
|
|
174
|
-
count = len(_packets)
|
|
175
|
-
|
|
166
|
+
count: int = len(_packets)
|
|
176
167
|
if not count:
|
|
177
|
-
|
|
178
|
-
last_sleep =
|
|
168
|
+
short_sleep()
|
|
169
|
+
last_sleep = self.timestamp.value
|
|
179
170
|
continue
|
|
180
|
-
|
|
181
171
|
for _ in range(count):
|
|
182
172
|
bts, timestamp = popleft()
|
|
183
|
-
|
|
184
173
|
data += bts
|
|
185
|
-
current_size = len(data)
|
|
186
|
-
current_position = 0
|
|
187
|
-
|
|
174
|
+
current_size: int = len(data)
|
|
175
|
+
current_position: int = 0
|
|
188
176
|
while True:
|
|
189
|
-
if
|
|
190
|
-
|
|
191
|
-
last_sleep =
|
|
192
|
-
|
|
177
|
+
if self.timestamp.value - last_sleep >= FIVE_MS:
|
|
178
|
+
short_sleep()
|
|
179
|
+
last_sleep = self.timestamp.value
|
|
193
180
|
if length is None:
|
|
194
181
|
if current_size >= HEADER_SIZE:
|
|
195
182
|
length, counter = HEADER_UNPACK_FROM(data, current_position)
|
|
@@ -201,31 +188,26 @@ class Usb(BaseTransport):
|
|
|
201
188
|
else:
|
|
202
189
|
if current_size >= length:
|
|
203
190
|
response = data[current_position : current_position + length]
|
|
204
|
-
|
|
205
|
-
|
|
191
|
+
process_response(response, length, counter, timestamp)
|
|
206
192
|
current_size -= length
|
|
207
193
|
current_position += length
|
|
208
|
-
|
|
209
194
|
length = None
|
|
210
|
-
|
|
211
195
|
else:
|
|
212
|
-
|
|
213
196
|
data = data[current_position:]
|
|
214
197
|
break
|
|
215
198
|
|
|
216
199
|
def send(self, frame):
|
|
217
|
-
|
|
218
|
-
self.pre_send_timestamp = time()
|
|
200
|
+
self.pre_send_timestamp = self.timestamp.value
|
|
219
201
|
try:
|
|
220
|
-
self.
|
|
221
|
-
except
|
|
202
|
+
self.out_ep.write(frame)
|
|
203
|
+
except (USBError, USBTimeoutError):
|
|
222
204
|
# sometimes usb.core.USBError: [Errno 5] Input/Output Error is raised
|
|
223
205
|
# even though the command is send and a reply is received from the device.
|
|
224
206
|
# Ignore this here since a Timeout error will be raised anyway if
|
|
225
207
|
# the device does not respond
|
|
226
208
|
pass
|
|
227
|
-
self.post_send_timestamp =
|
|
209
|
+
self.post_send_timestamp = self.timestamp.value
|
|
228
210
|
|
|
229
|
-
def
|
|
211
|
+
def close_connection(self):
|
|
230
212
|
if self.device is not None:
|
|
231
213
|
usb.util.dispose_resources(self.device)
|
pyxcp/types.py
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
2
|
import enum
|
|
4
3
|
from collections import namedtuple
|
|
5
4
|
|
|
6
5
|
import construct
|
|
7
|
-
from construct import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
6
|
+
from construct import (
|
|
7
|
+
BitsInteger,
|
|
8
|
+
BitStruct,
|
|
9
|
+
Bytes,
|
|
10
|
+
Enum,
|
|
11
|
+
Flag,
|
|
12
|
+
GreedyBytes,
|
|
13
|
+
GreedyRange,
|
|
14
|
+
If,
|
|
15
|
+
IfThenElse,
|
|
16
|
+
Int8ul,
|
|
17
|
+
Int16ub,
|
|
18
|
+
Int16ul,
|
|
19
|
+
Int32ub,
|
|
20
|
+
Int32ul,
|
|
21
|
+
Int64ub,
|
|
22
|
+
Int64ul,
|
|
23
|
+
Padding,
|
|
24
|
+
Struct,
|
|
25
|
+
Switch,
|
|
26
|
+
this,
|
|
27
|
+
)
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
if construct.version < (2, 8):
|
|
@@ -735,6 +737,11 @@ GetEventChannelInfoResponse = Struct(
|
|
|
735
737
|
"eventChannelPriority" / Int8ul,
|
|
736
738
|
)
|
|
737
739
|
|
|
740
|
+
GetSlaveIdResponse = Struct(
|
|
741
|
+
"magic" / Bytes(3),
|
|
742
|
+
"identifier" / Int32u,
|
|
743
|
+
)
|
|
744
|
+
|
|
738
745
|
GetDaqIdResponse = Struct(
|
|
739
746
|
"canIdFixed"
|
|
740
747
|
/ Enum(
|
|
@@ -909,6 +916,7 @@ DbgGetTriDescTblResponse = Struct("mode" / Int8ul, Padding(2), "length" / Int32u
|
|
|
909
916
|
|
|
910
917
|
DbgLlbtResponse = Struct(Padding(1), "length" / Int16u, "data" / Int8ul[this.length])
|
|
911
918
|
|
|
919
|
+
# Convert to seconds.
|
|
912
920
|
DAQ_TIMESTAMP_UNIT_TO_EXP = {
|
|
913
921
|
"DAQ_TIMESTAMP_UNIT_1PS": -12,
|
|
914
922
|
"DAQ_TIMESTAMP_UNIT_10PS": -11,
|
|
@@ -925,6 +933,39 @@ DAQ_TIMESTAMP_UNIT_TO_EXP = {
|
|
|
925
933
|
"DAQ_TIMESTAMP_UNIT_1S": 0,
|
|
926
934
|
}
|
|
927
935
|
|
|
936
|
+
# Convert to nano-seconds.
|
|
937
|
+
DAQ_TIMESTAMP_UNIT_TO_NS = {
|
|
938
|
+
"DAQ_TIMESTAMP_UNIT_1PS": 0.001,
|
|
939
|
+
"DAQ_TIMESTAMP_UNIT_10PS": 0.01,
|
|
940
|
+
"DAQ_TIMESTAMP_UNIT_100PS": 0.1,
|
|
941
|
+
"DAQ_TIMESTAMP_UNIT_1NS": 1,
|
|
942
|
+
"DAQ_TIMESTAMP_UNIT_10NS": 10,
|
|
943
|
+
"DAQ_TIMESTAMP_UNIT_100NS": 100,
|
|
944
|
+
"DAQ_TIMESTAMP_UNIT_1US": 1000,
|
|
945
|
+
"DAQ_TIMESTAMP_UNIT_10US": 10 * 1000,
|
|
946
|
+
"DAQ_TIMESTAMP_UNIT_100US": 100 * 1000,
|
|
947
|
+
"DAQ_TIMESTAMP_UNIT_1MS": 1000 * 1000,
|
|
948
|
+
"DAQ_TIMESTAMP_UNIT_10MS": 10 * 1000 * 1000,
|
|
949
|
+
"DAQ_TIMESTAMP_UNIT_100MS": 100 * 1000 * 1000,
|
|
950
|
+
"DAQ_TIMESTAMP_UNIT_1S": 1000 * 1000 * 1000,
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
EVENT_CHANNEL_TIME_UNIT_TO_EXP = {
|
|
954
|
+
"EVENT_CHANNEL_TIME_UNIT_1PS": -12,
|
|
955
|
+
"EVENT_CHANNEL_TIME_UNIT_10PS": -11,
|
|
956
|
+
"EVENT_CHANNEL_TIME_UNIT_100PS": -10,
|
|
957
|
+
"EVENT_CHANNEL_TIME_UNIT_1NS": -9,
|
|
958
|
+
"EVENT_CHANNEL_TIME_UNIT_10NS": -8,
|
|
959
|
+
"EVENT_CHANNEL_TIME_UNIT_100NS": -7,
|
|
960
|
+
"EVENT_CHANNEL_TIME_UNIT_1US": -6,
|
|
961
|
+
"EVENT_CHANNEL_TIME_UNIT_10US": -5,
|
|
962
|
+
"EVENT_CHANNEL_TIME_UNIT_100US": -4,
|
|
963
|
+
"EVENT_CHANNEL_TIME_UNIT_1MS": -3,
|
|
964
|
+
"EVENT_CHANNEL_TIME_UNIT_10MS": -2,
|
|
965
|
+
"EVENT_CHANNEL_TIME_UNIT_100MS": -1,
|
|
966
|
+
"EVENT_CHANNEL_TIME_UNIT_1S": 0,
|
|
967
|
+
}
|
|
968
|
+
|
|
928
969
|
|
|
929
970
|
class XcpGetSeedMode(enum.IntEnum):
|
|
930
971
|
FIRST_PART = 0
|
|
@@ -942,3 +983,11 @@ class FrameCategory(enum.IntEnum):
|
|
|
942
983
|
SERV = 5
|
|
943
984
|
DAQ = 6
|
|
944
985
|
STIM = 7
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
class TryCommandResult(enum.IntEnum):
|
|
989
|
+
""" """
|
|
990
|
+
|
|
991
|
+
OK = 0
|
|
992
|
+
XCP_ERROR = 1
|
|
993
|
+
OTHER_ERROR = 2
|
pyxcp/utils.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
|
|
2
|
+
import datetime
|
|
3
|
+
import functools
|
|
4
|
+
import operator
|
|
3
5
|
import sys
|
|
4
6
|
from binascii import hexlify
|
|
5
|
-
from time import
|
|
6
|
-
from time import perf_counter
|
|
7
|
-
from time import time
|
|
7
|
+
from time import perf_counter, sleep
|
|
8
8
|
|
|
9
9
|
import chardet
|
|
10
|
+
import pytz
|
|
11
|
+
|
|
12
|
+
from pyxcp.cpp_ext.cpp_ext import TimestampInfo
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
def hexDump(arr):
|
|
@@ -14,7 +17,7 @@ def hexDump(arr):
|
|
|
14
17
|
size = len(arr)
|
|
15
18
|
try:
|
|
16
19
|
arr = arr.hex()
|
|
17
|
-
except BaseException:
|
|
20
|
+
except BaseException: # noqa: B036
|
|
18
21
|
arr = hexlify(arr).decode("ascii")
|
|
19
22
|
return "[{}]".format(" ".join([arr[i * 2 : (i + 1) * 2] for i in range(size)]))
|
|
20
23
|
elif isinstance(arr, (list, tuple)):
|
|
@@ -22,28 +25,34 @@ def hexDump(arr):
|
|
|
22
25
|
size = len(arr)
|
|
23
26
|
try:
|
|
24
27
|
arr = arr.hex()
|
|
25
|
-
except BaseException:
|
|
28
|
+
except BaseException: # noqa: B036
|
|
26
29
|
arr = hexlify(arr).decode("ascii")
|
|
27
30
|
return "[{}]".format(" ".join([arr[i * 2 : (i + 1) * 2] for i in range(size)]))
|
|
28
31
|
else:
|
|
29
|
-
return "[{}]".format(" ".join(["{:02x}"
|
|
32
|
+
return "[{}]".format(" ".join([f"{x:02x}" for x in arr]))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def seconds_to_nanoseconds(value: float) -> int:
|
|
36
|
+
return int(value * 1_000_000_000)
|
|
30
37
|
|
|
31
38
|
|
|
32
39
|
def slicer(iterable, sliceLength, converter=None):
|
|
33
40
|
if converter is None:
|
|
34
41
|
converter = type(iterable)
|
|
35
42
|
length = len(iterable)
|
|
36
|
-
return [converter(
|
|
43
|
+
return [converter(iterable[item : item + sliceLength]) for item in range(0, length, sliceLength)]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def functools_reduce_iconcat(a):
|
|
47
|
+
return functools.reduce(operator.iconcat, a, [])
|
|
37
48
|
|
|
38
49
|
|
|
39
50
|
def flatten(*args):
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
result.append(arg)
|
|
46
|
-
return result
|
|
51
|
+
"""Flatten a list of lists into a single list.
|
|
52
|
+
|
|
53
|
+
s. https://stackoverflow.com/questions/952914/how-do-i-make-a-flat-list-out-of-a-list-of-lists
|
|
54
|
+
"""
|
|
55
|
+
return functools.reduce(operator.iconcat, args, [])
|
|
47
56
|
|
|
48
57
|
|
|
49
58
|
def getPythonVersion():
|
|
@@ -60,7 +69,10 @@ def decode_bytes(byte_str: bytes) -> str:
|
|
|
60
69
|
|
|
61
70
|
|
|
62
71
|
PYTHON_VERSION = getPythonVersion()
|
|
63
|
-
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def short_sleep():
|
|
75
|
+
sleep(0.0005)
|
|
64
76
|
|
|
65
77
|
|
|
66
78
|
def delay(amount: float):
|
|
@@ -69,3 +81,22 @@ def delay(amount: float):
|
|
|
69
81
|
start = perf_counter()
|
|
70
82
|
while perf_counter() < start + amount:
|
|
71
83
|
pass
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class CurrentDatetime(TimestampInfo):
|
|
87
|
+
|
|
88
|
+
def __init__(self, timestamp_ns: int):
|
|
89
|
+
TimestampInfo.__init__(self, timestamp_ns)
|
|
90
|
+
timezone = pytz.timezone(self.timezone)
|
|
91
|
+
dt = datetime.datetime.fromtimestamp(timestamp_ns / 1_000_000_000.0)
|
|
92
|
+
self.utc_offset = int(timezone.utcoffset(dt).total_seconds() / 60)
|
|
93
|
+
self.dst_offset = int(timezone.dst(dt).total_seconds() / 60)
|
|
94
|
+
|
|
95
|
+
def __str__(self):
|
|
96
|
+
return f"""CurrentDatetime(
|
|
97
|
+
datetime="{datetime.datetime.fromtimestamp(self.timestamp_ns / 1_000_000_000.0)!s}",
|
|
98
|
+
timezone="{self.timezone}",
|
|
99
|
+
timestamp_ns={self.timestamp_ns},
|
|
100
|
+
utc_offset={self.utc_offset},
|
|
101
|
+
dst_offset={self.dst_offset}
|
|
102
|
+
)"""
|
pyxcp/vector/map.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
from enum import IntEnum
|
|
4
2
|
|
|
5
3
|
MAP_NAMES = {
|
|
6
4
|
1: "BorlandC 16 Bit",
|
|
@@ -81,4 +79,4 @@ MAP name
|
|
|
81
79
|
|
|
82
80
|
|
|
83
81
|
def mapfile_name(name, counter, fmt):
|
|
84
|
-
return "{:2d}{:d}{:s}.map"
|
|
82
|
+
return f"{fmt:2d}{counter:d}{name:s}.map"
|
|
@@ -1,41 +1,43 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyxcp
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.23
|
|
4
4
|
Summary: Universal Calibration Protocol for Python
|
|
5
|
+
Home-page: https://github.com/christoph2/pyxcp
|
|
6
|
+
License: LGPLv3
|
|
5
7
|
Keywords: automotive,ecu,xcp,asam,autosar
|
|
6
8
|
Author: Christoph Schueler
|
|
7
|
-
Author-email:
|
|
8
|
-
Requires-Python: >=3.
|
|
9
|
+
Author-email: cpu.gems@googlemail.com
|
|
10
|
+
Requires-Python: >=3.8.1,<4.0.0
|
|
9
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
12
|
Classifier: Intended Audience :: Developers
|
|
11
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.9
|
|
12
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
21
|
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
22
|
Classifier: Topic :: Scientific/Engineering
|
|
19
23
|
Classifier: Topic :: Software Development
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist: chardet>=5.2.0
|
|
22
|
-
Requires-Dist: construct
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
|
|
24
|
+
Requires-Dist: bandit (>=1.7.8,<2.0.0)
|
|
25
|
+
Requires-Dist: chardet (>=5.2.0,<6.0.0)
|
|
26
|
+
Requires-Dist: construct (>=2.10.68,<3.0.0)
|
|
27
|
+
Requires-Dist: line-profiler-pycharm (>=1.1.0,<2.0.0)
|
|
28
|
+
Requires-Dist: mako (>=1.2.4,<2.0.0)
|
|
29
|
+
Requires-Dist: pyserial (>=3.5,<4.0)
|
|
30
|
+
Requires-Dist: python-can (>=4.2.2,<5.0.0)
|
|
31
|
+
Requires-Dist: pytz (>=2024.1,<2025.0)
|
|
32
|
+
Requires-Dist: pyusb (>=1.2.1,<2.0.0)
|
|
33
|
+
Requires-Dist: rich (>=13.6.0,<14.0.0)
|
|
34
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
35
|
+
Requires-Dist: tomlkit (>=0.12.5,<0.13.0)
|
|
36
|
+
Requires-Dist: traitlets (<=5.11.2)
|
|
37
|
+
Requires-Dist: uptime (>=3.0.1,<4.0.0)
|
|
34
38
|
Description-Content-Type: text/markdown
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
pyXCP
|
|
38
|
-
=====
|
|
40
|
+
# pyXCP
|
|
39
41
|
|
|
40
42
|
[](https://app.codacy.com/app/christoph2/pyxcp?utm_source=github.com&utm_medium=referral&utm_content=christoph2/pyxcp&utm_campaign=Badge_Grade_Settings)
|
|
41
43
|
[](https://codeclimate.com/github/christoph2/pyxcp/maintainability)
|
|
@@ -59,17 +61,20 @@ XCP also replaces the older CCP (CAN Calibration Protocol).
|
|
|
59
61
|
pyXCP is hosted on Github, get the latest release: [https://github.com/christoph2/pyxcp](https://github.com/christoph2/pyxcp)
|
|
60
62
|
|
|
61
63
|
You can install pyxcp from source:
|
|
64
|
+
|
|
62
65
|
```
|
|
63
66
|
pip install -r requirements.txt
|
|
64
67
|
python setup.py install
|
|
65
68
|
```
|
|
66
69
|
|
|
67
70
|
Alternatively, you can install pyxcp from source with pip:
|
|
71
|
+
|
|
68
72
|
```
|
|
69
73
|
pip install git+https://github.com/christoph2/pyxcp.git
|
|
70
74
|
```
|
|
71
75
|
|
|
72
76
|
Alternatively, get pyxcp from [PyPI](https://pypi.org/project/pyxcp/):
|
|
77
|
+
|
|
73
78
|
```
|
|
74
79
|
pip install pyxcp
|
|
75
80
|
```
|