Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ ENV/

# Mac Artifacts
**.DS_Store

# Personal documentation and sandbox (not part of pylink repo)
sandbox/github/
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- @fxd0h: Added `search_ranges` parameter to `rtt_start()` to specify custom RTT search ranges (Issue #209)
- @fxd0h: Added `block_address` parameter to `rtt_start()` for explicit RTT control block address (Issue #51)
- @fxd0h: Added `rtt_get_block_address()` method to search for RTT control block in memory (Issue #209)
- @fxd0h: Added `jlink_path` parameter to `JLink.__init__()` to specify custom J-Link SDK directory (Issue #251)
- @fxd0h: Added `Library.from_directory()` class method to load J-Link DLL from specific directory (Issue #251)
- @fxd0h: Added `read_idcode()` method to read device IDCODE via SWD/JTAG for connection health checks (Issue #252)
- @fxd0h: Added `check_connection_health()` method for firmware-independent reset detection (Issue #252)
- @fxd0h: Created `pylink.rtt` convenience module with high-level RTT functions:
- `auto_detect_rtt_ranges()` - Auto-generate search ranges from device RAM
- `start_rtt_with_polling()` - Start RTT with automatic polling until ready
- `reconnect_rtt()` - Reconnect RTT after device reset with parameter reconfiguration
- `rtt_context()` - Context manager for automatic RTT cleanup
- `monitor_rtt_with_reset_detection()` - Monitor RTT with automatic reset detection
- `read_rtt_without_echo()` - Read RTT data filtering out local echo characters (Issue #111)

### Changed
- @fxd0h: Simplified `rtt_start()` API per maintainer feedback - removed polling parameters and internal polling logic
- @fxd0h: `rtt_start()` now only configures search ranges if explicitly provided (no auto-generation)
- @fxd0h: Improved `rtt_write()` error messages to guide users when down buffers are missing (Issue #234)
- @fxd0h: Improved `rtt_read()` error handling for error code -11 with detailed diagnostics (Issue #160)
- @fxd0h: Moved convenience features (polling, auto-detection) to `pylink.rtt` module per maintainer feedback
- @fxd0h: Improved `get_device_index()` validation and error messages with device name suggestions (Issue #249)

### Fixed
- @fxd0h: Fixed `exec_command()` to distinguish informational messages from errors (Issue #171)
- @fxd0h: Improved RTT error messages to help diagnose configuration issues (Issues #234, #160)

## [2.0.0]
### Changed
- Python 2 is no longer supported.
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

[![Build Status](https://travis-ci.org/square/pylink.svg?branch=master)](https://travis-ci.org/square/pylink)

**Note:** This is a modified version with RTT improvements. See `issues/` directory for details on fixes and enhancements.

Python interface for the SEGGER J-Link.


Expand Down Expand Up @@ -69,6 +71,8 @@ $ export LD_LIBRARY_PATH=/path/to/SEGGER/JLink:$LD_LIBRARY_PATH

## Usage

### Basic Usage

```
import pylink

Expand All @@ -87,6 +91,34 @@ if __name__ == '__main__':
jlink.reset()
```

### RTT (Real-Time Transfer) Usage

For RTT operations, use the convenience module `pylink.rtt`:

```python
import pylink
from pylink.rtt import start_rtt_with_polling, rtt_context

jlink = pylink.JLink()
jlink.open()
jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
jlink.connect('NRF54L15_M33')

# Start RTT with auto-detected search ranges
if start_rtt_with_polling(jlink):
data = jlink.rtt_read(0, 1024)
print(bytes(data))

# Or use context manager for automatic cleanup
with rtt_context(jlink, search_ranges=[(0x20000000, 0x2003FFFF)]) as j:
data = j.rtt_read(0, 1024)
print(bytes(data))

jlink.close()
```

For more RTT examples, see `examples/rtt_example.py`.


## Troubleshooting

Expand Down
55 changes: 0 additions & 55 deletions TROUBLESHOOTING.md

This file was deleted.

46 changes: 46 additions & 0 deletions create_feature_branch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash
# Script to create feature branch for issue #252

set -e

echo "=== Creating feature branch for issue #252 ==="
echo ""

# Get current branch
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || git rev-parse --abbrev-ref HEAD)
echo "Current branch: $CURRENT_BRANCH"
echo ""

# Switch to master/main/development
if git show-ref --verify --quiet refs/heads/master; then
echo "Switching to master..."
git checkout master
elif git show-ref --verify --quiet refs/heads/main; then
echo "Switching to main..."
git checkout main
elif git show-ref --verify --quiet refs/heads/development; then
echo "Switching to development..."
git checkout development
else
echo "ERROR: No base branch found (master/main/development)"
exit 1
fi

# Pull latest changes
echo "Pulling latest changes from origin..."
git pull origin $(git branch --show-current) || echo "Warning: Could not pull from origin (continuing anyway)"
echo ""

# Create new feature branch
BRANCH_NAME="feature/252-reset-detection-swd-jtag"
echo "Creating branch: $BRANCH_NAME"
git checkout -b "$BRANCH_NAME"
echo ""

# Verify
echo "=== Branch created successfully ==="
echo "Current branch: $(git branch --show-current)"
echo ""
echo "You can now start implementing the feature request #252"
echo "GitHub Issue: https://github.com/square/pylink/issues/252"

1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Getting started is as simple as:
Unlockers <pylink.unlockers.rst>
Bindings <pylink.bindings.rst>
Extras <pylink.extras.rst>
RTT Convenience Module <pylink.rtt.rst>
Troubleshooting <troubleshooting.rst>

.. toctree::
Expand Down
21 changes: 21 additions & 0 deletions docs/pylink.extras.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,24 @@ This submodule provides different utility functions.
:members:
:undoc-members:
:show-inheritance:

RTT Convenience Functions
--------------------------

This submodule provides high-level convenience functions for RTT (Real-Time Transfer)
operations. It wraps the low-level JLink API and handles common use cases like
auto-detection, polling, and reconnection.

The low-level API in `jlink.py` is kept simple per maintainer feedback. This module
provides convenience features like:

- Automatic search range generation from device RAM info
- Polling for RTT readiness after start
- Automatic reconnection after device resets
- Context manager for automatic cleanup
- Reset detection and monitoring

.. automodule:: pylink.rtt
:members:
:undoc-members:
:show-inheritance:
125 changes: 125 additions & 0 deletions docs/pylink.rtt.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
RTT Convenience Functions
==========================

The ``pylink.rtt`` module provides high-level convenience functions for RTT
(Real-Time Transfer) operations. It wraps the low-level JLink API and handles
common use cases like auto-detection, polling, and reconnection.

The low-level API in ``jlink.py`` is kept simple per maintainer feedback. This
module provides convenience features like:

- Automatic search range generation from device RAM info
- Polling for RTT readiness after start
- Automatic reconnection after device resets
- Context manager for automatic cleanup
- Reset detection and monitoring

Quick Start
-----------

The simplest way to use RTT is with the context manager::

>>> import pylink
>>> from pylink.rtt import rtt_context
>>>
>>> jlink = pylink.JLink()
>>> jlink.open()
>>> jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
>>> jlink.connect('NRF54L15_M33')
>>>
>>> with rtt_context(jlink) as j:
... data = j.rtt_read(0, 1024)
... if data:
... print(bytes(data))

Auto-detection
--------------

The module can automatically detect RTT search ranges from device RAM info::

>>> from pylink.rtt import auto_detect_rtt_ranges, start_rtt_with_polling
>>>
>>> ranges = auto_detect_rtt_ranges(jlink)
>>> if ranges:
... start_rtt_with_polling(jlink, search_ranges=ranges)

Polling
-------

Start RTT with automatic polling until ready::

>>> from pylink.rtt import start_rtt_with_polling
>>>
>>> if start_rtt_with_polling(jlink, timeout=5.0):
... data = jlink.rtt_read(0, 1024)

Reconnection
------------

Reconnect RTT after device reset::

>>> from pylink.rtt import reconnect_rtt
>>>
>>> jlink.reset()
>>> if reconnect_rtt(jlink, search_ranges=[(0x20000000, 0x2003FFFF)]):
... print("RTT reconnected!")

Monitoring with Reset Detection
--------------------------------

Monitor RTT with automatic reset detection::

>>> from pylink.rtt import monitor_rtt_with_reset_detection
>>>
>>> for data in monitor_rtt_with_reset_detection(jlink):
... if data:
... print(bytes(data))

API Reference
-------------

.. automodule:: pylink.rtt
:members:
:undoc-members:
:show-inheritance:

Known Limitations
-----------------

RTT Telnet Port Configuration (Issue #161):
The J-Link SDK's ``SetRTTTelnetPort`` command sets the port that the J-Link
device listens on for Telnet connections. This is a server-side port
configuration that cannot be changed programmatically via pylink.

Limitations:
- The Telnet port is set by the J-Link device firmware, not by pylink
- Multiple J-Link instances may conflict if they use the same port
- Port conflicts must be resolved by using different J-Link devices or
configuring ports via SEGGER J-Link software

Workarounds:
- Use separate J-Link devices for different RTT sessions
- Use ``open_tunnel()`` with different client ports if connecting as client
- Configure ports via SEGGER J-Link Commander or J-Link Settings

For more details, see Issue #161.

Related Issues
--------------

This module addresses the following GitHub issues:

- `Issue #249 <https://github.com/square/pylink/issues/249>`_: RTT auto-detection fails
- `Issue #209 <https://github.com/square/pylink/issues/209>`_: Option to set RTT Search Range
- `Issue #51 <https://github.com/square/pylink/issues/51>`_: Initialize RTT with address of RTT control block
- `Issue #252 <https://github.com/square/pylink/issues/252>`_: Reset detection via SWD/JTAG
- `Issue #111 <https://github.com/square/pylink/issues/111>`_: RTT Echo (local echo option)
- `Issue #161 <https://github.com/square/pylink/issues/161>`_: Specify RTT Telnet port (limitation documented)

See Also
--------

- :doc:`pylink` - Low-level JLink API
- :doc:`troubleshooting` - Troubleshooting guide
- `SEGGER RTT Documentation <https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer/>`_

11 changes: 9 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@ Tool for updating J-Links on a Windows platform.
### Real Time Transfer (RTT)

#### Source
[RTT](./pylink-rtt)
[RTT Script](./pylink-rtt) | [RTT Examples](./rtt_example.py)

#### Description
Tool for a simple command-line terminal that communicates over RTT.
- **RTT Script**: Command-line terminal that communicates over RTT
- **RTT Examples**: Python examples demonstrating RTT usage with the convenience module `pylink.rtt`, including:
- Auto-detection of search ranges
- Polling for RTT readiness
- Reconnection after device reset
- Context manager for automatic cleanup
- Monitoring with reset detection
- Reading without local echo
Loading