Skip to content

New Feature: Flash Target Board #466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ The arguments for *compile* are:
* `--library` to compile the code as a [static .a/.ar library](#compiling-static-libraries).
* `--config` to inspect the runtime compile configuration (see below).
* `-S` or `--supported` shows a matrix of the supported targets and toolchains.
* `-f` or `--flash` to flash/program a connected target after successful compile.
* `-c ` to build from scratch, a clean build or rebuild.
* `-j <jobs>` to control the compile processes on your machine. The default value is 0, which infers the number of processes from the number of cores on your machine. You can use `-j 1` to trigger a sequential compile of source code.
* `-v` or `--verbose` for verbose diagnostic output.
Expand Down
51 changes: 40 additions & 11 deletions mbed/mbed.py
Original file line number Diff line number Diff line change
Expand Up @@ -1400,16 +1400,9 @@ def get_target(self, target=None):
target = target if target else target_cfg

if target and (target.lower() == 'detect' or target.lower() == 'auto'):
targets = self.get_detected_targets()
if targets == False:
error("The target detection requires that the 'mbed-ls' python module is installed.\nYou can install mbed-ls by running 'pip install mbed-ls'.")
elif len(targets) > 1:
error("Multiple targets were detected.\nOnly 1 target board should be connected to your system when you use the '-m auto' switch.")
elif len(targets) == 0:
error("No targets were detected.\nPlease make sure a target board is connected to this system.")
else:
action("Detected \"%s\" connected to \"%s\" and using com port \"%s\"" % (targets[0]['name'], targets[0]['mount'], targets[0]['serial']))
target = targets[0]['name']
detected = self.detect_target()
if detected:
target = detected['name']

if target is None:
error("Please specify target using the -m switch or set default target using command 'mbed target'", 1)
Expand Down Expand Up @@ -1447,6 +1440,22 @@ def ignore_build_dir(self):
except IOError:
error("Unable to write build ignore file in \"%s\"" % os.path.join(build_path, '.mbedignore'), 1)

def detect_target(self, info=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a valid case where you have multiple platforms plugged in, but all of them are different. This could be supported by supplying an optional target name to this function. Shouldn't be too hard to implement:

def detect_target(self, target_name=None, info=None):
    targets = self.get_detected_targets()

    if target_name:
        targets = [t for t in targets if t['name'].upper() == target_name.upper()]

    ...

(^Note that actual code is totally untested, but the idea should be sound)

But this can always be added in another PR. @screamerbg totally up to you on the priority of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use case for detecting multiple targets? Also what if I have multiple targets of the same kind mixed with different ones?

I guess I'm missing the point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Say I have a LPC1768, a K64F, and an NRF51_DK plugged into my machine. I could run mbed compile -m NRF51_DK ... --flash and mbed CLI could correctly figure out which board to flash. Can be useful when developing for multiple platforms, but maybe not important as of right now.

Also what if I have multiple targets of the same kind mixed with different ones?

In this case it would have to error like you do above since there are multiple boards (for example, 2 LPC1768s plugged in. You don't know which one to flash just by using the target name).

I'm afraid I'm hindering this PR more than I'm helping it with this comment. I'm happy to submit the change I mentioned above as a PR after this is merged for more discussion.

targets = self.get_detected_targets()
if targets == False:
error("The target detection requires that the 'mbed-ls' python module is installed.\nYou can install mbed-ls by running 'pip install mbed-ls'.", 1)
elif len(targets) > 1:
error("Multiple targets were detected.\nOnly 1 target board should be connected to your system.", 1)
elif len(targets) == 0:
error("No targets were detected.\nPlease make sure a target board is connected to this system.", 1)
else:
action("Detected \"%s\" connected to \"%s\" and using com port \"%s\"" % (targets[0]['name'], targets[0]['mount'], targets[0]['serial']))
info = {'msd': targets[0]['mount'], 'port': targets[0]['serial'], 'name': targets[0]['name']}

if info is None:
error("The detected target doesn't support Mass Storage Device capability (MSD)", 1)
return info

def get_detected_targets(self):
targets = []
try:
Expand Down Expand Up @@ -2137,12 +2146,13 @@ def status_(ignore=False):
dict(name='--source', action='append', help='Source directory. Default: . (current dir)'),
dict(name='--build', help='Build directory. Default: build/'),
dict(name=['-c', '--clean'], action='store_true', help='Clean the build directory before compiling'),
dict(name=['-f', '--flash'], action='store_true', help='Flash the built firmware onto a connected target.'),
dict(name=['-N', '--artifact-name'], help='Name of the built program or library'),
dict(name=['-S', '--supported'], dest='supported', action='store_true', help='Shows supported matrix of targets and toolchains'),
dict(name='--app-config', dest="app_config", help="Path of an app configuration file (Default is to look for 'mbed_app.json')"),
help='Compile code using the mbed build tools',
description=("Compile this program using the mbed build tools."))
def compile_(toolchain=None, target=None, profile=False, compile_library=False, compile_config=False, config_prefix=None, source=False, build=False, clean=False, artifact_name=None, supported=False, app_config=None):
def compile_(toolchain=None, target=None, profile=False, compile_library=False, compile_config=False, config_prefix=None, source=False, build=False, clean=False, flash=False, artifact_name=None, supported=False, app_config=None):
# Gather remaining arguments
args = remainder
# Find the root of the program
Expand Down Expand Up @@ -2221,6 +2231,25 @@ def compile_(toolchain=None, target=None, profile=False, compile_library=False,
+ (['-v'] if verbose else [])
+ args,
env=env)

if flash:
fw_name = artifact_name if artifact_name else program.name
fw_fbase = os.path.join(build_path, fw_name)
fw_file = fw_fbase + ('.hex' if os.path.exists(fw_fbase+'.hex') else '.bin')
if not os.path.exists(fw_file):
error("Build program file (firmware) not found \"%s\"" % fw_file, 1)
detected = program.detect_target()

try:
from mbed_host_tests.host_tests_toolbox import flash_dev, reset_dev
except (IOError, ImportError, OSError):
error("The '-f/--flash' option requires that the 'mbed-greentea' python module is installed.\nYou can install mbed-ls by running 'pip install mbed-greentea'.", 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really part of the mbed-host-tests module, not mbed-greentea. mbed-greentea will correctly bring in this dependency though. So it's ok to leave this as is I think, but just thought I'd mention it.

Copy link
Contributor Author

@screamerbg screamerbg Mar 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The developer never installs mbed-host-tests manually, neither is familiar with this module. Generally we would like to point developer at installing mbed-greentea as foundation of mbed OS testing, not specifically mbed-host-tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me!


if not flash_dev(detected['msd'], fw_file, program_cycle_s=2):
error("Unable to flash the target board connected to your system.", 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might also prompt the user to check for a FAIL.TXT on the board for more information. Not necessary though.

Copy link
Contributor Author

@screamerbg screamerbg Mar 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not have that check that in htrun instead, and have the top flash_dev() function handle it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, also a possibility. Like I said, not necessary and should't block this PR.


if not reset_dev(detected['port']):
error("Unable to reset the target board connected to your system.\nThis might be caused by an old interface firmware.\nPlease check the board page for new firmware.", 1)

program.set_defaults(target=target, toolchain=tchain)

Expand Down