Skip to content

Commit d76e4b1

Browse files
Merge pull request #370 from bridadan/firmware_detection
VID/PID based device type detection
2 parents 5139d74 + b0aa4be commit d76e4b1

File tree

2 files changed

+37
-21
lines changed

2 files changed

+37
-21
lines changed

mbed_lstools/lstools_base.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ class MbedLsToolsBase(object):
6969
DETAILS_TXT_NAME = 'DETAILS.TXT'
7070
MBED_HTM_NAME = 'mbed.htm'
7171

72+
VENDOR_ID_DEVICE_TYPE_MAP = {
73+
'0483': 'stlink',
74+
'0d28': 'daplink',
75+
'1366': 'jlink'
76+
}
77+
7278
def __init__(self, list_unmounted=False, **kwargs):
7379
""" ctor
7480
"""
@@ -211,13 +217,14 @@ def _update_device_from_fs(self, device, read_details_txt):
211217
try:
212218
directory_entries = os.listdir(device['mount_point'])
213219
device['directory_entries'] = directory_entries
214-
device['device_type'] = self._detect_device_type(directory_entries)
220+
device['device_type'] = self._detect_device_type(device)
215221
device['target_id'] = device['target_id_usb_id']
216222

217223
{
218-
'daplink': self._update_device_details_daplink,
224+
'daplink': self._update_device_details_daplink_compatible,
225+
'stlink': self._update_device_details_daplink_compatible,
219226
'jlink': self._update_device_details_jlink
220-
}[device['device_type']](device, read_details_txt, directory_entries)
227+
}[device['device_type'] or 'daplink'](device, read_details_txt)
221228
except (OSError, IOError) as e:
222229
logger.warning(
223230
'Marking device with mount point "%s" as unmounted due to the '
@@ -226,23 +233,22 @@ def _update_device_from_fs(self, device, read_details_txt):
226233
device['device_type'] = 'unknown'
227234

228235

229-
def _detect_device_type(self, directory_entries):
236+
def _detect_device_type(self, device):
230237
""" Returns a string of the device type
231-
@param directory_entries List of directories and files on the device
232-
@return 'daplink' or 'jlink'
238+
@param device Dictionary containing device information
239+
@return Device type located in VENDOR_ID_DEVICE_TYPE_MAP or None if unknown
233240
"""
234241

235-
return 'jlink' if 'segger.html' in [e.lower() for e in directory_entries] else 'daplink'
242+
return self.VENDOR_ID_DEVICE_TYPE_MAP.get(device.get('vendor_id'))
236243

237244

238-
def _update_device_details_daplink(self, device, read_details_txt, directory_entries):
245+
def _update_device_details_daplink_compatible(self, device, read_details_txt):
239246
""" Updates the daplink-specific device information based on files from its 'mount_point'
240247
@param device Dictionary containing device information
241248
@param read_details_txt A boolean controlling the presense of the
242249
output dict attributes read from other files present on the 'mount_point'
243-
@param directory_entries List of directories and files on the device
244250
"""
245-
lowercase_directory_entries = [e.lower() for e in directory_entries]
251+
lowercase_directory_entries = [e.lower() for e in device['directory_entries']]
246252
if self.MBED_HTM_NAME.lower() in lowercase_directory_entries:
247253
self._update_device_from_htm(device)
248254
elif not read_details_txt:
@@ -271,12 +277,11 @@ def _update_device_details_daplink(self, device, read_details_txt, directory_ent
271277
else:
272278
device['platform_name'] = None
273279

274-
def _update_device_details_jlink(self, device, _, directory_entries):
280+
def _update_device_details_jlink(self, device, _):
275281
""" Updates the jlink-specific device information based on files from its 'mount_point'
276282
@param device Dictionary containing device information
277-
@param directory_entries List of directories and files on the device
278283
"""
279-
lower_case_map = {e.lower(): e for e in directory_entries}
284+
lower_case_map = {e.lower(): e for e in device['directory_entries']}
280285

281286
if 'board.html' in lower_case_map:
282287
board_file_key = 'board.html'

test/mbedls_toolsbase.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,21 @@ def test_update_device_from_fs_unknown(self):
289289
self.assertEqual(device['device_type'], 'unknown')
290290

291291
def test_detect_device_test(self):
292-
device_type = self.base._detect_device_type(['Segger.html'])
293-
self.assertEqual(device_type, 'jlink')
294-
295-
device_type = self.base._detect_device_type(['MBED.HTM', 'DETAILS.TXT'])
292+
device_type = self.base._detect_device_type({
293+
'vendor_id': '0483'
294+
})
295+
self.assertEqual(device_type, 'stlink')
296+
297+
device_type = self.base._detect_device_type({
298+
'vendor_id': '0d28'
299+
})
296300
self.assertEqual(device_type, 'daplink')
297301

302+
device_type = self.base._detect_device_type({
303+
'vendor_id': '1366'
304+
})
305+
self.assertEqual(device_type, 'jlink')
306+
298307
def test_update_device_details_jlink(self):
299308
jlink_html_contents = ('<html><head><meta http-equiv="refresh" '
300309
'content="0; url=http://www.nxp.com/FRDM-KL27Z"/>'
@@ -307,24 +316,26 @@ def test_update_device_details_jlink(self):
307316

308317
with patch('mbed_lstools.lstools_base.open', _open, create=True):
309318
device = deepcopy(base_device)
310-
self.base._update_device_details_jlink(device, False, ['Board.html', 'User Guide.html'])
319+
device['directory_entries'] = ['Board.html', 'User Guide.html']
320+
self.base._update_device_details_jlink(device, False)
311321
self.assertEqual(device['url'], 'http://www.nxp.com/FRDM-KL27Z')
312322
self.assertEqual(device['platform_name'], 'KL27Z')
313323
_open.assert_called_once_with(os.path.join(dummy_mount_point, 'Board.html'), 'r')
314324

315325
_open.reset_mock()
316326

317327
device = deepcopy(base_device)
318-
self.base._update_device_details_jlink(device, False, ['User Guide.html'])
328+
device['directory_entries'] = ['User Guide.html']
329+
self.base._update_device_details_jlink(device, False)
319330
self.assertEqual(device['url'], 'http://www.nxp.com/FRDM-KL27Z')
320331
self.assertEqual(device['platform_name'], 'KL27Z')
321332
_open.assert_called_once_with(os.path.join(dummy_mount_point, 'User Guide.html'), 'r')
322333

323334
_open.reset_mock()
324335

325336
device = deepcopy(base_device)
326-
self.base._update_device_details_jlink(device, False, ['unhelpful_file.html'])
327-
self.assertEqual(device, base_device)
337+
device['directory_entries'] = ['unhelpful_file.html']
338+
self.base._update_device_details_jlink(device, False)
328339
_open.assert_not_called()
329340

330341
def test_fs_never(self):

0 commit comments

Comments
 (0)