pyxcp 0.25.2__cp314-cp314-win_arm64.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.
Files changed (154) hide show
  1. pyxcp/__init__.py +20 -0
  2. pyxcp/aml/EtasCANMonitoring.a2l +82 -0
  3. pyxcp/aml/EtasCANMonitoring.aml +67 -0
  4. pyxcp/aml/XCP_Common.aml +408 -0
  5. pyxcp/aml/XCPonCAN.aml +78 -0
  6. pyxcp/aml/XCPonEth.aml +33 -0
  7. pyxcp/aml/XCPonFlx.aml +113 -0
  8. pyxcp/aml/XCPonSxI.aml +66 -0
  9. pyxcp/aml/XCPonUSB.aml +106 -0
  10. pyxcp/aml/ifdata_CAN.a2l +20 -0
  11. pyxcp/aml/ifdata_Eth.a2l +11 -0
  12. pyxcp/aml/ifdata_Flx.a2l +94 -0
  13. pyxcp/aml/ifdata_SxI.a2l +13 -0
  14. pyxcp/aml/ifdata_USB.a2l +81 -0
  15. pyxcp/asam/__init__.py +0 -0
  16. pyxcp/asam/types.py +131 -0
  17. pyxcp/asamkeydll.c +116 -0
  18. pyxcp/asamkeydll.exe +0 -0
  19. pyxcp/asamkeydll.sh +2 -0
  20. pyxcp/checksum.py +732 -0
  21. pyxcp/cmdline.py +83 -0
  22. pyxcp/config/__init__.py +1257 -0
  23. pyxcp/config/legacy.py +120 -0
  24. pyxcp/constants.py +47 -0
  25. pyxcp/cpp_ext/__init__.py +0 -0
  26. pyxcp/cpp_ext/aligned_buffer.hpp +168 -0
  27. pyxcp/cpp_ext/bin.hpp +105 -0
  28. pyxcp/cpp_ext/blockmem.hpp +58 -0
  29. pyxcp/cpp_ext/cpp_ext.cp310-win_arm64.pyd +0 -0
  30. pyxcp/cpp_ext/cpp_ext.cp311-win_arm64.pyd +0 -0
  31. pyxcp/cpp_ext/cpp_ext.cp312-win_arm64.pyd +0 -0
  32. pyxcp/cpp_ext/cpp_ext.cp313-win_arm64.pyd +0 -0
  33. pyxcp/cpp_ext/cpp_ext.cp314-win_arm64.pyd +0 -0
  34. pyxcp/cpp_ext/daqlist.hpp +374 -0
  35. pyxcp/cpp_ext/event.hpp +67 -0
  36. pyxcp/cpp_ext/extension_wrapper.cpp +131 -0
  37. pyxcp/cpp_ext/framing.hpp +360 -0
  38. pyxcp/cpp_ext/helper.hpp +280 -0
  39. pyxcp/cpp_ext/mcobject.hpp +248 -0
  40. pyxcp/cpp_ext/sxi_framing.hpp +332 -0
  41. pyxcp/cpp_ext/tsqueue.hpp +46 -0
  42. pyxcp/daq_stim/__init__.py +306 -0
  43. pyxcp/daq_stim/optimize/__init__.py +67 -0
  44. pyxcp/daq_stim/optimize/binpacking.py +41 -0
  45. pyxcp/daq_stim/scheduler.cpp +62 -0
  46. pyxcp/daq_stim/scheduler.hpp +75 -0
  47. pyxcp/daq_stim/stim.cp310-win_arm64.pyd +0 -0
  48. pyxcp/daq_stim/stim.cp311-win_arm64.pyd +0 -0
  49. pyxcp/daq_stim/stim.cp312-win_arm64.pyd +0 -0
  50. pyxcp/daq_stim/stim.cp313-win_arm64.pyd +0 -0
  51. pyxcp/daq_stim/stim.cp314-win_arm64.pyd +0 -0
  52. pyxcp/daq_stim/stim.cpp +13 -0
  53. pyxcp/daq_stim/stim.hpp +604 -0
  54. pyxcp/daq_stim/stim_wrapper.cpp +50 -0
  55. pyxcp/dllif.py +100 -0
  56. pyxcp/errormatrix.py +878 -0
  57. pyxcp/examples/conf_can.toml +19 -0
  58. pyxcp/examples/conf_can_user.toml +16 -0
  59. pyxcp/examples/conf_can_vector.json +11 -0
  60. pyxcp/examples/conf_can_vector.toml +11 -0
  61. pyxcp/examples/conf_eth.toml +9 -0
  62. pyxcp/examples/conf_nixnet.json +20 -0
  63. pyxcp/examples/conf_socket_can.toml +12 -0
  64. pyxcp/examples/run_daq.py +165 -0
  65. pyxcp/examples/xcp_policy.py +60 -0
  66. pyxcp/examples/xcp_read_benchmark.py +38 -0
  67. pyxcp/examples/xcp_skel.py +48 -0
  68. pyxcp/examples/xcp_unlock.py +38 -0
  69. pyxcp/examples/xcp_user_supplied_driver.py +43 -0
  70. pyxcp/examples/xcphello.py +79 -0
  71. pyxcp/examples/xcphello_recorder.py +107 -0
  72. pyxcp/master/__init__.py +10 -0
  73. pyxcp/master/errorhandler.py +677 -0
  74. pyxcp/master/master.py +2645 -0
  75. pyxcp/py.typed +0 -0
  76. pyxcp/recorder/.idea/.gitignore +8 -0
  77. pyxcp/recorder/.idea/misc.xml +4 -0
  78. pyxcp/recorder/.idea/modules.xml +8 -0
  79. pyxcp/recorder/.idea/recorder.iml +6 -0
  80. pyxcp/recorder/.idea/sonarlint/issuestore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +7 -0
  81. pyxcp/recorder/.idea/sonarlint/issuestore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  82. pyxcp/recorder/.idea/sonarlint/issuestore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  83. pyxcp/recorder/.idea/sonarlint/issuestore/index.pb +7 -0
  84. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +0 -0
  85. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  86. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  87. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/index.pb +7 -0
  88. pyxcp/recorder/.idea/vcs.xml +10 -0
  89. pyxcp/recorder/__init__.py +96 -0
  90. pyxcp/recorder/build_clang.cmd +1 -0
  91. pyxcp/recorder/build_clang.sh +2 -0
  92. pyxcp/recorder/build_gcc.cmd +1 -0
  93. pyxcp/recorder/build_gcc.sh +2 -0
  94. pyxcp/recorder/build_gcc_arm.sh +2 -0
  95. pyxcp/recorder/converter/__init__.py +445 -0
  96. pyxcp/recorder/lz4.c +2829 -0
  97. pyxcp/recorder/lz4.h +879 -0
  98. pyxcp/recorder/lz4hc.c +2041 -0
  99. pyxcp/recorder/lz4hc.h +413 -0
  100. pyxcp/recorder/mio.hpp +1714 -0
  101. pyxcp/recorder/reader.hpp +138 -0
  102. pyxcp/recorder/reco.py +278 -0
  103. pyxcp/recorder/recorder.rst +0 -0
  104. pyxcp/recorder/rekorder.cp310-win_arm64.pyd +0 -0
  105. pyxcp/recorder/rekorder.cp311-win_arm64.pyd +0 -0
  106. pyxcp/recorder/rekorder.cp312-win_arm64.pyd +0 -0
  107. pyxcp/recorder/rekorder.cp313-win_arm64.pyd +0 -0
  108. pyxcp/recorder/rekorder.cp314-win_arm64.pyd +0 -0
  109. pyxcp/recorder/rekorder.cpp +59 -0
  110. pyxcp/recorder/rekorder.hpp +274 -0
  111. pyxcp/recorder/setup.py +41 -0
  112. pyxcp/recorder/test_reko.py +34 -0
  113. pyxcp/recorder/unfolder.hpp +1354 -0
  114. pyxcp/recorder/wrap.cpp +184 -0
  115. pyxcp/recorder/writer.hpp +302 -0
  116. pyxcp/scripts/__init__.py +0 -0
  117. pyxcp/scripts/pyxcp_probe_can_drivers.py +20 -0
  118. pyxcp/scripts/xcp_examples.py +64 -0
  119. pyxcp/scripts/xcp_fetch_a2l.py +40 -0
  120. pyxcp/scripts/xcp_id_scanner.py +18 -0
  121. pyxcp/scripts/xcp_info.py +144 -0
  122. pyxcp/scripts/xcp_profile.py +26 -0
  123. pyxcp/scripts/xmraw_converter.py +31 -0
  124. pyxcp/stim/__init__.py +0 -0
  125. pyxcp/tests/test_asam_types.py +24 -0
  126. pyxcp/tests/test_binpacking.py +186 -0
  127. pyxcp/tests/test_can.py +1324 -0
  128. pyxcp/tests/test_checksum.py +95 -0
  129. pyxcp/tests/test_daq.py +193 -0
  130. pyxcp/tests/test_daq_opt.py +426 -0
  131. pyxcp/tests/test_frame_padding.py +156 -0
  132. pyxcp/tests/test_framing.py +262 -0
  133. pyxcp/tests/test_master.py +2116 -0
  134. pyxcp/tests/test_transport.py +177 -0
  135. pyxcp/tests/test_utils.py +30 -0
  136. pyxcp/timing.py +60 -0
  137. pyxcp/transport/__init__.py +13 -0
  138. pyxcp/transport/base.py +484 -0
  139. pyxcp/transport/base_transport.hpp +0 -0
  140. pyxcp/transport/can.py +660 -0
  141. pyxcp/transport/eth.py +254 -0
  142. pyxcp/transport/sxi.py +209 -0
  143. pyxcp/transport/transport_ext.hpp +214 -0
  144. pyxcp/transport/transport_wrapper.cpp +249 -0
  145. pyxcp/transport/usb_transport.py +229 -0
  146. pyxcp/types.py +987 -0
  147. pyxcp/utils.py +127 -0
  148. pyxcp/vector/__init__.py +0 -0
  149. pyxcp/vector/map.py +82 -0
  150. pyxcp-0.25.2.dist-info/METADATA +341 -0
  151. pyxcp-0.25.2.dist-info/RECORD +154 -0
  152. pyxcp-0.25.2.dist-info/WHEEL +4 -0
  153. pyxcp-0.25.2.dist-info/entry_points.txt +9 -0
  154. pyxcp-0.25.2.dist-info/licenses/LICENSE +165 -0
