Skip to content

Commit dce7b12

Browse files
committed
Commands: exec context holds the selected core.
- CommandExecutionContext gets selected_core property, and inits it in attach_session(). - Changed all commands to use context.selected_core instead of the target's selected_core.
1 parent 036b375 commit dce7b12

File tree

5 files changed

+86
-70
lines changed

5 files changed

+86
-70
lines changed

pyocd/commands/base.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ def _convert_value(self, arg):
133133
offset = int(offset.strip(), base=0)
134134

135135
value = None
136-
if arg.lower() in self.context.target.core_registers.by_name:
137-
value = self.context.target.read_core_register(arg.lower())
136+
if arg.lower() in self.context.selected_core.core_registers.by_name:
137+
value = self.context.selected_core.read_core_register(arg.lower())
138138
self.context.writei("%s = 0x%08x", arg.lower(), value)
139139
else:
140140
subargs = arg.lower().split('.')
@@ -155,7 +155,8 @@ def _convert_value(self, arg):
155155
value = int(arg, base=0)
156156

157157
if deref:
158-
value = conversion.byte_list_to_u32le_list(self.context.target.read_memory_block8(value + offset, 4))[0]
158+
value = conversion.byte_list_to_u32le_list(
159+
self.context.selected_core.read_memory_block8(value + offset, 4))[0]
159160
self.context.writei("[%s,%d] = 0x%08x", arg, offset, value)
160161

161162
return value

pyocd/commands/commands.py

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ def execute(self):
114114

