Skip to content

Feature Request: Reset Detection via SWD/JTAG Connection Health Monitoring #252

@fxd0h

Description

@fxd0h

Feature Request: Reset Detection via SWD/JTAG Connection Health Monitoring

Problem

Currently, detecting device resets requires either:

  1. Firmware-dependent methods (monitoring data intervals) - unreliable
  2. Accessing J-Link DLL directly via _dll attribute - not stable API

Solution

Add a method to check device connection health by reading hardware resources that are always accessible via SWD/JTAG:

  • IDCODE (device identification code) - Universal, works for all architectures
  • CPUID register (ARM Cortex-M at 0xE000ED00) - Architecture-specific, only for ARM Cortex-M
  • Processor registers (e.g., R0) - Architecture-dependent but registers always exist

Note: CPUID address (0xE000ED00) is NOT universal - it's specific to ARM Cortex-M architecture. For other architectures (Cortex-A, RISC-V, etc.), CPUID read should be skipped. The method remains reliable because IDCODE and register reads are universal.

If all reads fail → reset detected. If any read succeeds → device is accessible.

Proposed API

# Option 1: Simple health check
is_accessible = jlink.check_connection_health()
# Returns True if device accessible, False if reset/disconnected

# Option 2: Read IDCODE directly
try:
    idcode = jlink.read_idcode()
    print(f"IDCODE: 0x{idcode:08X}")
except pylink.errors.JLinkException:
    print("Device reset detected")

# Option 3: Detailed health status
health = jlink.check_connection_health(detailed=True)
# Returns: {
#     'idcode': 0x12345678 or None,
#     'cpuid': 0x410FC241 or None,
#     'register_r0': 0x00000000 or None,
#     'all_accessible': True/False
# }

Benefits

  • Firmware-independent: Works regardless of firmware reporting intervals
  • Reliable: Uses hardware-level resources always accessible via SWD/JTAG
  • Fast: Can check every 200ms for quick reset detection
  • No false positives: Doesn't depend on firmware behavior

Real-World Validation

Successfully implemented in my production RTT Monitor application:

  • Detects resets within 200ms
  • Zero false positives (tested with firmware reporting every 5 seconds)
  • Distinguishes reset (< 2s) from disconnection (> 2s)
  • Works with any firmware implementation

Implementation Details

Requires wrapping JLINKARM_ReadIdCode() from J-Link SDK. Can leverage existing memory_read32() and reg_read() methods.

Reference Implementation: See tools/rtt_monitor/rtt_monitor.py in my repository for working example.

Current Workaround

# Access internal DLL (not stable)
dll = jlink._dll
idcode = dll.JLINKARM_ReadIdCode() if hasattr(dll, 'JLINKARM_ReadIdCode') else None
cpuid_ok = False
try:
    jlink.memory_read32(0xE000ED00, 1)
    cpuid_ok = True
except:
    pass
# ... check if any succeeded ...

This works but relies on internal _dll attribute which may change.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions