Skip to content

Commit 8f40e8c

Browse files
committed
Improve RTT auto-detection for nRF54L15 and similar devices
- Add search_ranges parameter to rtt_start() for custom RTT search ranges - Add reset_before_start parameter for devices requiring reset before RTT - Auto-generate search ranges from device RAM info when available - Add polling mechanism to wait for RTT control block initialization - Ensure device is running before starting RTT Fixes #249 Addresses #209
1 parent a6f0868 commit 8f40e8c

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [Unreleased]
9+
### Added
10+
- @fxd0h: Added `search_ranges` parameter to `rtt_start()` to specify custom RTT search ranges (Issue #209)
11+
- @fxd0h: Added `reset_before_start` parameter to `rtt_start()` for devices requiring reset before RTT
12+
- @fxd0h: Auto-generate RTT search ranges from device RAM info when available (Issue #249)
13+
14+
### Fixed
15+
- @fxd0h: Improved RTT auto-detection reliability with polling mechanism
16+
- @fxd0h: Ensure device is running before starting RTT (fixes Issue #249)
17+
818
## [2.0.0]
919
### Changed
1020
- Python 2 is no longer supported.

pylink/jlink.py

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5277,24 +5277,117 @@ def swo_read_stimulus(self, port, num_bytes):
52775277
###############################################################################
52785278

52795279
@open_required
5280-
def rtt_start(self, block_address=None):
5280+
def rtt_start(self, block_address=None, search_ranges=None, reset_before_start=False):
52815281
"""Starts RTT processing, including background read of target data.
52825282
52835283
Args:
52845284
self (JLink): the ``JLink`` instance
5285-
block_address (int): optional configuration address for the RTT block
5285+
block_address (int, optional): Optional configuration address for the RTT block.
5286+
If None, auto-detection will be attempted first.
5287+
search_ranges (List[Tuple[int, int]], optional): Optional list of (start, end)
5288+
address ranges to search for RTT control block. Uses SetRTTSearchRanges command.
5289+
Example: [(0x20000000, 0x20010000)]
5290+
reset_before_start (bool, optional): If True, reset the device before starting RTT.
5291+
Default: False
52865292
52875293
Returns:
52885294
``None``
52895295
52905296
Raises:
52915297
JLinkRTTException: if the underlying JLINK_RTTERMINAL_Control call fails.
52925298
"""
5299+
# Reset if requested
5300+
if reset_before_start and self.target_connected():
5301+
try:
5302+
self.reset(ms=1)
5303+
time.sleep(0.1)
5304+
except Exception:
5305+
pass
5306+
5307+
# Ensure device is running (RTT requires running CPU)
5308+
# Note: RTT Viewer works without explicit connection checks, so we'll be lenient
5309+
# Try to resume device if we can detect it's halted, but don't fail if we can't check
5310+
try:
5311+
is_connected = self._dll.JLINKARM_IsConnected()
5312+
if is_connected:
5313+
is_halted = self._dll.JLINKARM_IsHalted()
5314+
if is_halted == 1: # Device is halted
5315+
self._dll.JLINKARM_Go()
5316+
time.sleep(1.0)
5317+
except Exception:
5318+
# If we can't check, assume device is running (RTT Viewer works)
5319+
pass
5320+
5321+
# Wait a bit for device to stabilize
5322+
time.sleep(0.5)
5323+
5324+
# Set search ranges if provided or if we can derive from device info
5325+
if search_ranges:
5326+
for start_addr, end_addr in search_ranges:
5327+
try:
5328+
self.exec_command(f"SetRTTSearchRanges {start_addr:X} {end_addr:X}")
5329+
time.sleep(0.1) # Small delay between commands
5330+
except Exception:
5331+
pass
5332+
elif hasattr(self, '_device') and self._device and hasattr(self._device, 'RAMAddr'):
5333+
# Auto-generate search ranges from device RAM info (from J-Link API)
5334+
ram_start = self._device.RAMAddr
5335+
ram_size = self._device.RAMSize if hasattr(self._device, 'RAMSize') else None
5336+
5337+
if ram_size:
5338+
# Use the full RAM range (like RTT Viewer does)
5339+
ram_end = ram_start + ram_size - 1
5340+
try:
5341+
self.exec_command(f"SetRTTSearchRanges {ram_start:X} {ram_end:X}")
5342+
time.sleep(0.1)
5343+
except Exception:
5344+
pass
5345+
else:
5346+
# Fallback: use common 64KB range
5347+
try:
5348+
self.exec_command(f"SetRTTSearchRanges {ram_start:X} {ram_start + 0xFFFF:X}")
5349+
time.sleep(0.1)
5350+
except Exception:
5351+
pass
5352+
5353+
# Start RTT
52935354
config = None
52945355
if block_address is not None:
52955356
config = structs.JLinkRTTerminalStart()
52965357
config.ConfigBlockAddress = block_address
5358+
52975359
self.rtt_control(enums.JLinkRTTCommand.START, config)
5360+
5361+
# Wait a bit after START command before polling (RTT needs time to initialize)
5362+
time.sleep(1.0)
5363+
5364+
# Poll for RTT to be ready (some devices need time for auto-detection)
5365+
# This gives the J-Link library time to find the RTT control block
5366+
max_wait = 10.0 # Increased timeout
5367+
start_time = time.time()
5368+
wait_interval = 0.1
5369+
5370+
while (time.time() - start_time) < max_wait:
5371+
time.sleep(wait_interval)
5372+
try:
5373+
if self.rtt_get_num_up_buffers() > 0:
5374+
return # Success - RTT control block found
5375+
except errors.JLinkRTTException:
5376+
# RTT control block not found yet, continue waiting
5377+
wait_interval = min(wait_interval * 1.5, 0.5)
5378+
continue
5379+
5380+
# If we get here and block_address was specified, raise exception
5381+
# For auto-detection, the exception will be raised by rtt_get_num_up_buffers
5382+
# when called by the user, so we don't raise here to allow fallback strategies
5383+
if block_address is not None:
5384+
try:
5385+
self.rtt_stop()
5386+
except:
5387+
pass
5388+
raise errors.JLinkRTTException(
5389+
enums.JLinkRTTErrors.RTT_ERROR_CONTROL_BLOCK_NOT_FOUND
5390+
)
52985391

52995392
@open_required
53005393
def rtt_stop(self):

0 commit comments

Comments
 (0)