115115
class RegisterCommandBase(CommandBase):
116116
def dump_register_group(self, group_name):
117-
regs = natsort(self.context.target.core_registers.iter_matching(
117+
regs = natsort(self.context.selected_core.core_registers.iter_matching(
118118
lambda r: r.group == group_name), key=lambda r: r.name)
119-
reg_values = self.context.target.read_core_registers_raw(r.name for r in regs)
119+
reg_values = self.context.selected_core.read_core_registers_raw(r.name for r in regs)
120120

121121
col_printer = ColumnFormatter()
122122
for info, value in zip(regs, reg_values):
@@ -126,11 +126,11 @@ def dump_register_group(self, group_name):
126126
col_printer.write()
127127

128128
def dump_registers(self, show_all=False, show_group=None):
129-
if not self.context.target.is_halted():
129+
if not self.context.selected_core.is_halted():
130130
self.context.write("Core is not halted; cannot read core registers")
131131
return
132132

133-
all_groups = sorted(self.context.target.core_registers.groups)
133+
all_groups = sorted(self.context.selected_core.core_registers.groups)
134134
if show_all:
135135
groups_to_show = all_groups
136136
elif show_group:
@@ -147,7 +147,7 @@ def dump_registers(self, show_all=False, show_group=None):
147147
def _dump_peripheral_register(self, periph, reg, show_fields):
148148
size = reg.size or 32
149149
addr = periph.base_address + reg.address_offset
150-
value = self.context.target.read_memory(addr, size)
150+
value = self.context.selected_ap.read_memory(addr, size)
151151
value_str = format_hex_width(value, size)
152152
self.context.writei("%s.%s @ %08x = %s", periph.name, reg.name, addr, value_str)
153153

@@ -217,19 +217,19 @@ def execute(self):
217217
return
218218

219219
# Check register names first.
220-
if self.reg in self.context.target.core_registers.by_name:
221-
if not self.context.target.is_halted():
220+
if self.reg in self.context.selected_core.core_registers.by_name:
221+
if not self.context.selected_core.is_halted():
222222
self.context.write("Core is not halted; cannot read core registers")
223223
return
224224

225-
info = self.context.target.core_registers.by_name[self.reg]
226-
value = self.context.target.read_core_register(self.reg)
225+
info = self.context.selected_core.core_registers.by_name[self.reg]
226+
value = self.context.selected_core.read_core_register(self.reg)
227227
value_str = self._format_core_register(info, value)
228228
self.context.writei("%s = %s", self.reg, value_str)
229229
return
230230

231231
# Now look for matching group name.
232-
matcher = UniquePrefixMatcher(self.context.target.core_registers.groups)
232+
matcher = UniquePrefixMatcher(self.context.selected_core.core_registers.groups)
233233
group_matches = matcher.find_all(self.reg)
234234
if len(group_matches) == 1:
235235
self.dump_registers(show_group=group_matches[0])
@@ -277,16 +277,16 @@ def parse(self, args):
277277
self.value = args[idx + 1]
278278

279279
def execute(self):
280-
if self.reg in self.context.target.core_registers.by_name:
281-
if not self.context.target.is_halted():
280+
if self.reg in self.context.selected_core.core_registers.by_name:
281+
if not self.context.selected_core.is_halted():
282282
self.context.write("Core is not halted; cannot write core registers")
283283
return
284284

285285
if (self.reg.startswith('s') and self.reg != 'sp') or self.reg.startswith('d'):
286286
value = float(self.value)
287287
else:
288288
value = self._convert_value(self.value)
289-
self.context.target.write_core_register(self.reg, value)
289+
self.context.selected_core.write_core_register(self.reg, value)
290290
self.context.target.flush()
291291
else:
292292
value = self._convert_value(self.value)
@@ -301,18 +301,18 @@ def execute(self):
301301
addr = p.base_address + r.address_offset
302302
if len(subargs) == 2:
303303
self.context.writei("writing 0x%x to 0x%x:%d (%s)", value, addr, r.size, r.name)
304-
self.context.target.write_memory(addr, value, r.size)
304+
self.context.selected_ap.write_memory(addr, value, r.size)
305305
elif len(subargs) == 3:
306306
f = [x for x in r.fields if x.name.lower() == subargs[2]]
307307
if len(f):
308308
f = f[0]
309309
msb = f.bit_offset + f.bit_width - 1
310310
lsb = f.bit_offset
311-
originalValue = self.context.target.read_memory(addr, r.size)
311+
originalValue = self.context.selected_ap.read_memory(addr, r.size)
312312
value = bfi(originalValue, msb, lsb, value)
313313
self.context.writei("writing 0x%x to 0x%x[%d:%d]:%d (%s.%s)",
314314
value, addr, msb, lsb, r.size, r.name, f.name)
315-
self.context.target.write_memory(addr, value, r.size)
315+
self.context.selected_ap.write_memory(addr, value, r.size)
316316
else:
317317
raise exceptions.CommandError("too many dots")
318318
self.context.target.flush()
@@ -341,16 +341,16 @@ def parse(self, args):
341341
def execute(self):
342342
if self.do_halt:
343343
self.context.write("Resetting target with halt")
344-
self.context.target.reset_and_halt()
344+
self.context.selected_core.reset_and_halt()
345345

346-
status = self.context.target.get_state()
346+
status = self.context.selected_core.get_state()
347347
if status != Target.State.HALTED:
348348
self.context.writei("Failed to halt device on reset (state is %s)", status.name)
349349
else:
350350
self.context.write("Successfully halted device on reset")
351351
else:
352352
self.context.write("Resetting target")
353-
self.context.target.reset()
353+
self.context.selected_core.reset()
354354

355355
class DisassembleCommand(CommandBase):
356356
INFO = {
@@ -382,7 +382,7 @@ def execute(self):
382382
self.addr &= ~1
383383

384384
# Print disasm of data.
385-
data = self.context.target.read_memory_block8(self.addr, self.count)
385+
data = self.context.selected_ap.read_memory_block8(self.addr, self.count)
386386
print_disasm(self.context, bytes(bytearray(data)), self.addr)
387387

388388
class ReadCommandBase(CommandBase):
@@ -915,8 +915,8 @@ class ContinueCommand(CommandBase):
915915
}
916916

917917
def execute(self):
918-
self.context.target.resume()
919-
status = self.context.target.get_state()
918+
self.context.selected_core.resume()
919+
status = self.context.selected_core.get_state()
920920
if status == Target.State.RUNNING:
921921
self.context.write("Successfully resumed device")
922922
elif status == Target.State.SLEEPING:
@@ -947,16 +947,16 @@ def parse(self, args):
947947
self.count = 1
948948

949949
def execute(self):
950-
if not self.context.target.is_halted():
950+
if not self.context.selected_core.is_halted():
951951
self.context.write("Core is not halted; cannot step")
952952
return
953953

954954
for i in range(self.count):
955-
self.context.target.step(disable_interrupts=not self.context.session.options['step_into_interrupt'])
956-
addr = self.context.target.read_core_register('pc')
955+
self.context.selected_core.step(disable_interrupts=not self.context.session.options['step_into_interrupt'])
956+
addr = self.context.selected_core.read_core_register('pc')
957957
if IS_CAPSTONE_AVAILABLE:
958958
addr &= ~1
959-
data = self.context.target.read_memory_block8(addr, 4)
959+
data = self.context.selected_ap.read_memory_block8(addr, 4)
960960
print_disasm(self.context, bytes(bytearray(data)), addr, max_instructions=1)
961961
else:
962962
self.context.writei("PC = 0x%08x", addr)
@@ -972,9 +972,9 @@ class HaltCommand(CommandBase):
972972
}
973973

974974
def execute(self):
975-
self.context.target.halt()
975+
self.context.selected_core.halt()
976976

977-
status = self.context.target.get_state()
977+
status = self.context.selected_core.get_state()
978978
if status != Target.State.HALTED:
979979
self.context.writei("Failed to halt device; target state is %s", status.name.capitalize())
980980
return 1
@@ -995,8 +995,8 @@ def parse(self, args):
995995
self.addr = self._convert_value(args[0])
996996

997997
def execute(self):
998-
if self.context.target.set_breakpoint(self.addr):
999-
self.context.target.selected_core.bp_manager.flush()
998+
if self.context.selected_core.set_breakpoint(self.addr):
999+
self.context.selected_core.bp_manager.flush()
10001000
self.context.writei("Set breakpoint at 0x%08x", self.addr)
10011001
else:
10021002
self.context.writei("Failed to set breakpoint at 0x%08x", self.addr)
@@ -1016,9 +1016,9 @@ def parse(self, args):
10161016

10171017
def execute(self):
10181018
try:
1019-
type = self.context.target.get_breakpoint_type(self.addr)
1020-
self.context.target.remove_breakpoint(self.addr)
1021-
self.context.target.selected_core.bp_manager.flush()
1019+
type = self.context.selected_core.get_breakpoint_type(self.addr)
1020+
self.context.selected_core.remove_breakpoint(self.addr)
1021+
self.context.selected_core.bp_manager.flush()
10221022
self.context.writei("Removed breakpoint at 0x%08x", self.addr)
10231023
except Exception:
10241024
self.context.writei("Failed to remove breakpoint at 0x%08x", self.addr)
@@ -1034,9 +1034,9 @@ class ListBreakpointsCommand(CommandBase):
10341034
}
10351035

