oep-client-python 0.0.3__py3-none-any.whl → 0.0.4__py3-none-any.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.
- oep_client/__init__.py +1 -1
- oep_client/__main__.py +68 -3
- oep_client/fake_serial.py +4 -2
- {oep_client_python-0.0.3.dist-info → oep_client_python-0.0.4.dist-info}/METADATA +1 -1
- {oep_client_python-0.0.3.dist-info → oep_client_python-0.0.4.dist-info}/RECORD +8 -8
- {oep_client_python-0.0.3.dist-info → oep_client_python-0.0.4.dist-info}/WHEEL +0 -0
- {oep_client_python-0.0.3.dist-info → oep_client_python-0.0.4.dist-info}/entry_points.txt +0 -0
- {oep_client_python-0.0.3.dist-info → oep_client_python-0.0.4.dist-info}/licenses/LICENSE +0 -0
oep_client/__init__.py
CHANGED
oep_client/__main__.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
oep config show <probe>
|
|
5
5
|
oep config slot <probe> --name x035 --wire rvswd --pins 2,54 --attach at-boot --retry 1 --mechanism dmseq
|
|
6
6
|
oep config bind <probe> --port 1 --mode last-reset --stream slot:x035
|
|
7
|
+
oep config plan <probe> oep.fixture.uart#2 rx=48 tx=49 (the fn's whole plan; fn number or name#instance)
|
|
7
8
|
oep config remove <probe> bind 1 oep config save <probe> oep config erase <probe>
|
|
8
9
|
|
|
9
10
|
<probe>: a serial port, tcp://HOST:PORT or usb[:VID:PID[:SERIAL]]. A change takes the lock (owner "oep config") and
|
|
@@ -58,7 +59,7 @@ def _config_parser(sub) -> None:
|
|
|
58
59
|
slot.add_argument("probe")
|
|
59
60
|
slot.add_argument("--slot", type=int, default=0, help="the slot number (default 0)")
|
|
60
61
|
slot.add_argument("--name", required=True, help="1-32 of a-z 0-9 - _ (the oep://<probe>/<name> address)")
|
|
61
|
-
slot.add_argument("--wire",
|
|
62
|
+
slot.add_argument("--wire", help="rvswd or swio (or an fn); default: the probe's only wire")
|
|
62
63
|
slot.add_argument("--pins", help="swdio,swclk (one pin on swio); default: the wire's only pin set")
|
|
63
64
|
slot.add_argument("--attach", choices=sorted(config.ATTACH), default="host")
|
|
64
65
|
slot.add_argument("--retry", type=int, default=0, help="at-boot: try again every N s while absent (0: never)")
|
|
@@ -72,6 +73,21 @@ def _config_parser(sub) -> None:
|
|
|
72
73
|
bind.add_argument("--stream", action="append", required=True, help="slot:NAME, slot:N or uart:FN (repeatable)")
|
|
73
74
|
bind.add_argument("--select", type=int, default=0, help="manual: the stream it carries (index in --stream)")
|
|
74
75
|
bind.add_argument("--save", action="store_true")
|
|
76
|
+
plan = cs.add_parser("plan", help="the pins an interface keeps (its whole plan, kept as a setting)")
|
|
77
|
+
plan.add_argument("probe")
|
|
78
|
+
plan.add_argument("fn", help="an fn, or an interface name with #k for its k-th instance (1 = the first)")
|
|
79
|
+
plan.add_argument("roles", nargs="+", help="ROLE=CHANNEL, ROLE a number or the interface's role name (rx, tx, line...)")
|
|
80
|
+
plan.add_argument("--save", action="store_true")
|
|
81
|
+
label = cs.add_parser("label", help="name a channel (shown in oep.core's describe)")
|
|
82
|
+
label.add_argument("probe")
|
|
83
|
+
label.add_argument("channel", type=int)
|
|
84
|
+
label.add_argument("text")
|
|
85
|
+
label.add_argument("--save", action="store_true")
|
|
86
|
+
idle = cs.add_parser("idle", help="the state of a free pin")
|
|
87
|
+
idle.add_argument("probe")
|
|
88
|
+
idle.add_argument("channel", type=int)
|
|
89
|
+
idle.add_argument("mode", choices=sorted(config.IDLE))
|
|
90
|
+
idle.add_argument("--save", action="store_true")
|
|
75
91
|
rm = cs.add_parser("remove", help="remove one item: slot N, bind PORT, plan FN, label CH, idle CH")
|
|
76
92
|
rm.add_argument("probe")
|
|
77
93
|
rm.add_argument("kind", choices=["slot", "bind", "plan", "label", "idle"])
|
|
@@ -95,8 +111,40 @@ def _pins(hst, fn: int, text: str | None, wire: str) -> tuple[int, int]:
|
|
|
95
111
|
return groups[0]
|
|
96
112
|
|
|
97
113
|
|
|
98
|
-
def
|
|
99
|
-
|
|
114
|
+
def _plan_fn(hst, spec: str) -> tuple[int, dict[str, int]]:
|
|
115
|
+
"""fn and its role names (from the registry) for `spec`: an fn number, or name[#k] (k-th instance, 1-based)."""
|
|
116
|
+
from . import registry as reg
|
|
117
|
+
if spec.isdigit():
|
|
118
|
+
fn = int(spec)
|
|
119
|
+
name = next((e.name for e in core.list_entries(hst) if e.fn == fn), "")
|
|
120
|
+
else:
|
|
121
|
+
name, _, k = spec.partition("#")
|
|
122
|
+
fns = core.find_all(hst, name)
|
|
123
|
+
if not fns:
|
|
124
|
+
raise SystemExit(f"the probe offers no {name}")
|
|
125
|
+
index = int(k) - 1 if k else 0
|
|
126
|
+
if not 0 <= index < len(fns):
|
|
127
|
+
raise SystemExit(f"{name}: {len(fns)} instance(s), fns {fns}")
|
|
128
|
+
fn = fns[index]
|
|
129
|
+
iface = reg.INTERFACES.get(name)
|
|
130
|
+
roles = dict(iface.enum.get("role", {})) if iface else {}
|
|
131
|
+
return fn, roles
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _wire_fn(hst, wire: str | None) -> int:
|
|
135
|
+
if wire is None:
|
|
136
|
+
wires = [e for e in core.list_entries(hst, "oep.wire") if e.name in ("oep.wire.rvswd", "oep.wire.swio")]
|
|
137
|
+
if len(wires) != 1:
|
|
138
|
+
raise SystemExit("this probe has " + (", ".join(f"{e.name} (fn {e.fn})" for e in wires) or "no RISC-V wire")
|
|
139
|
+
+ ": name one with --wire")
|
|
140
|
+
return wires[0].fn
|
|
141
|
+
name = wire if wire.startswith("oep.") else f"oep.wire.{wire}"
|
|
142
|
+
if wire.isdigit():
|
|
143
|
+
return int(wire)
|
|
144
|
+
try:
|
|
145
|
+
return core.find(hst, name)
|
|
146
|
+
except LookupError:
|
|
147
|
+
raise SystemExit(f"this probe does not offer {name}") from None
|
|
100
148
|
|
|
101
149
|
|
|
102
150
|
def _stream(spec: str, slots: dict[str, int]) -> tuple[str, int]:
|
|
@@ -129,6 +177,7 @@ def _config(args) -> int:
|
|
|
129
177
|
return _show(hst, cfg, args.json)
|
|
130
178
|
if args.action == "slot":
|
|
131
179
|
fn = _wire_fn(hst, args.wire)
|
|
180
|
+
args.wire = args.wire or str(fn)
|
|
132
181
|
lock = None
|
|
133
182
|
if args.lock:
|
|
134
183
|
mask, _, value = args.lock.partition(":")
|
|
@@ -140,6 +189,22 @@ def _config(args) -> int:
|
|
|
140
189
|
slots = {it.name: it.slot for it in cfg.items() if isinstance(it, config.Slot)}
|
|
141
190
|
it = config.Bind(args.port, args.mode, [_stream(s, slots) for s in args.stream], args.select)
|
|
142
191
|
_change(hst, cfg, [it], args.save)
|
|
192
|
+
elif args.action == "plan":
|
|
193
|
+
fn, roles = _plan_fn(hst, args.fn)
|
|
194
|
+
items = []
|
|
195
|
+
for spec in args.roles:
|
|
196
|
+
role, _, ch = spec.partition("=")
|
|
197
|
+
if not ch:
|
|
198
|
+
raise SystemExit(f"{spec}: want ROLE=CHANNEL")
|
|
199
|
+
number = int(role) if role.isdigit() else roles.get(role.lower())
|
|
200
|
+
if number is None:
|
|
201
|
+
raise SystemExit(f"{role}: not a role of fn {fn} (roles: {', '.join(sorted(roles)) or 'numbers only'})")
|
|
202
|
+
items.append(config.Plan(fn, number, int(ch, 0)))
|
|
203
|
+
_change(hst, cfg, items, args.save)
|
|
204
|
+
elif args.action == "label":
|
|
205
|
+
_change(hst, cfg, [config.Label(args.channel, args.text)], args.save)
|
|
206
|
+
elif args.action == "idle":
|
|
207
|
+
_change(hst, cfg, [config.Idle(args.channel, args.mode)], args.save)
|
|
143
208
|
elif args.action == "remove":
|
|
144
209
|
_change(hst, cfg, [config.remove(args.kind, args.key)], args.save)
|
|
145
210
|
else:
|
oep_client/fake_serial.py
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
- a candidate runs from a 0x00 to the next 0x00; if it decodes and its CRC matches it is a request, otherwise it
|
|
7
7
|
(with its leading 0x00) is raw bytes, and the closing 0x00 starts the next candidate; bytes outside a candidate
|
|
8
|
-
are raw at once; a candidate that stops for 200 ms (`tick`) is raw;
|
|
8
|
+
are raw at once; a candidate that stops for 200 ms (`tick`) is raw; a candidate that is only its 0x00 (0x00 0x00,
|
|
9
|
+
or the closing 0x00 of a frame when nothing follows) is nothing
|
|
9
10
|
- raw bytes go to the endpoint's bind for this port (`Endpoint.port_input`)
|
|
10
11
|
- answers go out as 0x00 <COBS> 0x00, ahead of raw chunks (`Endpoint.port_output`); one writer, never a raw byte
|
|
11
12
|
inside a frame
|
|
@@ -80,7 +81,8 @@ class FakeSerialPort:
|
|
|
80
81
|
def _gap(self, now: int) -> None:
|
|
81
82
|
if self.cand is not None and now - self.last_ms >= GAP_MS:
|
|
82
83
|
raw, self.cand = bytes(self.cand), None
|
|
83
|
-
|
|
84
|
+
if len(raw) > 1: # only its 0x00: a delimiter (a frame's closing 0x00), not raw
|
|
85
|
+
self._raw(bytearray(raw))
|
|
84
86
|
|
|
85
87
|
def _raw(self, raw: bytearray) -> None:
|
|
86
88
|
if raw:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: oep-client-python
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Open Embedded Probe (OEP) v1 host: serial / USB / TCP transports, the session rules, the standard interfaces, and a fake probe
|
|
5
5
|
Project-URL: Homepage, https://github.com/Open-Embedded-Probe/oep-client-python
|
|
6
6
|
Project-URL: Repository, https://github.com/Open-Embedded-Probe/oep-client-python
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
oep_client/__init__.py,sha256=
|
|
2
|
-
oep_client/__main__.py,sha256=
|
|
1
|
+
oep_client/__init__.py,sha256=F5if_qpFrTQuYzjKnNr2nZ1QRiCVH8b_c43b3GQbvmQ,163
|
|
2
|
+
oep_client/__main__.py,sha256=Ta7D7jhtg5IhFWuI3KTikbDNYazh9QKCH3FtMMnDMjg,14143
|
|
3
3
|
oep_client/arm.py,sha256=JLyUhLSPcmsk73schZcaJYoOKuHzrvnU8kPmfrEvVuo,12331
|
|
4
4
|
oep_client/capture.py,sha256=RZgDnWqr8Aqy49U7PqQpnKIQEL18djVuDJFydxrmv-c,17996
|
|
5
5
|
oep_client/catalog.py,sha256=EqAQnSgHFxGbCO2GQ_Ee-uheJKbBBUUpL1-0qHfNMXU,6574
|
|
@@ -13,7 +13,7 @@ oep_client/dump.py,sha256=GAnmu2abuDmGmbWcbbEfC3EUuPp5Hady9vQVNcQ-724,6743
|
|
|
13
13
|
oep_client/endpoint.py,sha256=70eFSDQuu-UffiuooF74e9kS33dhE4DyJeC7yllRR7Y,72248
|
|
14
14
|
oep_client/esp32_targets.py,sha256=b8tNH-nb2KC-XgNfWg5l3TO0cyhZOF-gJajaVxNVSGQ,4988
|
|
15
15
|
oep_client/fake.py,sha256=UzpB-A42Ma2QqJj0l-JmwCJkMn6DPVHHN77fcemT59U,13104
|
|
16
|
-
oep_client/fake_serial.py,sha256=
|
|
16
|
+
oep_client/fake_serial.py,sha256=uKl0UNcifhdeykQtm8gnRRhqV7TT4vPwBFuBhbf-9BI,4504
|
|
17
17
|
oep_client/fake_serve.py,sha256=dIuYxhlAixSb8_OQ4b4UXTkWqW5Tpf_F9uuqMNWn0F4,14612
|
|
18
18
|
oep_client/fixture.py,sha256=653hCD-Iz0Lfs8dT4Hdg3QyubbbOGs1_xjq_3nb8foU,5564
|
|
19
19
|
oep_client/frames.py,sha256=xjgjnXmXUqNJZ5m0h91r4Cy48WoVK1mEMW4gRg-mlMI,3991
|
|
@@ -29,8 +29,8 @@ oep_client/rp2350.py,sha256=7OMyj270k3AY1e3-ljicPwOjf9jOlokbT6QNkA0b0yY,4227
|
|
|
29
29
|
oep_client/target.py,sha256=R8BvYfFfYNhZF0MysJkNb8b69YgBlmeGXNX8ReZIe5k,1068
|
|
30
30
|
oep_client/uiapduino.py,sha256=IEPG3LbZPksi8g3wmAf6T0CRWSfYKW1_qrH_GBVQdxY,6090
|
|
31
31
|
oep_client/usb_stream.py,sha256=1nvuRNLQkpp8054eG-JutBKh9y0F_8PHGDAfG0ZSbaY,8819
|
|
32
|
-
oep_client_python-0.0.
|
|
33
|
-
oep_client_python-0.0.
|
|
34
|
-
oep_client_python-0.0.
|
|
35
|
-
oep_client_python-0.0.
|
|
36
|
-
oep_client_python-0.0.
|
|
32
|
+
oep_client_python-0.0.4.dist-info/METADATA,sha256=7HtJZthSGhDIG5Ce8dvLIvdwtQpN5AYve_5YhSk8l5M,7359
|
|
33
|
+
oep_client_python-0.0.4.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
34
|
+
oep_client_python-0.0.4.dist-info/entry_points.txt,sha256=h6_8QX89Ww1ogALEGG5g4kspT3IOV6O51lwKqf5BWco,49
|
|
35
|
+
oep_client_python-0.0.4.dist-info/licenses/LICENSE,sha256=ntlalztb3L1OaNAxmQdHlubu5fVhjMc9oRZi3PeQhXg,1076
|
|
36
|
+
oep_client_python-0.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|