Skip to content

Commit ef02f6e

Browse files
Jussi Vatjus-AnttilaJuho Hovila
authored andcommitted
Custom target filename (#150)
1 parent 35b8bff commit ef02f6e

File tree

14 files changed

+182
-46
lines changed

14 files changed

+182
-46
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,24 @@ optional arguments:
8181
targets can be given. Does not continue flashing
8282
next device in case of failures. Short target_id
8383
matches boards by prefix
84+
--target_filename TARGET_FILENAME
85+
Custom target filename
8486
-t PLATFORM_NAME, --platform_name PLATFORM_NAME
8587
Platform of the target device(s)
8688
--no-reset Do not reset device before or after flashing
8789
8890
```
8991

92+
`--target_filename TARGET_FILENAME` -option is used to select custom
93+
target filename when source file is copied to mbed target
94+
95+
e.g.
96+
```
97+
$ mbedflash flash simple --tid 0240000032254e45000f800ab529001f3f31000097969900 -i setup.hex --target_filename asd.hex
98+
```
99+
input file in above example would be `setup.hex`, that must exists and filename
100+
that is created for target mount point would be `asd.hex`.
101+
90102
**Erase help**
91103

92104
```

mbed_flasher/common.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,46 @@ def check_is_file_flashable(logger, file_path):
146146
:param file_path: file to be flashed (string)
147147
:return: None on success, raise FlashError otherwise
148148
"""
149+
check_file(logger, file_path)
150+
check_file_exists(logger, file_path)
151+
check_file_extension(logger, file_path)
152+
153+
154+
def check_file(logger, file_path):
155+
"""
156+
CHeck if file_path is not "False"
157+
:param logger: logger object
158+
:param file_path: file to be flashed (string)
159+
:return: None on success, raise FlashError otherwise
160+
"""
149161
if not file_path:
150162
msg = "File to be flashed was not given"
151163
logger.error(msg)
152164
# pylint: disable=superfluous-parens
153165
raise FlashError(message=msg, return_code=EXIT_CODE_FILE_MISSING)
154166

167+
168+
def check_file_exists(logger, file_path):
169+
"""
170+
CHeck if file exists
171+
:param logger: logger object
172+
:param file_path: file to be flashed (string)
173+
:return: None on success, raise FlashError otherwise
174+
"""
155175
if not os.path.isfile(file_path):
156176
msg = "Could not find given file: {}".format(file_path)
157177
logger.error(msg)
158178
# pylint: disable=superfluous-parens
159179
raise FlashError(message=msg, return_code=EXIT_CODE_FILE_MISSING)
160180

181+
182+
def check_file_extension(logger, file_path):
183+
"""
184+
CHeck if file name extension is valid
185+
:param logger: logger object
186+
:param file_path: file to be flashed (string)
187+
:return: None on success, raise FlashError otherwise
188+
"""
161189
if not file_path.lower().endswith(ALLOWED_FILE_EXTENSIONS):
162190
msg = "File extension is not supported: {}".format(file_path)
163191
logger.error(msg)

mbed_flasher/flash.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
limitations under the License.
1515
"""
1616

17-
from mbed_flasher.common import Common, Logger, FlashError, check_is_file_flashable
17+
from mbed_flasher.common import Common, Logger, FlashError,\
18+
check_file, check_file_exists, check_file_extension
1819
from mbed_flasher.flashers import AvailableFlashers
1920
from mbed_flasher.return_codes import EXIT_CODE_SUCCESS
2021
from mbed_flasher.return_codes import EXIT_CODE_PLATFORM_REQUIRED
@@ -149,14 +150,15 @@ def _verify_platform_coherence(device_mapping_table):
149150
return_code=EXIT_CODE_PLATFORM_REQUIRED)
150151

