@@ -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