10361036
def execute(self):
1037-
availableBpCount = self.context.target.selected_core.available_breakpoint_count
1037+
availableBpCount = self.context.selected_core.available_breakpoint_count
10381038
self.context.writei("%d hardware breakpoints available", availableBpCount)
1039-
bps = self.context.target.selected_core.bp_manager.get_breakpoints()
1039+
bps = self.context.selected_core.bp_manager.get_breakpoints()
10401040
if not len(bps):
10411041
self.context.write("No breakpoints installed")
10421042
else:
@@ -1070,9 +1070,9 @@ def parse(self, args):
10701070
self.sz = 4
10711071

10721072
def execute(self):
1073-
if self.context.target.selected_core.dwt is None:
1073+
if self.context.selected_core.dwt is None:
10741074
raise exceptions.CommandError("DWT not present")
1075-
if self.context.target.set_watchpoint(self.addr, self.sz, self.wptype):
1075+
if self.context.selected_core.set_watchpoint(self.addr, self.sz, self.wptype):
10761076
self.context.writei("Set watchpoint at 0x%08x", self.addr)
10771077
else:
10781078
self.context.writei("Failed to set watchpoint at 0x%08x", self.addr)
@@ -1091,10 +1091,10 @@ def parse(self, args):
10911091
self.addr = self._convert_value(args[0])
10921092

10931093
def execute(self):
1094-
if self.context.target.selected_core.dwt is None:
1094+
if self.context.selected_core.dwt is None:
10951095
raise exceptions.CommandError("DWT not present")
10961096
try:
1097-
self.context.target.remove_watchpoint(self.addr)
1097+
self.context.selected_core.remove_watchpoint(self.addr)
10981098
self.context.writei("Removed watchpoint at 0x%08x", self.addr)
10991099
except Exception:
11001100
self.context.writei("Failed to remove watchpoint at 0x%08x", self.addr)
@@ -1110,19 +1110,19 @@ class ListWatchpointsCommand(CommandBase):
11101110
}
11111111

11121112
def execute(self):
1113-
if self.context.target.selected_core.dwt is None:
1113+
if self.context.selected_core.dwt is None:
11141114
raise exceptions.CommandError("DWT not present")
1115-
availableWpCount = self.context.target.selected_core.dwt.watchpoint_count
1115+
availableWpCount = self.context.selected_core.dwt.watchpoint_count
11161116
self.context.writei("%d hardware watchpoints available", availableWpCount)
1117-
wps = self.context.target.selected_core.dwt.get_watchpoints()
1117+
wps = self.context.selected_core.dwt.get_watchpoints()
11181118
if not len(wps):
11191119
self.context.write("No watchpoints installed")
11201120
else:
11211121
for i, wp in enumerate(wps):
11221122
# TODO fix requirement to access WATCH_TYPE_TO_FUNCT
11231123
self.context.writei("%d: 0x%08x, %d bytes, %s",
11241124
i, wp.addr, wp.size,
1125-
WATCHPOINT_FUNCTION_NAME_MAP[self.context.target.selected_core.dwt.WATCH_TYPE_TO_FUNCT[wp.func]])
1125+
WATCHPOINT_FUNCTION_NAME_MAP[self.context.selected_core.dwt.WATCH_TYPE_TO_FUNCT[wp.func]])
11261126