151152
# pylint: disable=too-many-arguments
152-
def flash_multiple(self, build, platform_name,
153-
method='simple', target_ids_or_prefix='', no_reset=None):
153+
def flash_multiple(self, build, platform_name, method='simple',
154+
target_ids_or_prefix='', no_reset=None, target_filename=None):
154155
"""
155156
:param build: build
156157
:param platform_name: platform name
157158
:param method: method
158159
:param target_ids_or_prefix: target ids or prefix
159160
:param no_reset: with/without reset
161+
:param target_filename: optional target filename
160162
:return:
161163
"""
162164
device_mapping_table = Common(self.logger).get_available_device_mapping(self._flashers)
@@ -192,34 +194,44 @@ def flash_multiple(self, build, platform_name,
192194
for item in device_mapping_table:
193195
self.logger.info(item['target_id'])
194196

197+
target_filename = target_filename or build
198+
195199
for device in device_mapping_table:
196200
self.flash(build=build,
197201
target_id=device['target_id'],
198202
platform_name=None,
199203
device_mapping_table=device_mapping_table,
200204
method=method,
201-
no_reset=no_reset)
205+
no_reset=no_reset,
206+
target_filename=target_filename)
202207

203208
return EXIT_CODE_SUCCESS
204209

205210
# pylint: disable=too-many-return-statements
206211
def flash(self, build, target_id=None, platform_name=None,
207-
device_mapping_table=None, method='simple', no_reset=None):
212+
device_mapping_table=None, method='simple', no_reset=None,
213+
target_filename=None):
208214
"""Flash (mbed) device
209-
:param build: Build -object or string (file-path)
215+
:param build: string (file-path)
210216
:param target_id: target_id
211217
:param platform_name: platform_name, to flash multiple devices of same type
212218
:param device_mapping_table: individual devices mapping table
213219
:param method: method for flashing i.e. simple, pyocd or edbg
214220
:param no_reset: whether to reset the board after flash
221+
:param target_filename: optional Target filename
215222
"""
216223

217224
k64f_target_id_length = 48
218225

219226
if target_id is None and platform_name is None:
220227
raise SyntaxError("target_id or target_name is required")
221228

222-
check_is_file_flashable(self.logger, build)
229+
target_filename = target_filename or build
230+
231+
check_file(self.logger, target_filename)
232+
check_file(self.logger, build)
233+
check_file_extension(self.logger, target_filename)
234+
check_file_exists(self.logger, build)
223235

224236
if (isinstance(target_id, list) or
225237
target_id.lower() == 'all' or
@@ -231,7 +243,8 @@ def flash(self, build, target_id=None, platform_name=None,
231243
platform_name=platform_name,
232244
method=method,
233245
target_ids_or_prefix=target_id,
234-
no_reset=no_reset)
246+
no_reset=no_reset,
247+
target_filename=target_filename)
235248

236249
device_mapping_table = self._refine__device_mapping_table(
237250
device_mapping_table, target_id)
@@ -257,7 +270,8 @@ def flash(self, build, target_id=None, platform_name=None,
257270
build=build,
258271
target=target_mbed,
259272
method=method,
260-
no_reset=no_reset)
273+
no_reset=no_reset,
274+
target_filename=target_filename)
261275
if retcode == EXIT_CODE_SUCCESS:
262276
self.logger.info("%s flash success", target_mbed["target_id"])
263277
else:
@@ -267,10 +281,14 @@ def flash(self, build, target_id=None, platform_name=None,
267281
return retcode
268282

269283
@staticmethod
270-
def _do_flash(flasher, build, target, method, no_reset):
284+
def _do_flash(flasher, build, target, method, no_reset, target_filename):
271285
try:
272286
return flasher.flash(
273-
source=build, target=target, method=method, no_reset=no_reset)
287+
source=build,
288+
target=target,
289+
method=method,
290+
no_reset=no_reset,
291+
target_filename=target_filename)
274292
except KeyboardInterrupt:
275293
raise FlashError(message="Aborted by user",
276294
return_code=EXIT_CODE_KEYBOARD_INTERRUPT)

mbed_flasher/flashers/FlasherAtmelAt.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,14 @@ def get_available_devices():
105105
"Connected atprogrammer supported devices: %s", connected_devices)
106106
return connected_devices
107107

