Skip to content

Commit 46cd150

Browse files
committed
Merge pull request #49 from ARMmbed/devel_retarget
Retargeting
2 parents a93b65c + 068a078 commit 46cd150

File tree

5 files changed

+167
-51
lines changed

5 files changed

+167
-51
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ __pycache__/
44

55
# mbed-ls related files
66
.mbedls-mock
7+
mbedls.json
78

89
# C extensions
910
*.so

README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
* [Exporting mbedls output to JSON](#exporting-mbedls-output-to-json)
1212
* [Porting instructions](#porting-instructions)
1313
* [mbed-ls auto-detection approach for Ubuntu](#mbed-ls-auto-detection-approach-for-ubuntu)
14+
* [Retarget mbed-ls autodetection results](#retarget-mbed-ls-autodetection-results)
15+
* [mbedls.json file properties](#mbedlsjson-file-properties)
16+
* [Example of retargeting](#example-of-retargeting)
1417
* [Mocking new or existing target to custom platform name](#mocking-new-or-existing-target-to-custom-platform-name)
1518
* [Mock command line examples](#mock-command-line-examples)
1619
* [Mocking example with Freescale K64F platform](#mocking-example-with-freescale-k64f-platform)
@@ -328,6 +331,86 @@ $ mbedls
328331
+---------------------+-------------------+-------------------+----------------------------------------+
329332
```
330333

334+
# Retarget mbed-ls autodetection results
335+
336+
User can create file ```mbedls.json``` in given directory. ```mbedls.json``` file should contain JSON formatted data which will redefine mbed's parameters returned by mbed-ls. ```mbed-ls``` will automatically read ```mbedls.json``` file and alter auto-detection result.
337+
File should be placed in directory where we want to alter mbed-ls behavior.
338+
339+
* Note: This feature in implicitly ON.
340+
* Note: This feature can be turned off with command line switch ```--skip-retarget```.
341+
342+
## mbedls.json file properties
343+
* If file ```mbedls.json``` exists will be implicitly used to retarget results.
344+
* If file ```mbedls.json``` exists and flag ```--skip-retarget``` is set, there will be no retarget.
345+
* If file ```mbedls.json``` doesn't exist flag ```--skip-retarget``` has no effect.
346+
347+
## Example of retargeting
348+
In this example we will replace serial port name during Freescale's K64F auto-detection:
349+
```
350+
$ mbedls
351+
+--------------+---------------------+------------+------------+-------------------------------------------------+
352+
|platform_name |platform_name_unique |mount_point |serial_port |target_id |
353+
+--------------+---------------------+------------+------------+-------------------------------------------------+
354+
|K64F |K64F[0] |F: |COM9 |0240022648cb1e77000000000000000000000000b512e3cf |
355+
+--------------+---------------------+------------+------------+-------------------------------------------------+
356+
```
357+
358+
Our device is detected on port ```COM9``` and MSD is mounted on ```F:```. We can check more details using ```--json``` switch:
359+
```
360+
$ mbedls --json
361+
[
362+
{
363+
"mount_point": "F:",
364+
"platform_name": "K64F",
365+
"platform_name_unique": "K64F[0]",
366+
"serial_port": "COM9",
367+
"target_id": "0240022648cb1e77000000000000000000000000b512e3cf",
368+
"target_id_mbed_htm": "0240022648cb1e77000000000000000000000000b512e3cf",
369+
"target_id_usb_id": "0240022648cb1e77000000000000000000000000b512e3cf"
370+
}
371+
]
372+
```
373+
374+
We must understand that ```mbed-ls``` stores information about mbed devices in dictionaries.
375+
The same information can be presented as dictionary where its keys are ```target_id``` and value is a mbed auto-detection data.
376+
377+
```
378+
$ mbedls --json-by-target-id
379+
{
380+
"0240022648cb1e77000000000000000000000000b512e3cf": {
381+
"mount_point": "F:",
382+
"platform_name": "K64F",
383+
"platform_name_unique": "K64F[0]",
384+
"serial_port": "COM9",
385+
"target_id": "0240022648cb1e77000000000000000000000000b512e3cf",
386+
"target_id_mbed_htm": "0240022648cb1e77000000000000000000000000b512e3cf",
387+
"target_id_usb_id": "0240022648cb1e77000000000000000000000000b512e3cf"
388+
}
389+
}
390+
```
391+
392+
Let's say we want change ```serial_port```'s value to other COM port. For example we are using other serial port (e.g. while debugging) on our device as standard output.
393+
To do so we would have to create a new file called ```mbedls.json``` in directory where want to use this modification. File content could look like this: a JSON file where keys are ```target_id```'s and values are dictionaries with new values:
394+
395+
```
396+
$ cat mbedls.ls
397+
{
398+
"0240022648cb1e77000000000000000000000000b512e3cf" : {
399+
"serial_port" : "MyComPort01"
400+
}
401+
}
402+
```
403+
404+
Now, when we issue ```mbedls``` command in this directory our auto-detection data will be replaced:
405+
```
406+
$ mbedls
407+
+--------------+---------------------+------------+------------+-------------------------------------------------+
408+
|platform_name |platform_name_unique |mount_point |serial_port |target_id |
409+
+--------------+---------------------+------------+------------+-------------------------------------------------+
410+
|K64F |K64F[0] |F: |MyComPort01 |0240022648cb1e77000000000000000000000000b512e3cf |
411+
+--------------+---------------------+------------+------------+-------------------------------------------------+
412+
```
413+
331414
# Mocking new or existing target to custom platform name
332415
Command line switch ```--mock``` provide simple manufacturers ID masking with new platform name.
333416
Users should be able to add locally new ```MID``` -> ```platform_name``` mapping when e.g. prototyping.

mbed_lstools/lstools_base.py

Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def __init__(self):
2929
#extra flags
3030
self.DEBUG_FLAG = False # Used to enable debug code / prints
3131
self.ERRORLEVEL_FLAG = 0 # Used to return success code to environment
32+
self.retarget_data = {} # Used to retarget mbed-enabled platform properties
3233

3334
# If there is a local mocking data use it and add / override manufacture_ids
3435
mock_ids = self.mock_read()
@@ -169,30 +170,71 @@ def __init__(self):
169170
}
170171

171172
MOCK_FILE_NAME = '.mbedls-mock'
173+
RETARGET_FILE_NAME = 'mbedls.json'
172174

173175
def mock_read(self):
174176
"""! Load mocking data from local file
175177
@return Curent mocking configuration (dictionary)
176178
"""
177179
if os.path.isfile(self.MOCK_FILE_NAME):
178180
if self.DEBUG_FLAG:
179-
self.debug(self.mock_read.__name__, "reading %s"% self.MOCK_FILE_NAME)
180-
with open(self.MOCK_FILE_NAME, "r") as f:
181-
return json.load(f)
181+
self.debug(self.mock_read.__name__, "reading mock file %s"% self.MOCK_FILE_NAME)
182+
try:
183+
with open(self.MOCK_FILE_NAME, "r") as f:
184+
return json.load(f)
185+
except IOError as e:
186+
self.err("reading file '%s' failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
187+
str(e)))
188+
except ValueError as e:
189+
self.err("reading file '%s' content failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
190+
str(e)))
182191
return {}
183192

184193
def mock_write(self, mock_ids):
185-
# Write current mocking structure
194+
"""! Write current mocking structure
195+
@param mock_ids JSON mock data to dump to file
196+
"""
186197
if self.DEBUG_FLAG:
187198
self.debug(self.mock_write.__name__, "writing %s"% self.MOCK_FILE_NAME)
188-
with open(self.MOCK_FILE_NAME, "w") as f:
189-
f.write(json.dumps(mock_ids, indent=4))
199+
try:
200+
with open(self.MOCK_FILE_NAME, "w") as f:
201+
f.write(json.dumps(mock_ids, indent=4))
202+
except IOError as e:
203+
self.err("reading file '%s' failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
204+
str(e)))
205+
except ValueError as e:
206+
self.err("reading file '%s' content failed: %s"% (os.path.abspath(self.MOCK_FILE_NAME),
207+
str(e)))
208+
209+
def retarget_read(self):
210+
"""! Load retarget data from local file
211+
@return Curent retarget configuration (dictionary)
212+
"""
213+
if os.path.isfile(self.RETARGET_FILE_NAME):
214+
if self.DEBUG_FLAG:
215+
self.debug(self.retarget_read.__name__, "reading retarget file %s"% self.RETARGET_FILE_NAME)
216+
try:
217+
with open(self.RETARGET_FILE_NAME, "r") as f:
218+
return json.load(f)
219+
except IOError as e:
220+
self.err("reading file '%s' failed: %s"% (os.path.abspath(self.RETARGET_FILE_NAME),
221+
str(e)))
222+
except ValueError as e:
223+
self.err("reading file '%s' content failed: %s"% (os.path.abspath(self.RETARGET_FILE_NAME),
224+
str(e)))
225+
return {}
226+
227+
def retarget(self):
228+
"""! Enable retargeting
229+
"""
230+
self.retarget_data = self.retarget_read()
231+
return self.retarget_data
190232

191233
def mock_manufacture_ids(self, mid, platform_name, oper='+'):
192234
"""! Replace (or add if manufacture id doesn't exist) entry in self.manufacture_ids
193-
@param oper '+' add new mock / override existing entry
194-
'-' remove mid from mocking entry
195-
@return Mocked structure (json format)
235+
@param oper '+' add new mock / override existing entry
236+
'-' remove mid from mocking entry
237+
@return Mocked structure (json format)
196238
"""
197239
mock_ids = self.mock_read()
198240

@@ -236,9 +278,7 @@ def list_mbeds(self):
236278

237279
def list_mbeds_ext(self):
238280
"""! Function adds extra information for each mbed device
239-
240281
@return Returns list of mbed devices plus extended data like 'platform_name_unique'
241-
242282
@details Get information about mbeds with extended parameters/info included
243283
"""
244284
platform_names = {} # Count existing platforms and assign unique number
@@ -252,13 +292,22 @@ def list_mbeds_ext(self):
252292
platform_names[platform_name] += 1
253293
# Assign normalized, unique string at the end of target name: TARGET_NAME[x] where x is an ordinal integer
254294
mbeds[i]['platform_name_unique'] = "%s[%d]" % (platform_name, platform_names[platform_name])
295+
296+
# Retarget values from retarget (mbedls.json) file
297+
if self.retarget_data and 'target_id' in val:
298+
target_id = val['target_id']
299+
if target_id in self.retarget_data:
300+
mbeds[i].update(self.retarget_data[target_id])
301+
if self.DEBUG_FLAG:
302+
self.debug(self.list_mbeds_ext.__name__, ("retargeting", target_id, mbed[i]))
303+
255304
if self.DEBUG_FLAG:
256305
self.debug(self.list_mbeds_ext.__name__, (mbeds[i]['platform_name_unique'], val['target_id']))
257306
return mbeds
258307

259308
def list_platforms(self):
260-
""" Useful if you just want to know which platforms are currently available on the system
261-
@return List of (unique values) available platforms
309+
"""! Useful if you just want to know which platforms are currently available on the system
310+
@return List of (unique values) available platforms
262311
"""
263312
result = []
264313
mbeds = self.list_mbeds()
@@ -269,8 +318,8 @@ def list_platforms(self):
269318
return result
270319

271320
def list_platforms_ext(self):
272-
""" Useful if you just want to know how many platforms of each type are currently available on the system
273-
@return Dict of platform: platform_count
321+
"""! Useful if you just want to know how many platforms of each type are currently available on the system
322+
@return Dict of platform: platform_count
274323
"""
275324
result = {}
276325
mbeds = self.list_mbeds()
@@ -283,12 +332,9 @@ def list_platforms_ext(self):
283332
return result
284333

285334
def list_mbeds_by_targetid(self):
286-
""" Get information about mbeds with extended parameters/info included
287-
288-
@return Returns dictionary where keys are TargetIDs and values are mbed structures
289-
290-
@details Ordered by target id (key: target_id).
291-
335+
"""! Get information about mbeds with extended parameters/info included
336+
@return Returns dictionary where keys are TargetIDs and values are mbed structures
337+
@details Ordered by target id (key: target_id).
292338
"""
293339
result = {}
294340
mbed_list = self.list_mbeds_ext()
@@ -299,27 +345,23 @@ def list_mbeds_by_targetid(self):
299345

300346
# Private part, methods used to drive interface functions
301347
def load_mbed_description(self, file_name):
302-
""" Loads JSON file with mbeds' description (mapping between target id and platform name)
348+
"""! Load JSON file with mbeds' description (mapping between target id and platform name)
303349
Sets self.manufacture_ids with mapping between manufacturers' ids and platform name.
304350
"""
305351
#self.manufacture_ids = {} # TODO: load this values from file
306352
pass
307353

308354
def err(self, text):
309355
"""! Prints error messages
310-
311356
@param text Text to be included in error message
312-
313357
@details Function prints directly on console
314358
"""
315359
print 'error: %s'% text
316360

317361
def debug(self, name, text):
318362
"""! Prints error messages
319-
320363
@param name Called function name
321364
@param text Text to be included in debug message
322-
323365
@details Function prints directly on console
324366
"""
325367
print 'debug @%s.%s: %s'% (self.__class__.__name__, name, text)
@@ -333,12 +375,10 @@ def __str__(self):
333375

334376
def get_string(self, border=False, header=True, padding_width=0, sortby='platform_name'):
335377
"""! Printing with some sql table like decorators
336-
337378
@param border Table border visibility
338379
@param header Table header visibility
339380
@param padding_width Table padding
340381
@param sortby Column used to sort results
341-
342382
@return Returns string which can be printed on console
343383
"""
344384
from prettytable import PrettyTable
@@ -367,7 +407,6 @@ def get_string(self, border=False, header=True, padding_width=0, sortby='platfor
367407

368408
def get_json_data_from_file(self, json_spec_filename, verbose=False):
369409
"""! Loads from file JSON formatted string to data structure
370-
371410
@return None if JSON can be loaded
372411
"""
373412
result = None
@@ -386,9 +425,7 @@ def get_json_data_from_file(self, json_spec_filename, verbose=False):
386425

387426
def get_mbed_htm_target_id(self, mount_point):
388427
"""! Function scans mbed.htm to get information about TargetID.
389-
390428
@return Function returns targetID, in case of failure returns None.
391-
392429
@details Note: This function should be improved to scan variety of boards' mbed.htm files
393430
"""
394431
result = None
@@ -409,7 +446,6 @@ def get_mbed_htm_target_id(self, mount_point):
409446

410447
def scan_html_line_for_target_id(self, line):
411448
"""! Scan if given line contains target id encoded in URL.
412-
413449
@return Returns None when no target_id string in line
414450
"""
415451
# Detecting modern mbed.htm file format

0 commit comments

Comments
 (0)