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.
Files changed (157) 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 +71 -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_amd64.pyd +0 -0
  30. pyxcp/cpp_ext/cpp_ext.cp311-win_amd64.pyd +0 -0
  31. pyxcp/cpp_ext/cpp_ext.cp312-win_amd64.pyd +0 -0
  32. pyxcp/cpp_ext/cpp_ext.cp313-win_amd64.pyd +0 -0
  33. pyxcp/cpp_ext/daqlist.hpp +374 -0
  34. pyxcp/cpp_ext/event.hpp +67 -0
  35. pyxcp/cpp_ext/extension_wrapper.cpp +131 -0
  36. pyxcp/cpp_ext/framing.hpp +360 -0
  37. pyxcp/cpp_ext/helper.hpp +280 -0
  38. pyxcp/cpp_ext/mcobject.hpp +248 -0
  39. pyxcp/cpp_ext/sxi_framing.hpp +332 -0
  40. pyxcp/cpp_ext/tsqueue.hpp +46 -0
  41. pyxcp/daq_stim/__init__.py +291 -0
  42. pyxcp/daq_stim/optimize/__init__.py +67 -0
  43. pyxcp/daq_stim/optimize/binpacking.py +41 -0
  44. pyxcp/daq_stim/scheduler.cpp +62 -0
  45. pyxcp/daq_stim/scheduler.hpp +75 -0
  46. pyxcp/daq_stim/stim.cp310-win_amd64.pyd +0 -0
  47. pyxcp/daq_stim/stim.cp311-win_amd64.pyd +0 -0
  48. pyxcp/daq_stim/stim.cp312-win_amd64.pyd +0 -0
  49. pyxcp/daq_stim/stim.cp313-win_amd64.pyd +0 -0
  50. pyxcp/daq_stim/stim.cpp +13 -0
  51. pyxcp/daq_stim/stim.hpp +604 -0
  52. pyxcp/daq_stim/stim_wrapper.cpp +50 -0
  53. pyxcp/dllif.py +100 -0
  54. pyxcp/errormatrix.py +878 -0
  55. pyxcp/examples/conf_can.toml +19 -0
  56. pyxcp/examples/conf_can_user.toml +16 -0
  57. pyxcp/examples/conf_can_vector.json +11 -0
  58. pyxcp/examples/conf_can_vector.toml +11 -0
  59. pyxcp/examples/conf_eth.toml +9 -0
  60. pyxcp/examples/conf_nixnet.json +20 -0
  61. pyxcp/examples/conf_socket_can.toml +12 -0
  62. pyxcp/examples/run_daq.py +165 -0
  63. pyxcp/examples/xcp_policy.py +60 -0
  64. pyxcp/examples/xcp_read_benchmark.py +38 -0
  65. pyxcp/examples/xcp_skel.py +48 -0
  66. pyxcp/examples/xcp_unlock.py +36 -0
  67. pyxcp/examples/xcp_user_supplied_driver.py +43 -0
  68. pyxcp/examples/xcphello.py +65 -0
  69. pyxcp/examples/xcphello_recorder.py +107 -0
  70. pyxcp/master/__init__.py +10 -0
  71. pyxcp/master/errorhandler.py +677 -0
  72. pyxcp/master/master.py +2641 -0
  73. pyxcp/py.typed +0 -0
  74. pyxcp/recorder/.idea/.gitignore +8 -0
  75. pyxcp/recorder/.idea/misc.xml +4 -0
  76. pyxcp/recorder/.idea/modules.xml +8 -0
  77. pyxcp/recorder/.idea/recorder.iml +6 -0
  78. pyxcp/recorder/.idea/sonarlint/issuestore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +7 -0
  79. pyxcp/recorder/.idea/sonarlint/issuestore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  80. pyxcp/recorder/.idea/sonarlint/issuestore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  81. pyxcp/recorder/.idea/sonarlint/issuestore/index.pb +7 -0
  82. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +0 -0
  83. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  84. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  85. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/index.pb +7 -0
  86. pyxcp/recorder/.idea/vcs.xml +10 -0
  87. pyxcp/recorder/__init__.py +96 -0
  88. pyxcp/recorder/build_clang.cmd +1 -0
  89. pyxcp/recorder/build_clang.sh +2 -0
  90. pyxcp/recorder/build_gcc.cmd +1 -0
  91. pyxcp/recorder/build_gcc.sh +2 -0
  92. pyxcp/recorder/build_gcc_arm.sh +2 -0
  93. pyxcp/recorder/converter/__init__.py +444 -0
  94. pyxcp/recorder/lz4.c +2829 -0
  95. pyxcp/recorder/lz4.h +879 -0
  96. pyxcp/recorder/lz4hc.c +2041 -0
  97. pyxcp/recorder/lz4hc.h +413 -0
  98. pyxcp/recorder/mio.hpp +1714 -0
  99. pyxcp/recorder/reader.hpp +138 -0
  100. pyxcp/recorder/reco.py +278 -0
  101. pyxcp/recorder/recorder.rst +0 -0
  102. pyxcp/recorder/rekorder.cp310-win_amd64.pyd +0 -0
  103. pyxcp/recorder/rekorder.cp311-win_amd64.pyd +0 -0
  104. pyxcp/recorder/rekorder.cp312-win_amd64.pyd +0 -0
  105. pyxcp/recorder/rekorder.cp313-win_amd64.pyd +0 -0
  106. pyxcp/recorder/rekorder.cpp +59 -0
  107. pyxcp/recorder/rekorder.hpp +274 -0
  108. pyxcp/recorder/setup.py +41 -0
  109. pyxcp/recorder/test_reko.py +34 -0
  110. pyxcp/recorder/unfolder.hpp +1354 -0
  111. pyxcp/recorder/wrap.cpp +184 -0
  112. pyxcp/recorder/writer.hpp +302 -0
  113. pyxcp/scripts/__init__.py +0 -0
  114. pyxcp/scripts/pyxcp_probe_can_drivers.py +20 -0
  115. pyxcp/scripts/xcp_examples.py +64 -0
  116. pyxcp/scripts/xcp_fetch_a2l.py +40 -0
  117. pyxcp/scripts/xcp_id_scanner.py +18 -0
  118. pyxcp/scripts/xcp_info.py +159 -0
  119. pyxcp/scripts/xcp_profile.py +26 -0
  120. pyxcp/scripts/xmraw_converter.py +31 -0
  121. pyxcp/stim/__init__.py +0 -0
  122. pyxcp/tests/test_asam_types.py +24 -0
  123. pyxcp/tests/test_binpacking.py +186 -0
  124. pyxcp/tests/test_can.py +1324 -0
  125. pyxcp/tests/test_checksum.py +95 -0
  126. pyxcp/tests/test_daq.py +193 -0
  127. pyxcp/tests/test_daq_opt.py +426 -0
  128. pyxcp/tests/test_frame_padding.py +156 -0
  129. pyxcp/tests/test_framing.py +262 -0
  130. pyxcp/tests/test_master.py +2116 -0
  131. pyxcp/tests/test_transport.py +177 -0
  132. pyxcp/tests/test_utils.py +30 -0
  133. pyxcp/timing.py +60 -0
  134. pyxcp/transport/__init__.py +13 -0
  135. pyxcp/transport/base.py +484 -0
  136. pyxcp/transport/base_transport.hpp +0 -0
  137. pyxcp/transport/can.py +660 -0
  138. pyxcp/transport/eth.py +254 -0
  139. pyxcp/transport/hdf5_policy.py +129 -0
  140. pyxcp/transport/sxi.py +209 -0
  141. pyxcp/transport/transport_ext.cp310-win_amd64.pyd +0 -0
  142. pyxcp/transport/transport_ext.cp311-win_amd64.pyd +0 -0
  143. pyxcp/transport/transport_ext.cp312-win_amd64.pyd +0 -0
  144. pyxcp/transport/transport_ext.cp313-win_amd64.pyd +0 -0
  145. pyxcp/transport/transport_ext.hpp +214 -0
  146. pyxcp/transport/transport_wrapper.cpp +249 -0
  147. pyxcp/transport/usb_transport.py +229 -0
  148. pyxcp/types.py +987 -0
  149. pyxcp/utils/__init__.py +127 -0
  150. pyxcp/utils/cli.py +78 -0
  151. pyxcp/vector/__init__.py +0 -0
  152. pyxcp/vector/map.py +82 -0
  153. pyxcp-0.25.4.dist-info/METADATA +341 -0
  154. pyxcp-0.25.4.dist-info/RECORD +157 -0
  155. pyxcp-0.25.4.dist-info/WHEEL +4 -0
  156. pyxcp-0.25.4.dist-info/entry_points.txt +9 -0
  157. pyxcp-0.25.4.dist-info/licenses/LICENSE +165 -0
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env python
2
+
3
+ """XCP info/exploration tool."""
4
+
5
+ import argparse
6
+ from pprint import pprint
7
+
8
+ from pyxcp.cmdline import ArgumentParser
9
+ from pyxcp.types import TryCommandResult
10
+
11
+
12
+ def getPagInfo(x):
13
+ result = {}
14
+ if x.slaveProperties.supportsCalpag:
15
+ status, pag = x.try_command(x.getPagProcessorInfo)
16
+ if status == TryCommandResult.OK:
17
+ result["maxSegments"] = pag.maxSegments
18
+ result["pagProperties"] = {}
19
+ result["pagProperties"]["freezeSupported"] = pag.pagProperties.freezeSupported
20
+ result["segments"] = []
21
+ for i in range(pag.maxSegments):
22
+ segment = {}
23
+ status, std_info = x.try_command(x.getSegmentInfo, 0x01, i, 0, 0)
24
+ if status == TryCommandResult.OK:
25
+ segment["maxPages"] = std_info.maxPages
26
+ segment["addressExtension"] = std_info.addressExtension
27
+ segment["maxMapping"] = std_info.maxMapping
28
+ segment["compressionMethod"] = std_info.compressionMethod
29
+ segment["encryptionMethod"] = std_info.encryptionMethod
30
+
31
+ status, seg_address = x.try_command(x.getSegmentInfo, 0x00, i, 0, 0)
32
+ status, seg_length = x.try_command(x.getSegmentInfo, 0x00, i, 1, 0)
33
+
34
+ segment["address"] = seg_address.basicInfo
35
+ segment["length"] = seg_length.basicInfo
36
+
37
+ result["segments"].append(segment)
38
+
39
+ status, pgi = x.try_command(x.getPageInfo, i, 0)
40
+ # print("PAGE:", pgi)
41
+ # for j in range(si.maxPages):
42
+ # pgi = x.getPageInfo(i, j)
43
+ # print(pgi)
44
+ else:
45
+ break
46
+ return result
47
+
48
+
49
+ def main():
50
+ parser = argparse.ArgumentParser(description="XCP info/exploration tool.")
51
+ parser.add_argument("--no-daq", action="store_true", help="Do not query DAQ information.")
52
+ parser.add_argument("--no-pag", action="store_true", help="Do not query PAG information.")
53
+ parser.add_argument("--no-pgm", action="store_true", help="Do not query PGM information.")
54
+ parser.add_argument("--no-ids", action="store_true", help="Do not scan implemented IDs.")
55
+ ap = ArgumentParser(parser)
56
+
57
+ with ap.run() as x:
58
+ x.connect()
59
+ if x.slaveProperties.optionalCommMode:
60
+ x.try_command(x.getCommModeInfo, extra_msg="availability signaled by CONNECT, this may be a slave configuration error.")
61
+ print("\nSlave Properties:")
62
+ print("=================")
63
+ pprint(x.slaveProperties)
64
+
65
+ if not ap.args.no_ids:
66
+ result = x.id_scanner()
67
+ print("\n")
68
+ print("Implemented IDs:")
69
+ print("================")
70
+ for key, value in result.items():
71
+ print(f"{key}: {value}", end="\n\n")
72
+
73
+ cps = x.getCurrentProtectionStatus()
74
+ print("\nProtection Status")
75
+ print("=================")
76
+ for k, v in cps.items():
77
+ print(f" {k:6s}: {v}")
78
+ x.cond_unlock()
79
+
80
+ if not ap.args.no_daq:
81
+ print("\nDAQ Info:")
82
+ print("=========")
83
+ if x.slaveProperties.supportsDaq:
84
+ daq_info = x.getDaqInfo()
85
+ pprint(daq_info)
86
+
87
+ daq_pro = daq_info["processor"]
88
+ daq_properties = daq_pro["properties"]
89
+ if x.slaveProperties.transport_layer == "CAN":
90
+ print("")
91
+ if daq_properties["pidOffSupported"]:
92
+ print("*** pidOffSupported -- i.e. one CAN-ID per DAQ-list.")
93
+ else:
94
+ print("*** NO support for PID_OFF")
95
+ num_predefined = daq_pro["minDaq"]
96
+ print("\nPredefined DAQ-Lists")
97
+ print("====================")
98
+ if num_predefined > 0:
99
+ print(f"There are {num_predefined} predefined DAQ-lists")
100
+ for idx in range(num_predefined):
101
+ print(f"DAQ-List #{idx}\n____________\n")
102
+ status, dm = x.try_command(x.getDaqListMode, idx)
103
+ if status == TryCommandResult.OK:
104
+ print(dm)
105
+ status, di = x.try_command(x.getDaqListInfo, idx)
106
+ if status == TryCommandResult.OK:
107
+ print(di)
108
+ else:
109
+ print("*** NO Predefined DAQ-Lists")
110
+ else:
111
+ print("*** DAQ IS NOT SUPPORTED .")
112
+
113
+ if not ap.args.no_pag:
114
+ print("\nPAG Info:")
115
+ print("=========")
116
+ if x.slaveProperties.supportsCalpag:
117
+ pgi = getPagInfo(x)
118
+ pprint(pgi)
119
+ else:
120
+ print("*** PAGING IS NOT SUPPORTED.")
121
+
122
+ if not ap.args.no_pgm:
123
+ print("\nPGM Info:")
124
+ print("=========")
125
+ if x.slaveProperties.supportsPgm:
126
+ status, pgm = x.try_command(x.getPgmProcessorInfo)
127
+ if status == TryCommandResult.OK:
128
+ print(pgm)
129
+ else:
130
+ print("*** FLASH PROGRAMMING IS NOT SUPPORTED.")
131
+
132
+ if x.slaveProperties.transport_layer == "CAN":
133
+ print("\nTransport-Layer CAN:")
134
+ print("====================")
135
+ status, res = x.try_command(x.getSlaveID, 0)
136
+ if status == TryCommandResult.OK:
137
+ print("CAN identifier for CMD/STIM:\n", res)
138
+ else:
139
+ pass
140
+ # print("*** GET_SLAVE_ID() IS NOT SUPPORTED.") # no response from bc address ???
141
+
142
+ print("\nPer DAQ-list Identifier")
143
+ print("-----------------------")
144
+ daq_id = 0
145
+ while True:
146
+ status, res = x.try_command(x.getDaqId, daq_id)
147
+ if status == TryCommandResult.OK:
148
+ print(f"DAQ-list #{daq_id}:", res)
149
+ daq_id += 1
150
+ else:
151
+ break
152
+ if daq_id == 0:
153
+ print("N/A")
154
+ x.disconnect()
155
+ print("\nDone.")
156
+
157
+
158
+ if __name__ == "__main__":
159
+ main()
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env python
2
+ """Create / convert pyxcp profiles (configurations)."""
3
+
4
+ import sys
5
+
6
+ from pyxcp.cmdline import ArgumentParser
7
+
8
+
9
+ def main():
10
+ if len(sys.argv) == 1:
11
+ sys.argv.append("profile")
12
+ elif len(sys.argv) >= 2 and sys.argv[1] != "profile":
13
+ sys.argv.insert(1, "profile")
14
+
15
+ ap = ArgumentParser(description="Create / convert pyxcp profiles (configurations).")
16
+
17
+ try:
18
+ with ap.run() as x: # noqa: F841
19
+ pass
20
+ except FileNotFoundError as e:
21
+ print(f"Error: {e}")
22
+ sys.exit(1)
23
+
24
+
25
+ if __name__ == "__main__":
26
+ main()
@@ -0,0 +1,31 @@
1
+ import argparse
2
+
3
+ from pyxcp.recorder.converter import convert_xmraw
4
+
5
+
6
+ parser = argparse.ArgumentParser(description="Convert .xmraw files.")
7
+
8
+ parser.add_argument(
9
+ "target_type",
10
+ help="target file type",
11
+ choices=[
12
+ "arrow",
13
+ "csv",
14
+ "excel",
15
+ "hdf5",
16
+ "mdf",
17
+ "sqlite3",
18
+ ],
19
+ )
20
+
21
+
22
+ def main():
23
+ parser.add_argument("xmraw_file", help=".xmraw file")
24
+ parser.add_argument("-t", "--taget-file-name", dest="target_file_name", help="target file name")
25
+ args = parser.parse_args()
26
+
27
+ convert_xmraw(args.target_type, args.xmraw_file, args.target_file_name)
28
+
29
+
30
+ if __name__ == "__main__":
31
+ main()
pyxcp/stim/__init__.py ADDED
File without changes
@@ -0,0 +1,24 @@
1
+ import pytest
2
+
3
+ from pyxcp.asam import types
4
+
5
+
6
+ def testEncodeUint32_0():
7
+ assert types.A_Uint32("<").encode(3415750566) == b"\xa67\x98\xcb"
8
+
9
+
10
+ def testDecodeUint32_0():
11
+ assert types.A_Uint32("<").decode((0xA6, 0x37, 0x98, 0xCB)) == 3415750566
12
+
13
+
14
+ def testLittleEndian():
15
+ assert isinstance(types.AsamBaseType(types.INTEL), types.AsamBaseType)
16
+
17
+
18
+ def testBigEndian():
19
+ assert isinstance(types.AsamBaseType(types.MOTOROLA), types.AsamBaseType)
20
+
21
+
22
+ def testInvalidByteOrderRaisesTypeError():
23
+ with pytest.raises(ValueError):
24
+ types.AsamBaseType("#")
@@ -0,0 +1,186 @@
1
+ import pytest
2
+
3
+ from pyxcp.daq_stim.optimize import McObject, make_continuous_blocks
4
+ from pyxcp.daq_stim.optimize.binpacking import Bin, first_fit_decreasing
5
+
6
+
7
+ # McObject(name="", address=section.address, ext=section.ext, length=section.length, components=[section])
8
+ # McObject(name: str, address: int, ext: int, length: int, data_type: str = '', components: list[pyxcp.cpp_ext.cpp_ext.McObject] = [])
9
+ @pytest.fixture
10
+ def blocks():
11
+ return [
12
+ McObject(name="", address=0x000E10BA, ext=0, length=2),
13
+ McObject(name="", address=0x000E10BE, ext=0, length=2),
14
+ McObject(name="", address=0x000E41F4, ext=0, length=4),
15
+ McObject(name="", address=0x000E51FC, ext=0, length=4),
16
+ McObject(name="", address=0x00125288, ext=0, length=4),
17
+ McObject(name="", address=0x00125294, ext=0, length=4),
18
+ McObject(name="", address=0x001252A1, ext=0, length=1),
19
+ McObject(name="", address=0x001252A4, ext=0, length=4),
20
+ McObject(name="", address=0x00125438, ext=0, length=3),
21
+ McObject(name="", address=0x0012543C, ext=0, length=1),
22
+ ]
23
+
24
+
25
+ def test_pack_to_single_bin(blocks):
26
+ BIN_SIZE = 253
27
+ bins = first_fit_decreasing(items=blocks, bin_size=BIN_SIZE)
28
+
29
+ assert len(bins) == 1
30
+ bin0 = bins[0]
31
+ assert bin0.residual_capacity == BIN_SIZE - 29
32
+ assert bin0.entries == [
33
+ McObject(name="", address=0x000E41F4, ext=0, length=4),
34
+ McObject(name="", address=0x000E51FC, ext=0, length=4),
35
+ McObject(name="", address=0x00125288, ext=0, length=4),
36
+ McObject(name="", address=0x00125294, ext=0, length=4),
37
+ McObject(name="", address=0x001252A4, ext=0, length=4),
38
+ McObject(name="", address=0x00125438, ext=0, length=3),
39
+ McObject(name="", address=0x000E10BA, ext=0, length=2),
40
+ McObject(name="", address=0x000E10BE, ext=0, length=2),
41
+ McObject(name="", address=0x001252A1, ext=0, length=1),
42
+ McObject(name="", address=0x0012543C, ext=0, length=1),
43
+ ]
44
+
45
+
46
+ def test_pack_empty_block_set():
47
+ BIN_SIZE = 253
48
+ bins = first_fit_decreasing(items=[], bin_size=BIN_SIZE)
49
+ assert bins == [Bin(size=BIN_SIZE)]
50
+
51
+
52
+ def test_pack_to_multiple_bins1(blocks):
53
+ BIN_SIZE = 6
54
+ bins = first_fit_decreasing(items=blocks, bin_size=BIN_SIZE)
55
+ assert len(bins) == 6
56
+ bin0, bin1, bin2, bin3, bin4, bin5 = bins
57
+ assert bin0.residual_capacity == 0
58
+ assert bin0.entries == [
59
+ McObject(name="", address=0x000E41F4, ext=0, length=4),
60
+ McObject(name="", address=0x000E10BA, ext=0, length=2),
61
+ ]
62
+ assert bin1.residual_capacity == 0
63
+ assert bin1.entries == [
64
+ McObject(name="", address=0x000E51FC, ext=0, length=4),
65
+ McObject(name="", address=0x000E10BE, ext=0, length=2),
66
+ ]
67
+ assert bin2.residual_capacity == 0
68
+ assert bin2.entries == [
69
+ McObject(name="", address=0x00125288, ext=0, length=4),
70
+ McObject(name="", address=0x001252A1, ext=0, length=1),
71
+ McObject(name="", address=0x0012543C, ext=0, length=1),
72
+ ]
73
+ assert bin3.residual_capacity == 2
74
+ assert bin3.entries == [McObject(name="", address=0x00125294, ext=0, length=4)]
75
+ assert bin4.residual_capacity == 2
76
+ assert bin4.entries == [McObject(name="", address=0x001252A4, ext=0, length=4)]
77
+ assert bin5.residual_capacity == 3
78
+ assert bin5.entries == [McObject(name="", address=0x00125438, ext=0, length=3)]
79
+
80
+
81
+ def test_binpacking_raises(blocks):
82
+ BIN_SIZE = 7
83
+ with pytest.raises(ValueError):
84
+ first_fit_decreasing(items=[McObject(name="", address=0x1000, ext=0, length=32)], bin_size=BIN_SIZE)
85
+
86
+
87
+ def test_binpacking_works(blocks):
88
+ BIN_SIZE = 7
89
+ first_fit_decreasing(items=[McObject(name="", address=0x1000, ext=0, length=7)], bin_size=BIN_SIZE)
90
+
91
+
92
+ def test_make_continuous_blocks1():
93
+ BLOCKS = [
94
+ McObject(name="", address=0x000E0002, ext=0, length=2),
95
+ McObject(name="", address=0x000E0008, ext=23, length=4),
96
+ McObject(name="", address=0x000E0004, ext=0, length=4),
97
+ McObject(name="", address=0x000E000C, ext=23, length=4),
98
+ McObject(name="", address=0x000E0000, ext=0, length=2),
99
+ ]
100
+ bins = make_continuous_blocks(chunks=BLOCKS)
101
+ assert bins == [
102
+ McObject(
103
+ name="",
104
+ address=917504,
105
+ ext=0,
106
+ length=8,
107
+ components=[
108
+ McObject(name="", address=917504, ext=0, length=2, components=[]),
109
+ McObject(name="", address=917506, ext=0, length=2, components=[]),
110
+ McObject(name="", address=917508, ext=0, length=4, components=[]),
111
+ ],
112
+ ),
113
+ McObject(
114
+ name="",
115
+ address=917512,
116
+ ext=23,
117
+ length=8,
118
+ components=[
119
+ McObject(name="", address=917512, ext=23, length=4, components=[]),
120
+ McObject(name="", address=917516, ext=23, length=4, components=[]),
121
+ ],
122
+ ),
123
+ ]
124
+
125
+
126
+ def test_make_continuous_blocks2():
127
+ BLOCKS = [
128
+ McObject(name="", address=0x000E0002, ext=0, length=2),
129
+ McObject(name="", address=0x000E0008, ext=0, length=4),
130
+ McObject(name="", address=0x000E0004, ext=0, length=4),
131
+ McObject(name="", address=0x000E000C, ext=0, length=4),
132
+ McObject(name="", address=0x000E0000, ext=0, length=2),
133
+ ]
134
+ bins = make_continuous_blocks(chunks=BLOCKS)
135
+ assert bins == [
136
+ McObject(
137
+ name="",
138
+ address=917504,
139
+ ext=0,
140
+ length=16,
141
+ components=[
142
+ McObject(name="", address=917504, ext=0, length=2, components=[]),
143
+ McObject(name="", address=917506, ext=0, length=2, components=[]),
144
+ McObject(name="", address=917508, ext=0, length=4, components=[]),
145
+ McObject(name="", address=917512, ext=0, length=4, components=[]),
146
+ McObject(name="", address=917516, ext=0, length=4, components=[]),
147
+ ],
148
+ )
149
+ ]
150
+
151
+
152
+ def test_make_continuous_blocks3():
153
+ BLOCKS = [
154
+ McObject(name="", address=0x000E0002, ext=0x01, length=2),
155
+ McObject(name="", address=0x000E0008, ext=0x03, length=4),
156
+ McObject(name="", address=0x000E0004, ext=0x02, length=4),
157
+ McObject(name="", address=0x000E000C, ext=0x04, length=4),
158
+ McObject(name="", address=0x000E0000, ext=0x00, length=2),
159
+ ]
160
+ bins = make_continuous_blocks(chunks=BLOCKS)
161
+ assert bins == [
162
+ McObject(
163
+ name="", address=917504, ext=0, length=2, components=[McObject(name="", address=917504, ext=0, length=2, components=[])]
164
+ ),
165
+ McObject(
166
+ name="", address=917506, ext=1, length=2, components=[McObject(name="", address=917506, ext=1, length=2, components=[])]
167
+ ),
168
+ McObject(
169
+ name="", address=917508, ext=2, length=4, components=[McObject(name="", address=917508, ext=2, length=4, components=[])]
170
+ ),
171
+ McObject(
172
+ name="", address=917512, ext=3, length=4, components=[McObject(name="", address=917512, ext=3, length=4, components=[])]
173
+ ),
174
+ McObject(
175
+ name="", address=917516, ext=4, length=4, components=[McObject(name="", address=917516, ext=4, length=4, components=[])]
176
+ ),
177
+ ]
178
+
179
+
180
+ def test_mc_object_len_zero():
181
+ with pytest.raises(ValueError):
182
+ McObject(name="", address=0, ext=0, length=0)
183
+
184
+
185
+ def test_mc_object_ok():
186
+ McObject(name="", address=0, ext=0, length=1)