108-
# actual flash procedure
109-
def flash(self, source, target):
110-
"""flash device
111-
:param sn: device serial number to be flashed
112-
:param binary: binary file to be flash
108+
# pylint: disable=too-many-arguments, unused-argument
109+
def flash(self, source, target, method, no_reset, target_filename):
110+
"""
111+
:param source: binary file to be flash
112+
:param target: target id
113+
:param method:
114+
:param no_reset:
115+
:param target_filename:
113116
:return: 0 when flashing success
114117
"""
115118
with tempfile.TemporaryFile() as temp:

mbed_flasher/flashers/FlasherBase.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ def is_executable_installed():
7171
"""
7272
raise NotImplementedError
7373

74-
def flash(self, source, target, method, no_reset):
74+
# pylint: disable=too-many-arguments
75+
def flash(self, source, target, method, no_reset, target_filename=None):
7576
"""flash device
7677
:param source: binary to be flashed
7778
:param target: target to be flashed

mbed_flasher/flashers/FlasherJLink.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,14 @@ def is_executable_installed():
8686
"""
8787
return spawn.find_executable(FlasherJLink.executable) is not None
8888

89-
def flash(self, source, target, method, no_reset):
89+
# pylint: disable=too-many-arguments
90+
def flash(self, source, target, method, no_reset, target_filename=None):
9091
"""flash device
9192
:param source: binary to be flashed
9293
:param target: target to be flashed
9394
:param method: method to use when flashing
9495
:param no_reset: do not reset flashed board at all
96+
:param target_filename: target filename (not in use)
9597
:return: 0 when flashing success
9698
"""
9799

mbed_flasher/flashers/FlasherMbed.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,14 @@ def can_flash(target):
8787
"""
8888
return True
8989

90-
# pylint: disable=too-many-return-statements, duplicate-except
91-
def flash(self, source, target, method, no_reset):
90+
# pylint: disable=too-many-return-statements, duplicate-except, too-many-arguments
91+
def flash(self, source, target, method, no_reset, target_filename):
9292
"""copy file to the destination
9393
:param source: binary to be flashed
9494
:param target: target to be flashed
9595
:param method: method to use when flashing
9696
:param no_reset: do not reset flashed board at all
97+
:param target_filename: destination filename
9798
"""
9899
if not isinstance(source, six.string_types):
99100
return
@@ -109,7 +110,7 @@ def flash(self, source, target, method, no_reset):
109110
return retry(
110111
logger=self.logger,
111112
func=self.try_drag_and_drop_flash,
112-
func_args=(source, target, no_reset),
113+
func_args=(source, target, target_filename, no_reset),
113114
retries=FlasherMbed.DRAG_AND_DROP_FLASH_RETRIES,
114115
conditions=[EXIT_CODE_OS_ERROR,
115116
EXIT_CODE_DAPLINK_TRANSIENT_ERROR,
@@ -146,7 +147,7 @@ def try_pyocd_flash(self, source, target):
146147
raise FlashError(message="PyOCD flash failed",
147148
return_code=EXIT_CODE_FLASH_FAILED)
148149

149-
def try_drag_and_drop_flash(self, source, target, no_reset):
150+
def try_drag_and_drop_flash(self, source, target, target_filename, no_reset):
150151
"""
151152
Try to flash the target using drag and drop method.
152153
:param source: file to be flashed
@@ -160,7 +161,7 @@ def try_drag_and_drop_flash(self, source, target, no_reset):
160161
raise FlashError(message="Target ID is missing",
161162
return_code=EXIT_CODE_TARGET_ID_MISSING)
162163

163-
destination = MbedCommon.get_binary_destination(target["mount_point"], source)
164+
destination = MbedCommon.get_binary_destination(target["mount_point"], target_filename)
164165

165166
try:
166167
if 'serial_port' in target and not no_reset:
@@ -170,7 +171,7 @@ def try_drag_and_drop_flash(self, source, target, no_reset):
170171
self.copy_file(source, destination)
171172
self.logger.debug("copy finished")
172173

173-
target = MbedCommon.wait_for_file_disappear(target, source)
174+
target = MbedCommon.wait_for_file_disappear(target, target_filename)
174175

