Skip to content

Commit 81f3b33

Browse files
committed
west: runners: jlink: Use registry to locate JLink executable
Instead of hardcoding a set of paths and trying to find the JLink executable in them, use the corresponding Windows registry to locate it: `HKEY_CURRENT_USER\\Software\\SEGGER\\J-Link` Signed-off-by: Carles Cufi <[email protected]> (cherry picked from commit bb1794b)
1 parent 01858bd commit 81f3b33

File tree

1 file changed

+18
-25
lines changed

1 file changed

+18
-25
lines changed

scripts/west_commands/runners/jlink.py

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
'''Runner for debugging with J-Link.'''
66

77
import argparse
8-
import glob
98
import ipaddress
109
import logging
1110
import os
@@ -110,41 +109,34 @@ def tool_opt_help(cls) -> str:
110109
return "Additional options for JLink Commander, e.g. '-autoconnect 1'"
111110

112111
@staticmethod
113-
def find_jlink():
112+
def default_jlink():
114113
global DEFAULT_JLINK_EXE
115114

116115
if sys.platform == 'win32':
117116
# JLink.exe can collide with the JDK executable of the same name
118-
# Look in the usual locations before falling back to $PATH
119-
for root in [os.environ["ProgramFiles"], os.environ["ProgramFiles(x86)"], str(Path.home())]: # noqa SIM112
120-
# SEGGER folder can contain a single "JLink" folder
121-
_direct = Path(root) / "SEGGER" / "JLink" / "JLink.exe"
122-
if _direct.exists():
123-
DEFAULT_JLINK_EXE = str(_direct)
124-
else:
125-
# SEGGER folder can contain multiple versions such as:
126-
# JLink_V796b
127-
# JLink_V796t
128-
# JLink_V798c
129-
# Find the latest version
130-
_versions = glob.glob(str(Path(root) / "SEGGER" / "JLink_V*"))
131-
if len(_versions) == 0:
132-
continue
133-
_expected_jlink = Path(_versions[-1]) / "JLink.exe"
134-
if not _expected_jlink.exists():
135-
continue
136-
DEFAULT_JLINK_EXE = str(_expected_jlink)
137-
break
138-
else:
139-
# Not found in the normal locations, hope that $PATH is correct
117+
# Locate the executable using the registry
118+
try:
119+
import winreg
120+
121+
# Note that when multiple JLink versions are installed on the
122+
# machine this points to the one that was installed
123+
# last, and not to the latest version.
124+
key = winreg.OpenKeyEx(
125+
winreg.HKEY_CURRENT_USER, r"Software\SEGGER\J-Link")
126+
DEFAULT_JLINK_EXE = (
127+
Path(winreg.QueryValueEx(key, "InstallPath")[0])
128+
/ "JLink.exe")
129+
except Exception:
130+
# Not found via the registry, hope that $PATH is correct
140131
DEFAULT_JLINK_EXE = "JLink.exe"
141132
else:
142133
DEFAULT_JLINK_EXE = "JLinkExe"
143134

144135
@classmethod
145136
def do_add_parser(cls, parser):
146137

147-
cls.find_jlink()
138+
# Find the default JLink executable
139+
cls.default_jlink()
148140

149141
# Required:
150142
parser.add_argument('--device', required=True, help='device name')
@@ -287,6 +279,7 @@ def do_run(self, command, **kwargs):
287279
# version of the tools we're using.
288280
self.commander = os.fspath(
289281
Path(self.require(self.commander)).resolve())
282+
self.logger.debug(f'JLink executable: {self.commander}')
290283
self.logger.info(f'JLink version: {self.jlink_version_str}')
291284

292285
rtos = self.thread_info_enabled and self.supports_thread_info

0 commit comments

Comments
 (0)