Skip to content

Commit 049a07b

Browse files
committed
build: Automatically determine image format to flash
The default image format is bin, but targets can override it with `"OUTPUT_EXT": "hex"` in `targets.json`. This is already taken care of in the CMake configuration generated by mbed-tools, but user still need to pass `--hex-file` if they want to run `mbed-tools compile` with `--flash` to flash a hex image. This commit makes the image selection automatic based on `OUTPUT_EXT`. Note: `--hex-file` is now redundant and thus removed. It does not make sense to have it anymore without also offering `--bin-file` for completeness. The test cases for bin and hex image flashing have been updated accordingly.
1 parent 2e5c64d commit 049a07b

File tree

5 files changed

+56
-27
lines changed

5 files changed

+56
-27
lines changed

news/20210602164800.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The `--flash` option of `mbed-tools compile` now automatically selects bin or hex image. The option `--hex-file` is removed.

src/mbed_tools/build/config.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55
"""Parses the Mbed configuration system and generates a CMake config script."""
66
import pathlib
77

8-
from typing import Any
8+
from typing import Any, Tuple
99

1010
from mbed_tools.lib.json_helpers import decode_json_file
1111
from mbed_tools.project import MbedProgram
1212
from mbed_tools.targets import get_target_by_name
1313
from mbed_tools.build._internal.cmake_file import render_mbed_config_cmake_template
14-
from mbed_tools.build._internal.config.assemble_build_config import assemble_config
14+
from mbed_tools.build._internal.config.assemble_build_config import Config, assemble_config
1515
from mbed_tools.build._internal.write_files import write_file
1616
from mbed_tools.build.exceptions import MbedBuildError
1717

1818
CMAKE_CONFIG_FILE = "mbed_config.cmake"
1919

2020

21-
def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> pathlib.Path:
21+
def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> Tuple[Config, pathlib.Path]:
2222
"""Generate an Mbed config file at the program root by parsing the mbed config system.
2323
2424
Args:
@@ -27,6 +27,7 @@ def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> p
2727
program: The MbedProgram to configure.
2828
2929
Returns:
30+
Config object (UserDict)
3031
Path to the generated config file.
3132
"""
3233
targets_data = _load_raw_targets_data(program)
@@ -39,7 +40,7 @@ def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> p
3940
)
4041
cmake_config_file_path = program.files.cmake_build_dir / CMAKE_CONFIG_FILE
4142
write_file(cmake_config_file_path, cmake_file_contents)
42-
return cmake_config_file_path
43+
return config, cmake_config_file_path
4344

4445

4546
def _load_raw_targets_data(program: MbedProgram) -> Any:

