Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions pyocd/subcommands/run_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ def invoke(self) -> int:
if isinstance(session.board.target.cores[core_number], GenericMemAPTarget):
continue

rtt_cfg = cfg if (cfg := rtt_config_list[core_number]) and cfg.channels is not None else None
run_server = RunServer(session=session,
core=core_number,
rtt_config=rtt_config_list[core_number],
rtt_config=rtt_cfg,
systemview_config=systemview_config,
enable_eot=self._args.eot,
shutdown_event=self.shared_shutdown)
Expand Down Expand Up @@ -225,13 +226,18 @@ def __init__(self, session: Session, core: Optional[int] = None, rtt_config: "RT

# Start RTT server
self._rtt_server = None
try:
rtt_manager = RTTManager(session=session, core=core, rtt_config=rtt_config, systemview_config=systemview_config)
self._rtt_server = rtt_manager.start_server()
if self._rtt_server is not None:
rtt_manager.configure_channels(stdio_handler=self._stdio_handler)
except RuntimeError as e:
LOG.debug("RTT configuration failed for core %d: %s", self.core, e)
self._rtt_config = rtt_config
self._rtt_manager = None
if self._rtt_config is not None:
# Try to start RTT server. If RTT control block is not initialized at program start, this may fail.
# In that case, we'll keep trying to start the RTT server every 10ms in the main loop.
try:
self._rtt_manager = RTTManager(session=session, core=core, rtt_config=rtt_config, systemview_config=systemview_config)
self._rtt_server = self._rtt_manager.start_server()
if self._rtt_server is not None:
self._rtt_manager.configure_channels(stdio_handler=self._stdio_handler)
except RuntimeError as e:
LOG.debug("RTT configuration failed for core %d: %s", self.core, e)

#
# If SWV is enabled, create a SWVReader thread. Note that we only do
Expand Down Expand Up @@ -287,11 +293,23 @@ def run(self):
if self._rtt_server:
self._rtt_server.poll()

# Check target state and handle semihosting every 10ms (every 10 loop iterations)
# to avoid slowing down RTT polling
# 10ms loop (every 10th iteration of 1ms loop) to avoid slowing down RTT polling
if state_check_interval_counter == 10:
state_check_interval_counter = 0

# Try to start RTT server if it isn't already running, and if the configuration is present
# This allows RTT to start up successfully even if the RTT control block is not initialized at program start
if self._rtt_config is not None and self._rtt_manager is not None and self._rtt_server is None:
# Attempt to start RTT server
try:
self._rtt_server = self._rtt_manager.start_server()
if self._rtt_server is not None:
LOG.info("RTT enabled for core %d", self.core)
self._rtt_manager.configure_channels(stdio_handler=self._stdio_handler)
except RuntimeError as e:
LOG.debug("RTT configuration failed for core %d: %s", self.core, e)

# Check target state
state = self._target.get_state()

# If we were able to successfully read the target state after previously receiving a fault,
Expand Down
29 changes: 20 additions & 9 deletions pyocd/utility/rtt_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ def __init__(self, session: Session, core: Optional[int] = None, rtt_config: RTT
else:
self._core = core
self._target = self._board.target.cores[core]
self._cb_detection_warning_logged = False

# RTT configuration
self._rtt_config = rtt_config
Expand Down Expand Up @@ -205,7 +206,7 @@ def _find_segger_rtt_symbol(self) -> Optional[int]:
def start_server(self) -> Optional[RTTServer]:
"""@brief Create and start RTT server."""

if not self._rtt_config.has_rtt_config:
if self._rtt_config is None or not self._rtt_config.has_rtt_config:
LOG.debug("RTT for core %d: no RTT configuration; RTT disabled", self._core)
return None

Expand All @@ -223,7 +224,9 @@ def start_server(self) -> Optional[RTTServer]:
if rtt_cb is not None:
address, size, auto_detect = rtt_cb
if address is None and auto_detect is False:
LOG.warning("RTT for core %d: control block configuration is missing address while auto-detect is disabled; RTT disabled", self._core)
if self._cb_detection_warning_logged is False:
LOG.warning("RTT for core %d: control block configuration is missing address while auto-detect is disabled; RTT disabled", self._core)
self._cb_detection_warning_logged = True
return None
if address is not None:
self._rtt_server = self._start_rtt_server(address, size)
Expand All @@ -234,31 +237,39 @@ def start_server(self) -> Optional[RTTServer]:
LOG.debug("RTT for core %d: RTT control block found via specified address 0x%X", self._core, address)
return self._rtt_server
else:
if size:
LOG.warning("RTT for core %d: failed to find RTT control block with specified address 0x%X and size 0x%X", self._core, address, size)
else:
LOG.warning("RTT for core %d: failed to find RTT control block with specified address 0x%X", self._core, address)
if self._cb_detection_warning_logged is False:
if size:
LOG.warning("RTT for core %d: failed to find RTT control block with specified address 0x%X and size 0x%X", self._core, address, size)
else:
LOG.warning("RTT for core %d: failed to find RTT control block with specified address 0x%X", self._core, address)
self._cb_detection_warning_logged = True
if auto_detect:
# Fallback: auto-detect via memory scan in default memory region if no address specified
self._rtt_server = self._start_rtt_server(None, None)
if self._rtt_server is not None:
LOG.debug("RTT for core %d: RTT control block found via auto-detect memory scan in default memory region", self._core)
return self._rtt_server
else:
LOG.warning("RTT for core %d: failed to find RTT control block with auto-detected address", self._core)
if self._cb_detection_warning_logged is False:
LOG.warning("RTT for core %d: failed to find RTT control block with auto-detected address", self._core)
self._cb_detection_warning_logged = True
return None
else:
# Auto-detect via symbol "_SEGGER_RTT" lookup in the ELF file
address = self._find_segger_rtt_symbol()
if address is None:
LOG.warning("RTT for core %d: failed to find _SEGGER_RTT symbol in ELF; cannot auto-detect RTT control block", self._core)
if self._cb_detection_warning_logged is False:
LOG.warning("RTT for core %d: failed to find _SEGGER_RTT symbol in ELF; cannot auto-detect RTT control block", self._core)
self._cb_detection_warning_logged = True
return None
self._rtt_server = self._start_rtt_server(address, None)
if self._rtt_server is not None:
LOG.debug("RTT for core %d: RTT control block found via _SEGGER_RTT symbol lookup at address 0x%X", self._core, address)
return self._rtt_server

LOG.warning("RTT for core %d: failed to find RTT control block with _SEGGER_RTT symbol address 0x%X", self._core, address)
if self._cb_detection_warning_logged is False:
LOG.warning("RTT for core %d: failed to find RTT control block with _SEGGER_RTT symbol address 0x%X", self._core, address)
self._cb_detection_warning_logged = True
return None

def configure_channels(self, stdio_handler: Optional[StdioHandler] = None):
Expand Down
Loading