BA / Mbed OS BaBoRo1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers make.py Source File

make.py

00001 #! /usr/bin/env python2
00002 """
00003 mbed SDK
00004 Copyright (c) 2011-2013 ARM Limited
00005 
00006 Licensed under the Apache License, Version 2.0 (the "License");
00007 you may not use this file except in compliance with the License.
00008 You may obtain a copy of the License at
00009 
00010     http://www.apache.org/licenses/LICENSE-2.0
00011 
00012 Unless required by applicable law or agreed to in writing, software
00013 distributed under the License is distributed on an "AS IS" BASIS,
00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 See the License for the specific language governing permissions and
00016 limitations under the License.
00017 
00018 
00019 TEST BUILD & RUN
00020 """
00021 from __future__ import print_function
00022 from builtins import str
00023 import sys
00024 import json
00025 from time import sleep
00026 from shutil import copy
00027 from os.path import join, abspath, dirname
00028 from json import load, dump
00029 
00030 # Be sure that the tools directory is in the search path
00031 ROOT = abspath(join(dirname(__file__), ".."))
00032 sys.path.insert(0, ROOT)
00033 
00034 from tools.utils import args_error
00035 from tools.utils import NotSupportedException
00036 from tools.paths import BUILD_DIR
00037 from tools.paths import MBED_LIBRARIES
00038 from tools.paths import RPC_LIBRARY
00039 from tools.paths import USB_LIBRARIES
00040 from tools.paths import DSP_LIBRARIES
00041 from tools.tests import TESTS, Test, TEST_MAP
00042 from tools.tests import TEST_MBED_LIB
00043 from tools.tests import test_known, test_name_known
00044 from tools.targets import TARGET_MAP
00045 from tools.options import get_default_options_parser
00046 from tools.options import extract_profile
00047 from tools.options import extract_mcus
00048 from tools.build_api import build_project
00049 from tools.build_api import mcu_toolchain_matrix
00050 from tools.build_api import mcu_toolchain_list
00051 from tools.build_api import mcu_target_list
00052 from tools.build_api import merge_build_data
00053 from utils import argparse_filestring_type
00054 from utils import argparse_many
00055 from utils import argparse_dir_not_parent
00056 from tools.toolchains import mbedToolchain, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
00057 from tools.settings import CLI_COLOR_MAP
00058 
00059 if __name__ == '__main__':
00060     # Parse Options
00061     parser = get_default_options_parser(add_app_config=True)
00062     group = parser.add_mutually_exclusive_group(required=False)
00063     group.add_argument(
00064         "-p",
00065         type=argparse_many(test_known),
00066         dest="program",
00067         help="The index of the desired test program: [0-%d]" % (len(TESTS)-1))
00068 
00069     group.add_argument(
00070         "-n",
00071         type=argparse_many(test_name_known),
00072         dest="program",
00073         help="The name of the desired test program")
00074 
00075     parser.add_argument(
00076         "-j", "--jobs",
00077         type=int,
00078         dest="jobs",
00079         default=0,
00080         help="Number of concurrent jobs. Default: 0/auto (based on host machine's number of CPUs)")
00081 
00082     parser.add_argument(
00083         "-v", "--verbose",
00084         action="store_true",
00085         dest="verbose",
00086         default=False,
00087         help="Verbose diagnostic output")
00088 
00089     parser.add_argument(
00090         "--silent",
00091         action="store_true",
00092         dest="silent",
00093         default=False,
00094         help="Silent diagnostic output (no copy, compile notification)")
00095 
00096     parser.add_argument(
00097         "-D",
00098         action="append",
00099         dest="macros",
00100         help="Add a macro definition")
00101 
00102     group.add_argument(
00103         "-S", "--supported-toolchains",
00104         dest="supported_toolchains",
00105         default=False,
00106         const="matrix",
00107         choices=["matrix", "toolchains", "targets"],
00108         nargs="?",
00109         help="Displays supported matrix of MCUs and toolchains")
00110 
00111     parser.add_argument(
00112         '-f', '--filter',
00113         dest='general_filter_regex',
00114         default=None,
00115         help='For some commands you can use filter to filter out results')
00116 
00117     parser.add_argument(
00118         "--stats-depth",
00119         type=int,
00120         dest="stats_depth",
00121         default=2,
00122         help="Depth level for static memory report")
00123 
00124     # Local run
00125     parser.add_argument("--automated", action="store_true", dest="automated",
00126                       default=False, help="Automated test")
00127     parser.add_argument("--host", dest="host_test",
00128                       default=None, help="Host test")
00129     parser.add_argument("--extra", dest="extra",
00130                       default=None, help="Extra files")
00131     parser.add_argument("--peripherals", dest="peripherals",
00132                       default=None, help="Required peripherals")
00133     parser.add_argument("--dep", dest="dependencies",
00134                       default=None, help="Dependencies")
00135     parser.add_argument("--source", dest="source_dir", type=argparse_filestring_type,
00136                        default=None, help="The source (input) directory", action="append")
00137     parser.add_argument("--duration", type=int, dest="duration",
00138                       default=None, help="Duration of the test")
00139     parser.add_argument("--build", dest="build_dir", type=argparse_dir_not_parent(ROOT),
00140                       default=None, help="The build (output) directory")
00141     parser.add_argument("-N", "--artifact-name", dest="artifact_name",
00142                       default=None, help="The built project's name")
00143     parser.add_argument("-d", "--disk", dest="disk",
00144                       default=None, help="The mbed disk")
00145     parser.add_argument("-s", "--serial", dest="serial",
00146                       default=None, help="The mbed serial port")
00147     parser.add_argument("-b", "--baud", type=int, dest="baud",
00148                       default=None, help="The mbed serial baud rate")
00149     group.add_argument("-L", "--list-tests", action="store_true", dest="list_tests",
00150                       default=False, help="List available tests in order and exit")
00151 
00152     # Ideally, all the tests with a single "main" thread can be run with, or
00153     # without the usb, dsp
00154     parser.add_argument("--rpc",
00155                       action="store_true", dest="rpc",
00156                       default=False, help="Link with RPC library")
00157 
00158     parser.add_argument("--usb",
00159                       action="store_true",
00160                       dest="usb",
00161                       default=False,
00162                       help="Link with USB Device library")
00163 
00164     parser.add_argument("--dsp",
00165                       action="store_true",
00166                       dest="dsp",
00167                       default=False,
00168                       help="Link with DSP library")
00169 
00170     parser.add_argument("--testlib",
00171                       action="store_true",
00172                       dest="testlib",
00173                       default=False,
00174                       help="Link with mbed test library")
00175 
00176     parser.add_argument("--build-data",
00177                         dest="build_data",
00178                         default=None,
00179                         help="Dump build_data to this file")
00180 
00181     # Specify a different linker script
00182     parser.add_argument("-l", "--linker", dest="linker_script",
00183                       type=argparse_filestring_type,
00184                       default=None, help="use the specified linker script")
00185 
00186     options = parser.parse_args()
00187 
00188     # Only prints matrix of supported toolchains
00189     if options.supported_toolchains:
00190         if options.supported_toolchains == "matrix":
00191             print(mcu_toolchain_matrix(platform_filter=options.general_filter_regex))
00192         elif options.supported_toolchains == "toolchains":
00193             toolchain_list = mcu_toolchain_list()
00194             # Only print the lines that matter
00195             for line in toolchain_list.split("\n"):
00196                 if not "mbed" in line:
00197                     print(line)
00198         elif options.supported_toolchains == "targets":
00199             print(mcu_target_list())
00200         exit(0)
00201 
00202     # Print available tests in order and exit
00203     if options.list_tests is True:
00204         print('\n'.join(map(str, sorted(TEST_MAP.values()))))
00205         sys.exit()
00206 
00207     # force program to "0" if a source dir is specified
00208     if options.source_dir is not None:
00209         p = 0
00210     else:
00211     # Program Number or name
00212         p = options.program
00213 
00214     # If 'p' was set via -n to list of numbers make this a single element integer list
00215     if type(p) != type([]):
00216         p = [p]
00217 
00218     # Target
00219     if options.mcu is None :
00220         args_error(parser, "argument -m/--mcu is required")
00221     mcu = extract_mcus(parser, options)[0]
00222 
00223     # Toolchain
00224     if options.tool is None:
00225         args_error(parser, "argument -t/--tool is required")
00226     toolchain = options.tool[0]
00227 
00228     if (options.program is None) and (not options.source_dir):
00229         args_error(parser, "one of -p, -n, or --source is required")
00230 
00231     if options.source_dir and not options.build_dir:
00232         args_error(parser, "argument --build is required when argument --source is provided")
00233 
00234 
00235     if options.color:
00236         # This import happens late to prevent initializing colorization when we don't need it
00237         import colorize
00238         if options.verbose:
00239             notify = mbedToolchain.print_notify_verbose
00240         else:
00241             notify = mbedToolchain.print_notify
00242         notify = colorize.print_in_color_notifier(CLI_COLOR_MAP, notify)
00243     else:
00244         notify = None
00245 
00246     if not TOOLCHAIN_CLASSES[toolchain].check_executable():
00247         search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
00248         args_error(parser, "Could not find executable for %s.\n"
00249                            "Currently set search path: %s"
00250                            %(toolchain, search_path))
00251 
00252     # Test
00253     build_data_blob = {} if options.build_data else None
00254     for test_no in p:
00255         test = Test(test_no)
00256         if options.automated is not None:    test.automated = options.automated
00257         if options.dependencies is not None: test.dependencies = options.dependencies
00258         if options.host_test is not None:    test.host_test = options.host_test;
00259         if options.peripherals is not None:  test.peripherals = options.peripherals;
00260         if options.duration is not None:     test.duration = options.duration;
00261         if options.extra is not None:        test.extra_files = options.extra
00262 
00263         if not test.is_supported(mcu, toolchain):
00264             print('The selected test is not supported on target %s with toolchain %s' % (mcu, toolchain))
00265             sys.exit()
00266 
00267         # Linking with extra libraries
00268         if options.rpc:      test.dependencies.append(RPC_LIBRARY)
00269         if options.usb:      test.dependencies.append(USB_LIBRARIES)
00270         if options.dsp:      test.dependencies.append(DSP_LIBRARIES)
00271         if options.testlib:  test.dependencies.append(TEST_MBED_LIB)
00272 
00273         build_dir = join(BUILD_DIR, "test", mcu, toolchain, test.id)
00274         if options.source_dir is not None:
00275             test.source_dir = options.source_dir
00276             build_dir = options.source_dir
00277 
00278         if options.build_dir is not None:
00279             build_dir = options.build_dir
00280 
00281         try:
00282             bin_file = build_project(test.source_dir, build_dir, mcu, toolchain,
00283                                      set(test.dependencies),
00284                                      linker_script=options.linker_script,
00285                                      clean=options.clean,
00286                                      verbose=options.verbose,
00287                                      notify=notify,
00288                                      report=build_data_blob,
00289                                      silent=options.silent,
00290                                      macros=options.macros,
00291                                      jobs=options.jobs,
00292                                      name=options.artifact_name,
00293                                      app_config=options.app_config,
00294                                      inc_dirs=[dirname(MBED_LIBRARIES)],
00295                                      build_profile=extract_profile(parser,
00296                                                                    options,
00297                                                                    toolchain),
00298                                      stats_depth=options.stats_depth)
00299             print('Image: %s'% bin_file)
00300 
00301             if options.disk:
00302                 # Simple copy to the mbed disk
00303                 copy(bin_file, options.disk)
00304 
00305             if options.serial:
00306                 # Import pyserial: https://pypi.python.org/pypi/pyserial
00307                 from serial import Serial
00308 
00309                 sleep(TARGET_MAP[mcu].program_cycle_s)
00310 
00311                 serial = Serial(options.serial, timeout = 1)
00312                 if options.baud:
00313                     serial.setBaudrate(options.baud)
00314 
00315                 serial.flushInput()
00316                 serial.flushOutput()
00317 
00318                 try:
00319                     serial.sendBreak()
00320                 except:
00321                     # In linux a termios.error is raised in sendBreak and in setBreak.
00322                     # The following setBreak() is needed to release the reset signal on the target mcu.
00323                     try:
00324                         serial.setBreak(False)
00325                     except:
00326                         pass
00327 
00328                 while True:
00329                     c = serial.read(512)
00330                     sys.stdout.write(c)
00331                     sys.stdout.flush()
00332 
00333         except KeyboardInterrupt as e:
00334             print("\n[CTRL+c] exit")
00335         except NotSupportedException as e:
00336             print("\nCould not compile for %s: %s" % (mcu, str(e)))
00337         except Exception as e:
00338             if options.verbose:
00339                 import traceback
00340                 traceback.print_exc(file=sys.stdout)
00341             else:
00342                 print("[ERROR] %s" % str(e))
00343 
00344             sys.exit(1)
00345     if options.build_data:
00346         merge_build_data(options.build_data, build_data_blob, "application")