src/mbed_tools/cli/build.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@
4242
@click.option(
4343
"-f", "--flash", is_flag=True, default=False, help="Flash the binary onto a device",
4444
)
45-
@click.option(
46-
"--hex-file", is_flag=True, default=False, help="Use hex file, this option should be used with '-f/--flash' option",
47-
)
4845
@click.option(
4946
"-s", "--sterm", is_flag=True, default=False, help="Launch a serial terminal to the device.",
5047
)
@@ -61,7 +58,6 @@ def build(
6158
mbed_target: str = "",
6259
clean: bool = False,
6360
flash: bool = False,
64-
hex_file: bool = False,
6561
sterm: bool = False,
6662
baudrate: int = 9600,
6763
mbed_os_path: str = None,
@@ -81,7 +77,6 @@ def build(
8177
mbed_target: The name of the Mbed target to build for.
8278
clean: Perform a clean build.
8379
flash: Flash the binary onto a device.
84-
hex_file: Use hex file, this option should be used with '-f/--flash' option.
8580
sterm: Open a serial terminal to the connected target.
8681
baudrate: Change the serial baud rate (ignored unless --sterm is also given).
8782
"""
@@ -100,7 +95,7 @@ def build(
10095
click.echo("Configuring project and generating build system...")
10196
if custom_targets_json is not None:
10297
program.files.custom_targets_json = pathlib.Path(custom_targets_json)
103-
generate_config(mbed_target.upper(), toolchain, program)
98+
config, _ = generate_config(mbed_target.upper(), toolchain, program)
10499
generate_build_system(program.root, build_tree, profile)
105100

106101
click.echo("Building Mbed project...")
@@ -114,10 +109,9 @@ def build(
114109

115110
if flash:
116111
for dev in devices:
112+
hex_file = "OUTPUT_EXT" in config and config["OUTPUT_EXT"] == "hex"
117113
flashed_path = flash_binary(dev.mount_points[0].resolve(), program.root, build_tree, mbed_target, hex_file)
118114
click.echo(f"Copied {str(flashed_path.resolve())} to {len(devices)} device(s).")
119-
elif hex_file:
120-
click.echo("'--hex-file' option should be used with '-f/--flash' option")
121115

122116
if sterm:
123117
dev = devices[0]

src/mbed_tools/cli/configure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,5 @@ def configure(
6767
program.files.cmake_build_dir = pathlib.Path(output_dir)
6868

6969
mbed_target = mbed_target.upper()
70-
output_path = generate_config(mbed_target, toolchain, program)
70+
_, output_path = generate_config(mbed_target, toolchain, program)
7171
click.echo(f"mbed_config.cmake has been generated and written to '{str(output_path.resolve())}'")

tests/cli/test_build.py

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ def test_calls_generate_build_system_if_build_tree_nonexistent(
6868
):
6969
program = mbed_program.from_existing()
7070
with mock_project_directory(program, mbed_config_exists=True, build_tree_exists=False):
71+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
72+
7173
runner = CliRunner()
7274
runner.invoke(build, DEFAULT_BUILD_ARGS)
7375

@@ -154,6 +156,8 @@ def test_build_system_regenerated_when_mbed_os_path_passed(
154156
build_tree_exists=True,
155157
build_subdir=pathlib.Path("K64F", "develop", "GCC_ARM"),
156158
):
159+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
160+
157161
toolchain = "gcc_arm"
158162
target = "k64f"
159163
mbed_os_path = "./extern/mbed-os"
@@ -189,6 +193,8 @@ def test_build_folder_removed_when_clean_flag_passed(
189193
build_tree_exists=True,
190194
build_subdir=pathlib.Path("K64F", "develop", "GCC_ARM"),
191195
):
196+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
197+
192198
toolchain = "gcc_arm"
193199
target = "k64f"
194200

@@ -201,31 +207,55 @@ def test_build_folder_removed_when_clean_flag_passed(
201207

202208
@mock.patch("mbed_tools.cli.build.flash_binary")
203209
@mock.patch("mbed_tools.cli.build.find_all_connected_devices")
204-
def test_build_flash_option(
205-
self, mock_find_devices, flash_binary, generate_config, mbed_program, build_project, generate_build_system
210+
def test_build_flash_options_bin_target(
211+
self,
212+
mock_find_devices,
213+
flash_binary,
214+
generate_config,
215+
mbed_program,
216+
build_project,
217+
generate_build_system,
206218
):
219+
# A target with bin images does not need OUTPUT_EXT defined
220+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
207221
mock_find_devices.return_value = [mock.MagicMock()]
208222
runner = CliRunner()
209223
runner.invoke(build, ["--flash", *DEFAULT_BUILD_ARGS])
210-
flash_binary.assert_called_once()
224+
call_args = flash_binary.call_args
225+
args, kwargs = call_args
226+
flash_binary.assert_called_once_with(args[0], args[1], args[2], args[3], False)
211227

212228
@mock.patch("mbed_tools.cli.build.flash_binary")
213229
@mock.patch("mbed_tools.cli.build.find_all_connected_devices")
214-
def test_build_flash_and_hex_file_options(
215-
self, mock_find_devices, flash_binary, generate_config, mbed_program, build_project, generate_build_system
230+
def test_build_flash_options_hex_target(
231+
self,
232+
mock_find_devices,
233+
flash_binary,
234+
generate_config,
235+
mbed_program,
236+
build_project,
237+
generate_build_system,
216238
):
239+
generate_config.return_value = [{"OUTPUT_EXT": "hex"}, mock.MagicMock()]
217240
mock_find_devices.return_value = [mock.MagicMock()]
218241
runner = CliRunner()
219-
runner.invoke(build, ["--flash", "--hex-file", *DEFAULT_BUILD_ARGS])
242+
runner.invoke(build, ["--flash", *DEFAULT_BUILD_ARGS])
220243
call_args = flash_binary.call_args
221244
args, kwargs = call_args
222245
flash_binary.assert_called_once_with(args[0], args[1], args[2], args[3], True)
223246

224247
@mock.patch("mbed_tools.cli.build.flash_binary")
225248
@mock.patch("mbed_tools.cli.build.find_all_connected_devices")
226249
def test_build_flash_both_two_devices(
227-
self, mock_find_devices, flash_binary, generate_config, mbed_program, build_project, generate_build_system
250+
self,
251+
mock_find_devices,
252+
flash_binary,
253+
generate_config,
254+
mbed_program,
255+
build_project,
256+
generate_build_system,
228257
):
258+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
229259
mock_find_devices.return_value = [mock.MagicMock(), mock.MagicMock()]
230260
runner = CliRunner()
231261
runner.invoke(build, ["--flash", *DEFAULT_BUILD_ARGS])
@@ -234,19 +264,20 @@ def test_build_flash_both_two_devices(
234264
@mock.patch("mbed_tools.cli.build.flash_binary")
235265
@mock.patch("mbed_tools.cli.build.find_connected_device")
236266
def test_build_flash_only_identifier_device(
237-
self, mock_find_device, flash_binary, generate_config, mbed_program, build_project, generate_build_system
267+
self,
268+
mock_find_device,
269+
flash_binary,
270+
generate_config,
271+
mbed_program,
272+
build_project,
273+
generate_build_system,
238274
):
275+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
239276
mock_find_device.return_value = mock.MagicMock()
240277
runner = CliRunner()
241278
runner.invoke(build, ["--flash", "-m", "K64F[1]", "-t", "GCC_ARM"])
242279
self.assertEqual(flash_binary.call_count, 1)
243280

244-
def test_build_only_hex_file_option(self, generate_config, mbed_program, build_project, generate_build_system):
245-
runner = CliRunner()
246-
result = runner.invoke(build, ["--hex-file", *DEFAULT_BUILD_ARGS])
247-
248-
self.assertRegex(result.output, "-f/--flash")
249-
250281
@mock.patch("mbed_tools.cli.build.terminal")
251282
@mock.patch("mbed_tools.cli.build.find_connected_device")
252283
def test_sterm_is_started_when_flag_passed(
@@ -256,6 +287,7 @@ def test_sterm_is_started_when_flag_passed(
256287
serial_port = "tty.k64f"
257288
baud = 115200
258289
mock_find_device.return_value = mock.Mock(serial_port=serial_port)
290+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
259291

260292
CliRunner().invoke(build, ["-m", target, "-t", "gcc_arm", "--sterm", "--baudrate", baud])
261293

@@ -270,6 +302,7 @@ def test_raises_if_device_does_not_have_serial_port_and_sterm_flag_given(
270302
target = "K64F"
271303
serial_port = None
272304
mock_find_device.return_value = mock.Mock(serial_port=serial_port)
305+
generate_config.return_value = [mock.MagicMock(), mock.MagicMock()]
273306

274307
output = CliRunner().invoke(build, ["-m", target, "-t", "gcc_arm", "--sterm"])
275308
self.assertEqual(type(output.exception), SystemExit)

0 commit comments

Comments
 (0)