@@ -0,0 +1,374 @@
1
+
2
+ #if !defined(__DAQ_LIST_HPP)
3
+ #define __DAQ_LIST_HPP
4
+
5
+ #include "bin.hpp"
6
+ #include "helper.hpp"
7
+ #include "mcobject.hpp"
8
+
9
+ using flatten_odts_t = std::vector<std::vector<std::tuple<std::string, std::uint32_t, std::uint8_t, std::uint16_t, std::int16_t>>>;
10
+
11
+ class Odt {
12
+ public:
13
+ using odt_entry_initializer_t = std::tuple<std::string, std::string>;
14
+
15
+ Odt(const std::vector<odt_entry_initializer_t>& entries) {
16
+ for (const auto& entry : entries) {
17
+ const auto& [name, dt_name] = entry;
18
+ m_entries.emplace_back(McObject(name, 0, 0, 0, dt_name));
19
+ }
20
+ }
21
+
22
+ const std::vector<McObject>& get_entries() const {
23
+ return m_entries;
24
+ }
25
+
26
+ std::string dumps() const {
27
+ std::stringstream ss;
28
+ ss << to_binary(m_entries.size());
29
+ for (const auto& entry : m_entries) {
30
+ ss << entry.dumps();
31
+ }
32
+ return ss.str();
33
+ }
34
+
35
+ std::string to_string() const {
36
+ std::stringstream ss;
37
+ ss << "Odt(entries=[";
38
+ for (std::size_t i = 0; i < m_entries.size(); ++i) {
39
+ ss << ::to_string(m_entries[i]);
40
+ if (i + 1 < m_entries.size()) {
41
+ ss << ", ";
42
+ }
43
+ }
44
+ ss << "])";
45
+ return ss.str();
46
+ }
47
+
48
+ private:
49
+ std::vector<McObject> m_entries;
50
+ };
51
+
52
+ inline std::string to_string(const Odt& odt) {
53
+ return odt.to_string();
54
+ }
55
+
56
+ class DaqListBase {
57
+ public:
58
+ DaqListBase(std::string_view name, std::uint16_t event_num, bool stim, bool enable_timestamps, std::uint8_t priority, std::uint8_t prescaler) :
59
+ m_name(name),
60
+ m_event_num(event_num),
61
+ m_priority(priority),
62
+ m_prescaler(prescaler),
63
+ m_stim(stim),
64
+ m_enable_timestamps(enable_timestamps),
65
+ m_odt_count(0),
66
+ m_total_entries(0),
67
+ m_total_length(0) {
68
+ }
69
+
70
+ virtual ~DaqListBase() = default;
71
+
72
+ virtual std::string dumps() const = 0;
73
+ virtual std::string to_string() const = 0;
74
+
75
+ bool get_enable_timestamps() const {
76
+ return m_enable_timestamps;
77
+ }
78
+
79
+ const std::string& get_name() const {
80
+ return m_name;
81
+ }
82
+
83
+ std::uint16_t get_event_num() const {
84
+ return m_event_num;
85
+ }
86
+
87
+ std::uint8_t get_priority() const {
88
+ return m_priority;
89
+ }
90
+
91
+ std::uint8_t get_prescaler() const {
92
+ return m_prescaler;
93
+ }
94
+
95
+ void set_event_num(std::uint16_t event_num) {
96
+ m_event_num = event_num;
97
+ }
98
+
99
+ bool get_stim() const {
100
+ return m_stim;
101
+ }
102
+
103
+ const std::vector<Bin>& get_measurements_opt() const {
104
+ return m_measurements_opt;
105
+ }
106
+
107
+ const std::vector<std::string>& get_header_names() const {
108
+ return m_header_names;
109
+ }
110
+
111
+ const std::vector<std::tuple<std::string, std::string>>& get_headers() const noexcept {
112
+ return m_headers;
113
+ }
114
+
115
+ std::uint16_t get_odt_count() const {
116
+ return m_odt_count;
117
+ }
118
+
119
+ std::uint16_t get_total_entries() const {
120
+ return m_total_entries;
121
+ }
122
+
123
+ std::uint16_t get_total_length() const {
124
+ return m_total_length;
125
+ }
126
+
127
+ const flatten_odts_t& get_flatten_odts() const {
128
+ return m_flatten_odts;
129
+ }
130
+
131
+ void set_measurements_opt(const std::vector<Bin>& measurements_opt) {
132
+ m_measurements_opt = measurements_opt;
133
+ m_header_names.clear();
134
+ m_headers.clear();
135
+ m_flatten_odts.clear();
136
+
137
+ auto odt_count = 0u;
138
+ auto total_entries = 0u;
139
+ auto total_length = 0u;
140
+ for (const auto& bin : measurements_opt) {
141
+ odt_count++;
142
+ std::vector<std::tuple<std::string, std::uint32_t, std::uint8_t, std::uint16_t, std::int16_t>> flatten_odt{};
143
+ for (const auto& mc_obj : bin.get_entries()) {
144
+ const auto& components = mc_obj.get_components();
145
+ if (!components.empty()) {
146
+ for (const auto& component : components) {
147
+ m_header_names.emplace_back(component.get_name());
148
+ flatten_odt.emplace_back(
149
+ component.get_name(), component.get_address(), component.get_ext(), component.get_length(),
150
+ component.get_type_index()
151
+ );
152
+ // TYPE_MAP_REV::at may throw if key is invalid; this indicates a programming error upstream.
153
+ m_headers.emplace_back(component.get_name(), TYPE_MAP_REV.at(static_cast<std::uint16_t>(component.get_type_index())));
154
+ total_entries++;
155
+ total_length += component.get_length();
156
+ }
157
+ } else {
158
+ // Treat the McObject itself as an entry when it has no components.
159
+ m_header_names.emplace_back(mc_obj.get_name());
160
+ flatten_odt.emplace_back(
161
+ mc_obj.get_name(), mc_obj.get_address(), mc_obj.get_ext(), mc_obj.get_length(), mc_obj.get_type_index()
162
+ );
163
+ m_headers.emplace_back(mc_obj.get_name(), TYPE_MAP_REV.at(static_cast<std::uint16_t>(mc_obj.get_type_index())));
164
+ total_entries++;
165
+ total_length += mc_obj.get_length();
166
+ }
167
+ }
168
+ m_flatten_odts.emplace_back(std::move(flatten_odt));
169
+ }
170
+ m_odt_count = static_cast<std::uint16_t>(odt_count);
171
+ m_total_entries = static_cast<std::uint16_t>(total_entries);
172
+ m_total_length = static_cast<std::uint16_t>(total_length);
173
+ }
174
+
175
+ protected:
176
+ std::string m_name;
177
+ std::uint16_t m_event_num;
178
+ std::uint8_t m_priority;
179
+ std::uint8_t m_prescaler;
180
+ bool m_stim;
181
+ bool m_enable_timestamps;
182
+ std::vector<Bin> m_measurements_opt;
183
+ std::vector<std::string> m_header_names;
184
+ std::vector<std::tuple<std::string, std::string>> m_headers;
185
+ std::uint16_t m_odt_count;
186
+ std::uint16_t m_total_entries;
187
+ std::uint16_t m_total_length;
188
+ flatten_odts_t m_flatten_odts;
189
+ };
190
+
191
+ class DaqList : public DaqListBase {
192
+ public:
193
+
194
+ using daq_list_initialzer_t = std::tuple<std::string, std::uint32_t, std::uint16_t, std::string>;
195
+
196
+ DaqList(
197
+ std::string_view meas_name, std::uint16_t event_num, bool stim, bool enable_timestamps,
198
+ const std::vector<daq_list_initialzer_t>& measurements, std::uint8_t priority=0x00, std::uint8_t prescaler=0x01
199
+ ) :
200
+ DaqListBase(meas_name, event_num, stim, enable_timestamps, priority, prescaler) {
201
+ for (const auto& measurement : measurements) {
202
+ auto const& [name, address, ext, dt_name] = measurement;
203
+ m_measurements.emplace_back(McObject(name, address, static_cast<std::uint8_t>(ext), 0, dt_name));
204
+ }
205
+ }
206
+
207
+ const std::vector<McObject>& get_measurements() const {
208
+ return m_measurements;
209
+ }
210
+
211
+ std::string dumps() const override {
212
+ std::stringstream ss;
213
+
214
+ std::uint8_t discr=1;
215
+
216
+ ss << to_binary(discr);
217
+ ss << to_binary(m_name);
218
+ ss << to_binary(m_event_num);
219
+ ss << to_binary(m_stim);
220
+ ss << to_binary(m_enable_timestamps);
221
+ ss << to_binary(m_priority);
222
+ ss << to_binary(m_prescaler);
223
+
224
+ ss << to_binary(m_odt_count);
225
+ ss << to_binary(m_total_entries);
226
+ ss << to_binary(m_total_length);
227
+
228
+ std::size_t meas_size = m_measurements.size();
229
+ ss << to_binary(meas_size);
230
+ for (const auto& mc_obj : m_measurements) {
231
+ ss << mc_obj.dumps();
232
+ }
233
+ std::size_t meas_opt_size = m_measurements_opt.size();
234
+ ss << to_binary(meas_opt_size);
235
+ for (const auto& mc_obj : m_measurements_opt) {
236
+ ss << mc_obj.dumps();
237
+ }
238
+ std::size_t hname_size = m_header_names.size();
239
+ ss << to_binary(hname_size);
240
+ for (const auto& hdr_obj : m_header_names) {
241
+ ss << to_binary(hdr_obj);
242
+ }
243
+ return ss.str();
244
+ }
245
+
246
+ std::string to_string() const override {
247
+ std::stringstream ss;
248
+ ss << "DaqList(";
249
+ ss << "name='" << m_name << "', ";
250
+ ss << "event_num=" << static_cast<std::uint16_t>(m_event_num) << ", ";
251
+ ss << "stim=" << bool_to_string(m_stim) << ", ";
252
+ ss << "enable_timestamps=" << bool_to_string(m_enable_timestamps) << ", ";
253
+ ss << "priority=" << static_cast<std::uint16_t>(m_priority) << ", ";
254
+ ss << "prescaler=" << static_cast<std::uint16_t>(m_prescaler) << ", ";
255
+ ss << "odt_count=" << static_cast<std::uint16_t>(m_odt_count) << ", ";
256
+ ss << "total_entries=" << static_cast<std::uint16_t>(m_total_entries) << ", ";
257
+ ss << "total_length=" << static_cast<std::uint16_t>(m_total_length) << ", ";
258
+ ss << "measurements=[";
259
+ for (std::size_t i = 0; i < m_measurements.size(); ++i) {
260
+ ss << ::to_string(m_measurements[i]);
261
+ if (i + 1 < m_measurements.size()) ss << ", ";
262
+ }
263
+ ss << "], ";
264
+ ss << "measurements_opt=[";
265
+ for (std::size_t i = 0; i < m_measurements_opt.size(); ++i) {
266
+ ss << ::to_string(m_measurements_opt[i]);
267
+ if (i + 1 < m_measurements_opt.size()) ss << ", ";
268
+ }
269
+ ss << "], ";
270
+ ss << "header_names=[";
271
+ for (std::size_t i = 0; i < m_header_names.size(); ++i) {
272
+ ss << "'" << m_header_names[i] << "'";
273
+ if (i + 1 < m_header_names.size()) ss << ", ";
274
+ }
275
+ ss << "])";
276
+ return ss.str();
277
+ }
278
+
279
+ static void loads(std::string_view buffer) {
280
+ }
281
+
282
+ private:
283
+ std::vector<McObject> m_measurements;
284
+ };
285
+
286
+ class PredefinedDaqList : public DaqListBase {
287
+ public:
288
+ using odt_initializer_t = std::vector<Odt::odt_entry_initializer_t>;
289
+ using predefined_daq_list_initializer_t = std::vector<odt_initializer_t>;
290
+
291
+ PredefinedDaqList(
292
+ std::string_view name, std::uint16_t event_num, bool stim, bool enable_timestamps,
293
+ const predefined_daq_list_initializer_t& odts, std::uint8_t priority = 0x00, std::uint8_t prescaler = 0x01) :
294
+ DaqListBase(name, event_num, stim, enable_timestamps, priority, prescaler) {
295
+ std::vector<Bin> bins;
296
+ bins.reserve(odts.size());
297
+ for (const auto& odt_init : odts) {
298
+ Bin bin(0);
299
+ std::uint16_t total_length = 0;
300
+ for (const auto& entry : odt_init) {
301
+ const auto& [name, dt_name] = entry;
302
+ // McObject will validate dt_name and set length accordingly.
303
+ McObject obj(name, 0, 0, 0, dt_name);
304
+ total_length = static_cast<std::uint16_t>(total_length + obj.get_length());
305
+ bin.append(obj);
306
+ }
307
+ // Derive Bin size and residual capacity from sum of entry lengths.
308
+ bin.set_size(total_length);
309
+ bin.set_residual_capacity(total_length);
310
+ bins.emplace_back(std::move(bin));
311
+ }
312
+ set_measurements_opt(bins);
313
+ }
314
+
315
+ std::string dumps() const override {
316
+ std::stringstream ss;
317
+
318
+ std::uint8_t discr=2;
319
+
320
+ ss << to_binary(discr);
321
+
322
+ ss << to_binary(m_name);
323
+ ss << to_binary(m_event_num);
324
+ ss << to_binary(m_stim);
325
+ ss << to_binary(m_enable_timestamps);
326
+ ss << to_binary(m_priority);
327
+ ss << to_binary(m_prescaler);
328
+
329
+ ss << to_binary(m_odt_count);
330
+ ss << to_binary(m_total_entries);
331
+ ss << to_binary(m_total_length);
332
+
333
+ std::size_t meas_opt_size = m_measurements_opt.size();
334
+ ss << to_binary(meas_opt_size);
335
+ for (const auto& mc_obj : m_measurements_opt) {
336
+ ss << mc_obj.dumps();
337
+ }
338
+ std::size_t hname_size = m_header_names.size();
339
+ ss << to_binary(hname_size);
340
+ for (const auto& hdr_obj : m_header_names) {
341
+ ss << to_binary(hdr_obj);
342
+ }
343
+ return ss.str();
344
+ }
345
+
346
+ std::string to_string() const override {
347
+ std::stringstream ss;
348
+ ss << "PredefinedDaqList(";
349
+ ss << "name='" << m_name << "', ";
350
+ ss << "event_num=" << static_cast<std::uint16_t>(m_event_num) << ", ";
351
+ ss << "stim=" << bool_to_string(m_stim) << ", ";
352
+ ss << "enable_timestamps=" << bool_to_string(m_enable_timestamps) << ", ";
353
+ ss << "priority=" << static_cast<std::uint16_t>(m_priority) << ", ";
354
+ ss << "prescaler=" << static_cast<std::uint16_t>(m_prescaler) << ", ";
355
+ ss << "odt_count=" << static_cast<std::uint16_t>(m_odt_count) << ", ";
356
+ ss << "total_entries=" << static_cast<std::uint16_t>(m_total_entries) << ", ";
357
+ ss << "total_length=" << static_cast<std::uint16_t>(m_total_length) << ", ";
358
+ ss << "measurements_opt=[";
359
+ for (std::size_t i = 0; i < m_measurements_opt.size(); ++i) {
360
+ ss << ::to_string(m_measurements_opt[i]);
361
+ if (i + 1 < m_measurements_opt.size()) ss << ", ";
362
+ }
363
+ ss << "], ";
364
+ ss << "header_names=[";
365
+ for (std::size_t i = 0; i < m_header_names.size(); ++i) {
366
+ ss << "'" << m_header_names[i] << "'";
367
+ if (i + 1 < m_header_names.size()) ss << ", ";
368
+ }
369
+ ss << "])";
370
+ return ss.str();
371
+ }
372
+ };
373
+
374
+ #endif // __DAQ_LIST_HPP
@@ -0,0 +1,67 @@
1
+
2
+ #ifndef __EVENT_HPP
3
+ #define __EVENT_HPP
4
+
5
+ #include <atomic>
6
+ #include <condition_variable>
7
+ #include <mutex>
8
+
9
+ class Event {
10
+ public:
11
+
12
+ Event(const Event& other) noexcept {
13
+ std::scoped_lock lock(other.m_mtx);
14
+ m_flag = other.m_flag;
15
+ }
16
+
17
+ ~Event() = default;
18
+ Event() = default;
19
+
20
+ void signal() noexcept {
21
+ std::scoped_lock lock(m_mtx);
22
+ m_flag = true;
23
+ m_cond.notify_one();
24
+ }
25
+
26
+ void wait() noexcept {
27
+ std::unique_lock lock(m_mtx);
28
+ m_cond.wait(lock, [this] { return m_flag; });
29
+ m_flag = false;
30
+ }
31
+
32
+ bool state() const noexcept {
33
+ std::scoped_lock lock(m_mtx);
34
+ return m_flag;
35
+ }
36
+
37
+ private:
38
+
39
+ mutable std::mutex m_mtx{};
40
+ bool m_flag{ false };
41
+ std::condition_variable m_cond{};
42
+ };
43
+
44
+ #if 0
45
+ class Spinlock {
46
+ public:
47
+
48
+ Spinlock() : m_flag(ATOMIC_FLAG_INIT) {
49
+ }
50
+
51
+ ~Spinlock() = default;
52
+
53
+ void lock() {
54
+ while (m_flag.test_and_set()) {
55
+ }
56
+ }
57
+
58
+ void unlock() {
59
+ m_flag.clear();
60
+ }
61
+
62
+ private:
63
+ std::atomic_flag m_flag;
64
+ };
65
+ #endif
66
+
67
+ #endif // __EVENT_HPP
@@ -0,0 +1,131 @@
1
+
2
+ #include <pybind11/chrono.h>
3
+ #include <pybind11/functional.h>
4
+ #include <pybind11/numpy.h>
5
+ #include <pybind11/pybind11.h>
6
+ #include <pybind11/stl.h>
7
+ #include <memory>
8
+
9
+ #include <cstdint>
10
+
11
+ #include "aligned_buffer.hpp"
12
+ #include "bin.hpp"
13
+ #include "daqlist.hpp"
14
+ #include "mcobject.hpp"
15
+
16
+ namespace py = pybind11;
17
+ using namespace pybind11::literals;
18
+
19
+ class PyTimestampInfo : public TimestampInfo {
20
+ public:
21
+
22
+ using TimestampInfo::TimestampInfo;
23
+ };
24
+
25
+
26
+ PYBIND11_MODULE(cpp_ext, m) {
27
+ m.doc() = "C++ extensions for pyXCP.";
28
+
29
+ //m.def("sleep_ms", &sleep_ms, "milliseconds"_a);
30
+ //m.def("sleep_ns", &sleep_ns, "nanoseconds"_a);
31
+
32
+ py::class_<McObject>(m, "McObject")
33
+ .def(
34
+ py::init<
35
+ std::string_view, std::uint32_t, std::uint8_t, std::uint16_t, const std::string&, const std::vector<McObject>&>(),
36
+ "name"_a, "address"_a, "ext"_a, "length"_a, "data_type"_a = "", "components"_a = std::vector<McObject>()
37
+ )
38
+ .def_property("name", &McObject::get_name, &McObject::set_name)
39
+ .def_property("address", &McObject::get_address, &McObject::set_address)
40
+ .def_property("ext", &McObject::get_ext, &McObject::set_ext)
41
+ .def_property("length", &McObject::get_length, &McObject::set_length)
42
+ .def_property("data_type", &McObject::get_data_type, &McObject::set_data_type)
43
+ .def_property_readonly("components", &McObject::get_components)
44
+
45
+ .def("add_component", &McObject::add_component, "component"_a)
46
+ .def("__eq__", [](const McObject& self, const McObject& other) { return self == other; })
47
+ .def("__repr__", [](const McObject& self) { return to_string(self); })
48
+ .def("__hash__", [](const McObject& self) { return self.get_hash(); })
49
+ ;
50
+
51
+ py::class_<Bin>(m, "Bin")
52
+ .def(py::init<std::uint16_t>(), "size"_a)
53
+ .def_property("size", &Bin::get_size, &Bin::set_size)
54
+ .def_property("residual_capacity", &Bin::get_residual_capacity, &Bin::set_residual_capacity)
55
+ .def_property("entries", &Bin::get_entries, nullptr)
56
+ .def("append", &Bin::append)
57
+ .def("__repr__", [](const Bin& self) { return to_string(self); })
58
+ .def("__eq__", [](const Bin& self, const Bin& other) { return self == other; })
59
+ .def("__len__", [](const Bin& self) { return std::size(self.get_entries()); });
60
+
61
+ py::class_<DaqListBase, std::shared_ptr<DaqListBase>>(m, "DaqListBase")
62
+ .def_property("name", &DaqListBase::get_name, nullptr)
63
+ .def_property("event_num", &DaqListBase::get_event_num, &DaqListBase::set_event_num)
64
+ .def_property("priority", &DaqListBase::get_priority, nullptr)
65
+ .def_property("prescaler", &DaqListBase::get_prescaler, nullptr)
66
+ .def_property("stim", &DaqListBase::get_stim, nullptr)
67
+ .def_property("enable_timestamps", &DaqListBase::get_enable_timestamps, nullptr)
68
+ .def_property("measurements_opt", &DaqListBase::get_measurements_opt, &DaqListBase::set_measurements_opt)
69
+ .def_property("headers", &DaqListBase::get_headers, nullptr)
70
+ .def_property("odt_count", &DaqListBase::get_odt_count, nullptr)
71
+ .def_property("total_entries", &DaqListBase::get_total_entries, nullptr)
72
+ .def_property("total_length", &DaqListBase::get_total_length, nullptr);
73
+
74
+ py::class_<DaqList, DaqListBase, std::shared_ptr<DaqList>>(m, "DaqList")
75
+ .def(
76
+ py::init<std::string_view, std::uint16_t, bool, bool, const std::vector<DaqList::daq_list_initialzer_t>&,
77
+ std::uint8_t, std::uint8_t>(), "name"_a, "event_num"_a, "stim"_a, "enable_timestamps"_a, "measurements"_a,
78
+ "priority"_a=0, "prescaler"_a=1
79
+ )
80
+ .def("__repr__", [](const DaqList& self) { return self.to_string(); })
81
+ .def_property("measurements", &DaqList::get_measurements, nullptr);
82
+
83
+ py::class_<PredefinedDaqList, DaqListBase, std::shared_ptr<PredefinedDaqList>>(m, "PredefinedDaqList")
84
+ .def(
85
+ py::init<std::string_view, std::uint16_t, bool, bool, const PredefinedDaqList::predefined_daq_list_initializer_t&,
86
+ std::uint8_t, std::uint8_t>(), "name"_a, "event_num"_a, "stim"_a, "enable_timestamps"_a, "odts"_a,
87
+ "priority"_a=0, "prescaler"_a=1
88
+ )
89
+ .def("__repr__", [](const PredefinedDaqList& self) {
90
+ try {
91
+ return self.to_string();
92
+ } catch (const std::exception& e) {
93
+ return std::string("PredefinedDaqList(<repr error: ") + e.what() + ">)";
94
+ } catch (...) {
95
+ return std::string("PredefinedDaqList(<repr error: unknown>)");
96
+ }
97
+ })
98
+ ;
99
+
100
+ // Aligned buffer utility
101
+ py::class_<AlignedBuffer>(m, "AlignedBuffer")
102
+ .def(py::init<std::size_t>(), py::arg("size") = 0xffff)
103
+ .def("reset", &AlignedBuffer::reset)
104
+ .def("append", &AlignedBuffer::append, py::arg("value"))
105
+ .def("extend", py::overload_cast<const py::bytes&>(&AlignedBuffer::extend))
106
+ .def("extend", py::overload_cast<const std::vector<std::uint8_t>&>(&AlignedBuffer::extend))
107
+ .def("__len__", [](const AlignedBuffer& self) { return self.size(); })
108
+ .def("__getitem__", [](const AlignedBuffer& self, py::object index) { return self.get_item(index); });
109
+
110
+
111
+ py::enum_<TimestampType>(m, "TimestampType")
112
+ .value("ABSOLUTE_TS", TimestampType::ABSOLUTE_TS)
113
+ .value("RELATIVE_TS", TimestampType::RELATIVE_TS);
114
+
115
+ py::class_<Timestamp>(m, "Timestamp")
116
+ .def(py::init<TimestampType>(), "ts_type"_a)
117
+ .def_property_readonly("absolute", &Timestamp::absolute)
118
+ .def_property_readonly("relative", &Timestamp::relative)
119
+ .def_property_readonly("value", &Timestamp::get_value)
120
+ .def_property_readonly("initial_value", &Timestamp::get_initial_value);
121
+
122
+ py::class_<TimestampInfo, PyTimestampInfo>(m, "TimestampInfo", py::dynamic_attr())
123
+ .def(py::init<std::uint64_t>())
124
+ .def(py::init<std::uint64_t, const std::string&, std::int16_t, std::int16_t>())
125
+
126
+ .def_property_readonly("timestamp_ns", &TimestampInfo::get_timestamp_ns)
127
+ .def_property("utc_offset", &TimestampInfo::get_utc_offset, &TimestampInfo::set_utc_offset)
128
+ .def_property("dst_offset", &TimestampInfo::get_dst_offset, &TimestampInfo::set_dst_offset)
129
+ .def_property("timezone", &TimestampInfo::get_timezone, &TimestampInfo::set_timezone);
130
+
131
+ }