175176
if not no_reset:
176177
Reset(logger=self.logger).reset_board(target["serial_port"])
@@ -179,7 +180,7 @@ def try_drag_and_drop_flash(self, source, target, no_reset):
179180
# verify flashing went as planned
180181
self.logger.debug("verifying flash")
181182
return self.verify_flash_success(
182-
target, MbedCommon.get_binary_destination(target["mount_point"], source))
183+
target, MbedCommon.get_binary_destination(target["mount_point"], target_filename))
183184
# In python3 IOError is just an alias for OSError
184185
except (OSError, IOError) as error:
185186
msg = "File copy failed due to: {}".format(str(error))

mbed_flasher/flashers/FlasherST.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,14 @@ def is_executable_installed():
8484
"""
8585
return spawn.find_executable(FlasherSTLink.executable) is not None
8686

87-
def flash(self, source, target, method, no_reset):
87+
# pylint: disable=too-many-arguments
88+
def flash(self, source, target, method, no_reset, target_filename=None):
8889
"""flash device
8990
:param source: binary to be flashed
9091
:param target: target to be flashed
9192
:param method: method to use when flashing
9293
:param no_reset: do not reset flashed board at all
94+
:param target_filename: target filename (not in use)
9395
:return: 0 when flashing success
9496
"""
9597
try:

mbed_flasher/main.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import time
2828

2929
from mbed_flasher.common import Common, FlashError, EraseError, ResetError, GeneralFatalError,\
30-
check_is_file_flashable
30+
check_file, check_file_extension, check_file_exists
3131
from mbed_flasher.flash import Flash
3232
from mbed_flasher.erase import Erase
3333
from mbed_flasher.reset import Reset
@@ -196,6 +196,9 @@ def argparser_setup(self, sysargs):
196196
'also multiple targets can be given. '
197197
'Short target_id matches boards by prefix',
198198
default=None, metavar='TARGET_ID', action='append')
199+
parser_flash.add_argument('--target_filename',
200+
help='Custom target filename',
201+
default=None, metavar='TARGET_FILENAME')
199202
parser_flash.add_argument('-t', '--platform_name',
200203
help='Platform of the target device(s)',
201204
default=None)
@@ -292,7 +295,11 @@ def subcmd_flash_handler(self, args):
292295
raise FlashError(message=msg,
293296
return_code=EXIT_CODE_TARGET_ID_MISSING)
294297

295-
check_is_file_flashable(self.logger, args.input)
298+
check_file(self.logger, args.target_filename or args.input)
299+
check_file(self.logger, args.input)
300+
check_file_exists(self.logger, args.input)
301+
check_file_extension(self.logger, args.target_filename or args.input)
302+
296303

297304
flasher = Flash()
298305
available = Common(self.logger).get_available_device_mapping(
@@ -309,6 +316,7 @@ def subcmd_flash_handler(self, args):
309316
if 'all' in args.tid:
310317
retcode = flasher.flash(build=args.input, target_id='all',
311318
platform_name=args.platform_name,
319+
target_filename=args.target_filename,
312320
method=args.method, no_reset=args.no_reset)
313321

314322
if len(available) <= 0:
@@ -333,6 +341,7 @@ def subcmd_flash_handler(self, args):
333341
else:
334342
retcode = flasher.flash(build=args.input,
335343
target_id=target_ids_to_flash,
344+
target_filename=args.target_filename,
336345
platform_name=available_platforms[0],
337346
method=args.method,
338347
no_reset=args.no_reset)

test/hardware/test_cliapi.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,11 @@ def test_flash_user_error_k64f(self):
6262
target_id = first_or_default['target_id']
6363
parameters = ['flash', '--no-reset', '-i', filename, '--tid', target_id]
6464
self.assertEqual(ApiTests.spawn(parameters), EXIT_CODE_DAPLINK_USER_ERROR)
65+
66+
# pylint:disable=invalid-name
67+
def test_flash_success_with_target_filename(self):
68+
first_or_default = self.find_platform('K64F')
69+
filename = self.bin_hello_world
70+
target_id = first_or_default['target_id']
71+
parameters = ['flash', '-i', filename, '--tid', target_id, '--target_filename', 'test.bin']
72+
self.assertEqual(ApiTests.spawn(parameters), EXIT_CODE_SUCCESS)

0 commit comments

Comments
 (0)