mbed-os
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
Diff: tools/make.py
- Revision:
- 0:b74591d5ab33
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/make.py Mon Dec 11 17:54:04 2017 +0000 @@ -0,0 +1,344 @@ +#! /usr/bin/env python2 +""" +mbed SDK +Copyright (c) 2011-2013 ARM Limited + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +TEST BUILD & RUN +""" +import sys +import json +from time import sleep +from shutil import copy +from os.path import join, abspath, dirname +from json import load, dump + +# Be sure that the tools directory is in the search path +ROOT = abspath(join(dirname(__file__), "..")) +sys.path.insert(0, ROOT) + +from tools.utils import args_error +from tools.utils import NotSupportedException +from tools.paths import BUILD_DIR +from tools.paths import MBED_LIBRARIES +from tools.paths import RPC_LIBRARY +from tools.paths import USB_LIBRARIES +from tools.paths import DSP_LIBRARIES +from tools.tests import TESTS, Test, TEST_MAP +from tools.tests import TEST_MBED_LIB +from tools.tests import test_known, test_name_known +from tools.targets import TARGET_MAP +from tools.options import get_default_options_parser +from tools.options import extract_profile +from tools.options import extract_mcus +from tools.build_api import build_project +from tools.build_api import mcu_toolchain_matrix +from tools.build_api import mcu_toolchain_list +from tools.build_api import mcu_target_list +from tools.build_api import merge_build_data +from utils import argparse_filestring_type +from utils import argparse_many +from utils import argparse_dir_not_parent +from tools.toolchains import mbedToolchain, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS +from tools.settings import CLI_COLOR_MAP + +if __name__ == '__main__': + # Parse Options + parser = get_default_options_parser(add_app_config=True) + group = parser.add_mutually_exclusive_group(required=False) + group.add_argument( + "-p", + type=argparse_many(test_known), + dest="program", + help="The index of the desired test program: [0-%d]" % (len(TESTS)-1)) + + group.add_argument( + "-n", + type=argparse_many(test_name_known), + dest="program", + help="The name of the desired test program") + + parser.add_argument( + "-j", "--jobs", + type=int, + dest="jobs", + default=0, + help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)") + + parser.add_argument( + "-v", "--verbose", + action="store_true", + dest="verbose", + default=False, + help="Verbose diagnostic output") + + parser.add_argument( + "--silent", + action="store_true", + dest="silent", + default=False, + help="Silent diagnostic output (no copy, compile notification)") + + parser.add_argument( + "-D", + action="append", + dest="macros", + help="Add a macro definition") + + group.add_argument( + "-S", "--supported-toolchains", + dest="supported_toolchains", + default=False, + const="matrix", + choices=["matrix", "toolchains", "targets"], + nargs="?", + help="Displays supported matrix of MCUs and toolchains") + + parser.add_argument( + '-f', '--filter', + dest='general_filter_regex', + default=None, + help='For some commands you can use filter to filter out results') + + parser.add_argument( + "--stats-depth", + type=int, + dest="stats_depth", + default=2, + help="Depth level for static memory report") + + # Local run + parser.add_argument("--automated", action="store_true", dest="automated", + default=False, help="Automated test") + parser.add_argument("--host", dest="host_test", + default=None, help="Host test") + parser.add_argument("--extra", dest="extra", + default=None, help="Extra files") + parser.add_argument("--peripherals", dest="peripherals", + default=None, help="Required peripherals") + parser.add_argument("--dep", dest="dependencies", + default=None, help="Dependencies") + parser.add_argument("--source", dest="source_dir", type=argparse_filestring_type, + default=None, help="The source (input) directory", action="append") + parser.add_argument("--duration", type=int, dest="duration", + default=None, help="Duration of the test") + parser.add_argument("--build", dest="build_dir", type=argparse_dir_not_parent(ROOT), + default=None, help="The build (output) directory") + parser.add_argument("-N", "--artifact-name", dest="artifact_name", + default=None, help="The built project's name") + parser.add_argument("-d", "--disk", dest="disk", + default=None, help="The mbed disk") + parser.add_argument("-s", "--serial", dest="serial", + default=None, help="The mbed serial port") + parser.add_argument("-b", "--baud", type=int, dest="baud", + default=None, help="The mbed serial baud rate") + group.add_argument("-L", "--list-tests", action="store_true", dest="list_tests", + default=False, help="List available tests in order and exit") + + # Ideally, all the tests with a single "main" thread can be run with, or + # without the usb, dsp + parser.add_argument("--rpc", + action="store_true", dest="rpc", + default=False, help="Link with RPC library") + + parser.add_argument("--usb", + action="store_true", + dest="usb", + default=False, + help="Link with USB Device library") + + parser.add_argument("--dsp", + action="store_true", + dest="dsp", + default=False, + help="Link with DSP library") + + parser.add_argument("--testlib", + action="store_true", + dest="testlib", + default=False, + help="Link with mbed test library") + + parser.add_argument("--build-data", + dest="build_data", + default=None, + help="Dump build_data to this file") + + # Specify a different linker script + parser.add_argument("-l", "--linker", dest="linker_script", + type=argparse_filestring_type, + default=None, help="use the specified linker script") + + options = parser.parse_args() + + # Only prints matrix of supported toolchains + if options.supported_toolchains: + if options.supported_toolchains == "matrix": + print mcu_toolchain_matrix(platform_filter=options.general_filter_regex) + elif options.supported_toolchains == "toolchains": + toolchain_list = mcu_toolchain_list() + # Only print the lines that matter + for line in toolchain_list.split("\n"): + if not "mbed" in line: + print line + elif options.supported_toolchains == "targets": + print mcu_target_list() + exit(0) + + # Print available tests in order and exit + if options.list_tests is True: + print '\n'.join(map(str, sorted(TEST_MAP.values()))) + sys.exit() + + # force program to "0" if a source dir is specified + if options.source_dir is not None: + p = 0 + else: + # Program Number or name + p = options.program + + # If 'p' was set via -n to list of numbers make this a single element integer list + if type(p) != type([]): + p = [p] + + # Target + if options.mcu is None : + args_error(parser, "argument -m/--mcu is required") + mcu = extract_mcus(parser, options)[0] + + # Toolchain + if options.tool is None: + args_error(parser, "argument -t/--tool is required") + toolchain = options.tool[0] + + if (options.program is None) and (not options.source_dir): + args_error(parser, "one of -p, -n, or --source is required") + + if options.source_dir and not options.build_dir: + args_error(parser, "argument --build is required when argument --source is provided") + + + if options.color: + # This import happens late to prevent initializing colorization when we don't need it + import colorize + if options.verbose: + notify = mbedToolchain.print_notify_verbose + else: + notify = mbedToolchain.print_notify + notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify) + else: + notify = None + + if not TOOLCHAIN_CLASSES[toolchain].check_executable(): + search_path = TOOLCHAIN_PATHS[toolchain] or "No path set" + args_error(parser, "Could not find executable for %s.\n" + "Currently set search path: %s" + %(toolchain,search_path)) + + # Test + build_data_blob = {} if options.build_data else None + for test_no in p: + test = Test(test_no) + if options.automated is not None: test.automated = options.automated + if options.dependencies is not None: test.dependencies = options.dependencies + if options.host_test is not None: test.host_test = options.host_test; + if options.peripherals is not None: test.peripherals = options.peripherals; + if options.duration is not None: test.duration = options.duration; + if options.extra is not None: test.extra_files = options.extra + + if not test.is_supported(mcu, toolchain): + print 'The selected test is not supported on target %s with toolchain %s' % (mcu, toolchain) + sys.exit() + + # Linking with extra libraries + if options.rpc: test.dependencies.append(RPC_LIBRARY) + if options.usb: test.dependencies.append(USB_LIBRARIES) + if options.dsp: test.dependencies.append(DSP_LIBRARIES) + if options.testlib: test.dependencies.append(TEST_MBED_LIB) + + build_dir = join(BUILD_DIR, "test", mcu, toolchain, test.id) + if options.source_dir is not None: + test.source_dir = options.source_dir + build_dir = options.source_dir + + if options.build_dir is not None: + build_dir = options.build_dir + + try: + bin_file = build_project(test.source_dir, build_dir, mcu, toolchain, + set(test.dependencies), + linker_script=options.linker_script, + clean=options.clean, + verbose=options.verbose, + notify=notify, + report=build_data_blob, + silent=options.silent, + macros=options.macros, + jobs=options.jobs, + name=options.artifact_name, + app_config=options.app_config, + inc_dirs=[dirname(MBED_LIBRARIES)], + build_profile=extract_profile(parser, + options, + toolchain), + stats_depth=options.stats_depth) + print 'Image: %s'% bin_file + + if options.disk: + # Simple copy to the mbed disk + copy(bin_file, options.disk) + + if options.serial: + # Import pyserial: https://pypi.python.org/pypi/pyserial + from serial import Serial + + sleep(TARGET_MAP[mcu].program_cycle_s) + + serial = Serial(options.serial, timeout = 1) + if options.baud: + serial.setBaudrate(options.baud) + + serial.flushInput() + serial.flushOutput() + + try: + serial.sendBreak() + except: + # In linux a termios.error is raised in sendBreak and in setBreak. + # The following setBreak() is needed to release the reset signal on the target mcu. + try: + serial.setBreak(False) + except: + pass + + while True: + c = serial.read(512) + sys.stdout.write(c) + sys.stdout.flush() + + except KeyboardInterrupt, e: + print "\n[CTRL+c] exit" + except NotSupportedException as e: + print "\nCould not compile for %s: %s" % (mcu, str(e)) + except Exception,e: + if options.verbose: + import traceback + traceback.print_exc(file=sys.stdout) + else: + print "[ERROR] %s" % str(e) + + sys.exit(1) + if options.build_data: + merge_build_data(options.build_data, build_data_blob, "application")