Skip to content

Commit 44d819c

Browse files
Merge pull request #299 from bridadan/jlink_and_other_fw_detection
Jlink and other fw detection
2 parents 2efd5a8 + ba99fc8 commit 44d819c

File tree

4 files changed

+501
-303
lines changed

4 files changed

+501
-303
lines changed

mbed_lstools/lstools_base.py

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ def list_mbeds(
120120
Ex. mbeds = list_mbeds(filter_function=lambda m: m['platform_name'] == 'K64F')
121121
@param unique_names A boolean controlling the presence of the
122122
'platform_unique_name' member of the output dict
123-
@param read_details_text A boolean controlling the presense of the
124-
output dict attributes read from "DETAILS.TXT"
123+
@param read_details_txt A boolean controlling the presense of the
124+
output dict attributes read from other files present on the 'mount_point'
125125
@details Function returns list of dictionaries with mbed attributes 'mount_point', TargetID name etc.
126126
Function returns mbed list with platform names if possible
127127
"""
@@ -166,7 +166,9 @@ def _fs_never(self, device, filter_function, read_details_txt):
166166
"""Filter device without touching the file system of the device"""
167167
device['target_id'] = device['target_id_usb_id']
168168
device['target_id_mbed_htm'] = None
169-
device['platform_name'] = self.plat_db.get(device['target_id'][0:4])
169+
platform_data = self.plat_db.get(device['target_id'][0:4],
170+
verbose_data=True)
171+
device.update(platform_data or {'platform_name': None})
170172
if not filter_function or filter_function(device):
171173
return device
172174
else:
@@ -176,13 +178,9 @@ def _fs_before_id_check(self, device, filter_function, read_details_txt):
176178
"""Filter device after touching the file system of the device.
177179
Said another way: Touch the file system before filtering
178180
"""
179-
self._update_device_from_htm(device)
180-
181-
if read_details_txt:
182-
details_txt = self._details_txt(device['mount_point']) or {}
183-
device.update({"daplink_%s" % f.lower().replace(' ', '_'): v
184-
for f, v in details_txt.items()})
185181

182+
device['target_id'] = device['target_id_usb_id']
183+
self._update_device_from_fs(device, read_details_txt)
186184
if not filter_function or filter_function(device):
187185
return device
188186
else:
@@ -194,19 +192,95 @@ def _fs_after_id_check(self, device, filter_function, read_details_txt):
194192
"""
195193
device['target_id'] = device['target_id_usb_id']
196194
device['target_id_mbed_htm'] = None
197-
device['platform_name'] = self.plat_db.get(device['target_id'][0:4])
195+
platform_data = self.plat_db.get(device['target_id'][0:4], verbose_data=True)
196+
device.update(platform_data or {'platform_name': None})
198197
if not filter_function or filter_function(device):
199-
self._update_device_from_htm(device)
200-
201-
if read_details_txt:
202-
details_txt = self._details_txt(device['mount_point']) or {}
203-
device.update({"daplink_%s" % f.lower().replace(' ', '_'): v
204-
for f, v in details_txt.items()})
205-
198+
self._update_device_from_fs(device, read_details_txt)
206199
return device
207200
else:
208201
return None
209202

203+
def _update_device_from_fs(self, device, read_details_txt):
204+
""" Updates the device information based on files from its 'mount_point'
205+
@param device Dictionary containing device information
206+
@param read_details_txt A boolean controlling the presense of the
207+
output dict attributes read from other files present on the 'mount_point'
208+
"""
209+
if not device.get('mount_point', None):
210+
device['device_type'] = 'unknown'
211+
return
212+
213+
directory_entries = os.listdir(device['mount_point'])
214+
device['device_type'] = self._detect_device_type(directory_entries)
215+
device['target_id'] = device['target_id_usb_id']
216+
217+
{
218+
'daplink': self._update_device_details_daplink,
219+
'jlink': self._update_device_details_jlink
220+
}[device['device_type']](device, read_details_txt, directory_entries)
221+
222+
223+
def _detect_device_type(self, directory_entries):
224+
""" Returns a string of the device type
225+
@param directory_entries List of directories and files on the device
226+
@return 'daplink' or 'jlink'
227+
"""
228+
229+
return 'jlink' if 'segger.html' in [e.lower() for e in directory_entries] else 'daplink'
230+
231+
232+
def _update_device_details_daplink(self, device, read_details_txt, _):
233+
""" Updates the daplink-specific device information based on files from its 'mount_point'
234+
@param device Dictionary containing device information
235+
@param read_details_txt A boolean controlling the presense of the
236+
output dict attributes read from other files present on the 'mount_point'
237+
@param directory_entries List of directories and files on the device
238+
"""
239+
self._update_device_from_htm(device)
240+
if read_details_txt:
241+
details_txt = self._details_txt(device['mount_point']) or {}
242+
device.update({"daplink_%s" % f.lower().replace(' ', '_'): v
243+
for f, v in details_txt.items()})
244+
245+
if device['target_id']:
246+
platform_data = self.plat_db.get(device['target_id'][0:4],
247+
device_type='daplink',
248+
verbose_data=True)
249+
device.update(platform_data or {'platform_name': None})
250+
else:
251+
device['platform_name'] = None
252+
253+
def _update_device_details_jlink(self, device, _, directory_entries):
254+
""" Updates the jlink-specific device information based on files from its 'mount_point'
255+
@param device Dictionary containing device information
256+
@param directory_entries List of directories and files on the device
257+
"""
258+
lower_case_map = {e.lower(): e for e in directory_entries}
259+
260+
if 'board.html' in lower_case_map:
261+
board_file_key = 'board.html'
262+
elif 'user guide.html' in lower_case_map:
263+
board_file_key = 'user guide.html'
264+
else:
265+
logger.warning('No valid file found to update JLink device details')
266+
return
267+
268+
board_file_path = os.path.join(device['mount_point'], lower_case_map[board_file_key])
269+
with open(board_file_path, 'r') as board_file:
270+
board_file_lines = board_file.readlines()
271+
272+
for line in board_file_lines:
273+
m = re.search(r'url=([\w\d\:\-/\\\?\.=-_]+)', line)
274+
if m:
275+
device['url'] = m.group(1).strip()
276+
identifier = device['url'].split('/')[-1]
277+
platform_data = self.plat_db.get(identifier,
278+
device_type='jlink',
279+
verbose_data=True)
280+
device.update(platform_data or {'platform_name': None})
281+
break
282+
283+
210284
def _update_device_from_htm(self, device):
211285
"""Set the 'target_id', 'target_id_mbed_htm', 'platform_name' and
212286
'daplink_*' attributes by reading from mbed.htm on the device
@@ -225,10 +299,6 @@ def _update_device_from_htm(self, device):
225299
device['target_id_usb_id'])
226300
device['target_id'] = device['target_id_usb_id']
227301
device['target_id_mbed_htm'] = htm_target_id
228-
if device['target_id']:
229-
device['platform_name'] = self.plat_db.get(device['target_id'][0:4])
230-
else:
231-
device['platform_name'] = None
232302

233303
def mock_manufacture_id(self, mid, platform_name, oper='+'):
234304
"""! Replace (or add if manufacture id doesn't exist) entry in self.manufacture_ids

0 commit comments

Comments
 (0)