11271127
class SelectCoreCommand(CommandBase):
11281128
INFO = {
@@ -1137,20 +1137,20 @@ class SelectCoreCommand(CommandBase):
11371137
def parse(self, args):
11381138
if len(args) == 0:
11391139
self.show_core = True
1140-
self.core = None
1140+
self.core_num = None
11411141
else:
11421142
self.show_core = False
1143-
self.core = int(args[0], base=0)
1143+
self.core_num = int(args[0], base=0)
11441144

11451145
def execute(self):
11461146
if self.show_core:
1147-
self.context.writei("Core %d is selected", self.context.target.selected_core.core_number)
1147+
self.context.writei("Core %d is selected", self.context.selected_core.core_number)
11481148
return
1149-
original_core_ap = core_ap = self.context.target.selected_core.ap
1150-
self.context.target.selected_core = self.core
1151-
core_ap = self.context.target.selected_core.ap
1149+
original_core_ap = core_ap = self.context.selected_core.ap
1150+
self.context.selected_core = self.context.session.target.cores[self.core_num]
1151+
core_ap = self.context.selected_core.ap
11521152
self.context.selected_ap_address = core_ap.address
1153-
self.context.writef("Selected core {} ({})", self.core, core_ap.short_description)
1153+
self.context.writef("Selected core {} ({})", self.core_num, core_ap.short_description)
11541154

11551155
class ReadDpCommand(CommandBase):
11561156
INFO = {
@@ -1299,7 +1299,7 @@ def parse(self, args):
12991299
if len(args) >= 1:
13001300
self.addr = self._convert_value(args[0])
13011301
else:
1302-
self.addr = self.context.target.read_core_register('pc')
1302+
self.addr = self.context.selected_core.read_core_register('pc')
13031303
self.addr &= ~0x1 # remove thumb bit
13041304

13051305
def execute(self):
@@ -1372,7 +1372,7 @@ def parse(self, args):
13721372
raise exceptions.CommandError("invalid action")
13731373

13741374
def execute(self):
1375-
core_number = self.context.target.selected_core.core_number
1375+
core_number = self.context.selected_core.core_number
13761376
if self.action == 'start':
13771377
if core_number not in self.context.session.gdbservers:
13781378
# Persist the gdbserver

pyocd/commands/execution_context.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ def __init__(self, no_init=False, output_stream=None):
138138

139139
# State attributes.
140140
self._session = None
141+
self._selected_core = None
141142
self._selected_ap_address = None
142143
self._peripherals = {}
143144
self._loaded_peripherals = False
@@ -192,7 +193,7 @@ def writef(self, fmt, *args, **kwargs):
192193
def attach_session(self, session):
193194
"""! @brief Associate a session with the command context.
194195
195-
Various data for the context are initialized. This includes selecting the initially selected MEM-AP,
196+
Various data for the context are initialized. This includes selecting the initially selected core and MEM-AP,
196197
and getting an ELF file that was set on the target.
197198
198199
@param self This object.
@@ -207,8 +208,13 @@ def attach_session(self, session):
207208
# Select the first core's MEM-AP by default.
208209
if not self._no_init:
209210
try:
210-
if self.target.selected_core is not None:
211-
self.selected_ap_address = self.target.selected_core.ap.address
211+
# Selected core defaults to the target's default selected core.
212+
if self.selected_core is None:
213+
self.selected_core = self.target.selected_core
214+
215+
# Get the AP for the selected core.
216+
if self.selected_core is not None:
217+
self.selected_ap_address = self.selected_core.ap.address
212218
except IndexError:
213219
pass
214220

@@ -263,6 +269,15 @@ def output_stream(self):
263269
def output_stream(self, stream):
264270
self._output = stream
265271

272+
@property
273+
def selected_core(self):
274+
"""! @brief The Target instance for the selected core."""
275+
return self._selected_core
276+
277+
@selected_core.setter
278+
def selected_core(self, value):
279+
self._selected_core = value
280+
266281
@property
267282
def selected_ap_address(self):
268283
return self._selected_ap_address

0 commit comments

Comments
 (0)