Skip to content

Commit dcc416c

Browse files
committed
J-Link: avoid opening probe to read strings in constructor.
- Removed ctor code that temporarily opened the probe to access the product name and OEM strings, replaced with the acProductName attr from the probe info object returned by pylink. This is a slightly differently string, but is still better than the generic "J-Link" USB product name. The OEM string is not supported anymore. - Added class method to format serial number as a string, so there is only one place where this logic is located. - Corrected passing the integer serial number to the pylink open() method (instead of the string). - Raising a ProbeError instead of assertion if neither SWD nor JTAG are supported. - Added _get_probe_info() class method.
1 parent cbf3519 commit dcc416c

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

pyocd/probe/jlink_probe.py

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,18 @@ def _get_jlink(cls):
5454
)
5555
except TypeError:
5656
return None
57+
58+
@classmethod
59+
def _format_serial_number(cls, serial_number):
60+
return "{:d}".format(serial_number)
5761

5862
@classmethod
5963
def get_all_connected_probes(cls, unique_id=None, is_explicit=False):
6064
try:
6165
jlink = cls._get_jlink()
6266
if jlink is None:
6367
return []
64-
return [cls(str(info.SerialNumber)) for info in jlink.connected_emulators()]
68+
return [cls(cls._format_serial_number(info.SerialNumber)) for info in jlink.connected_emulators()]
6569
except JLinkException as exc:
6670
six.raise_from(cls._convert_exception(exc), exc)
6771

@@ -72,43 +76,60 @@ def get_probe_with_id(cls, unique_id, is_explicit=False):
7276
if jlink is None:
7377
return None
7478
for info in jlink.connected_emulators():
75-
if str(info.SerialNumber) == unique_id:
76-
return cls(str(info.SerialNumber))
79+
sn = cls._format_serial_number(info.SerialNumber)
80+
if sn == unique_id:
81+
return cls(sn)
82+
else:
83+
return None
84+
except JLinkException as exc:
85+
six.raise_from(cls._convert_exception(exc), exc)
86+
87+
@classmethod
88+
def _get_probe_info(cls, serial_number, jlink):
89+
"""! @brief Look up and return a JLinkConnectInfo for the probe with matching serial number.
90+
@param cls The class object.
91+
@param serial_number String serial number. Must be the full serial number.
92+
@return JLinkConnectInfo object or None if there was no match.
93+
"""
94+
try:
95+
for info in jlink.connected_emulators():
96+
if cls._format_serial_number(info.SerialNumber) == serial_number:
97+
return info
7798
else:
7899
return None
79100
except JLinkException as exc:
80101
six.raise_from(cls._convert_exception(exc), exc)
81102

82103
def __init__(self, serial_number):
104+
"""! @brief Constructor.
105+
@param self The object.
106+
@param serial_number String. The J-Link's serial number.
107+
"""
83108
super(JLinkProbe, self).__init__()
84109
self._link = self._get_jlink()
85110
if self._link is None:
86111
raise exceptions.ProbeError("unable to open JLink DLL")
87112

113+
info = self._get_probe_info(serial_number, self._link)
114+
if info is None:
115+
raise exceptions.ProbeError("could not find JLink probe with serial number '{}'".format(serial_number))
116+
88117
self._serial_number = serial_number
118+
self._serial_number_int = int(serial_number, base=10)
89119
self._supported_protocols = None
90120
self._protocol = None
91121
self._default_protocol = None
92122
self._is_open = False
93123
self._dp_select = -1
94-
self._product_name = None
95-
self._oem = None
96-
97-
# Get some strings by temporarily opening.
98-
try:
99-
self.open()
100-
self._product_name = self._link.product_name
101-
self._oem = self._link.oem
102-
finally:
103-
self.close()
124+
self._product_name = six.ensure_str(info.acProduct)
104125

105126
@property
106127
def description(self):
107128
return self.vendor_name + " " + self.product_name
108129

109130
@property
110131
def vendor_name(self):
111-
return self._oem or "Segger"
132+
return "Segger"
112133

113134
@property
114135
def product_name(self):
@@ -137,7 +158,7 @@ def capabilities(self):
137158

138159
def open(self):
139160
try:
140-
self._link.open(self._serial_number)
161+
self._link.open(self._serial_number_int)
141162
self._is_open = True
142163

143164
# Get available wire protocols.
@@ -147,7 +168,9 @@ def open(self):
147168
self._supported_protocols.append(DebugProbe.Protocol.JTAG)
148169
if ifaces & (1 << pylink.enums.JLinkInterfaces.SWD):
149170
self._supported_protocols.append(DebugProbe.Protocol.SWD)
150-
assert len(self._supported_protocols) > 1
171+
if not len(self._supported_protocols) >= 2: # default + 1
172+
raise exceptions.ProbeError("J-Link probe {} does not support any known wire protocols".format(
173+
self.unique_id))
151174

152175
# Select default protocol, preferring SWD over JTAG.
153176
if DebugProbe.Protocol.SWD in self._supported_protocols:

0 commit comments

Comments
 (0)