Knight KE / Mbed OS Game_Master
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.notifier.term import TerminalNotifier
00049 from tools.build_api import build_project
00050 from tools.build_api import mcu_toolchain_matrix
00051 from tools.build_api import mcu_toolchain_list
00052 from tools.build_api import mcu_target_list
00053 from tools.build_api import merge_build_data
00054 from utils import argparse_filestring_type
00055 from utils import argparse_many
00056 from utils import argparse_dir_not_parent
00057 from tools.toolchains import mbedToolchain, TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
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("--ignore", dest="ignore", type=argparse_many(str),
00144                         default=None, help="Comma separated list of patterns to add to mbedignore (eg. ./main.cpp)")
00145     parser.add_argument("-d", "--disk", dest="disk",
00146                       default=None, help="The mbed disk")
00147     parser.add_argument("-s", "--serial", dest="serial",
00148                       default=None, help="The mbed serial port")
00149     parser.add_argument("-b", "--baud", type=int, dest="baud",
00150                       default=None, help="The mbed serial baud rate")
00151     group.add_argument("-L", "--list-tests", action="store_true", dest="list_tests",
00152                       default=False, help="List available tests in order and exit")
00153 
00154     # Ideally, all the tests with a single "main" thread can be run with, or
00155     # without the usb, dsp
00156     parser.add_argument("--rpc",
00157                       action="store_true", dest="rpc",
00158                       default=False, help="Link with RPC library")
00159 
00160     parser.add_argument("--usb",
00161                       action="store_true",
00162                       dest="usb",
00163                       default=False,
00164                       help="Link with USB Device library")
00165 
00166     parser.add_argument("--dsp",
00167                       action="store_true",
00168                       dest="dsp",
00169                       default=False,
00170                       help="Link with DSP library")
00171 
00172     parser.add_argument("--testlib",
00173                       action="store_true",
00174                       dest="testlib",
00175                       default=False,
00176                       help="Link with mbed test library")
00177 
00178     parser.add_argument("--build-data",
00179                         dest="build_data",
00180                         default=None,
00181                         help="Dump build_data to this file")
00182 
00183     # Specify a different linker script
00184     parser.add_argument("-l", "--linker", dest="linker_script",
00185                       type=argparse_filestring_type,
00186                       default=None, help="use the specified linker script")
00187 
00188     options = parser.parse_args()
00189 
00190     # Only prints matrix of supported toolchains
00191     if options.supported_toolchains:
00192         if options.supported_toolchains == "matrix":
00193             print(mcu_toolchain_matrix(platform_filter=options.general_filter_regex))
00194         elif options.supported_toolchains == "toolchains":
00195             toolchain_list = mcu_toolchain_list()
00196             # Only print the lines that matter
00197             for line in toolchain_list.split("\n"):
00198                 if not "mbed" in line:
00199                     print(line)
00200         elif options.supported_toolchains == "targets":
00201             print(mcu_target_list())
00202         exit(0)
00203 
00204     # Print available tests in order and exit
00205     if options.list_tests is True:
00206         print('\n'.join(map(str, sorted(TEST_MAP.values()))))
00207         sys.exit()
00208 
00209     # force program to "0" if a source dir is specified
00210     if options.source_dir is not None:
00211         p = 0
00212     else:
00213     # Program Number or name
00214         p = options.program
00215 
00216     # If 'p' was set via -n to list of numbers make this a single element integer list
00217     if type(p) != type([]):
00218         p = [p]
00219 
00220     # Target
00221     if options.mcu is None :
00222         args_error(parser, "argument -m/--mcu is required")
00223     mcu = extract_mcus(parser, options)[0]
00224 
00225     # Toolchain
00226     if options.tool is None:
00227         args_error(parser, "argument -t/--tool is required")
00228     toolchain = options.tool[0]
00229 
00230     if (options.program is None) and (not options.source_dir):
00231         args_error(parser, "one of -p, -n, or --source is required")
00232 
00233     if options.source_dir and not options.build_dir:
00234         args_error(parser, "argument --build is required when argument --source is provided")
00235 
00236 
00237     notify = TerminalNotifier(options.verbose, options.silent, options.color)
00238 
00239     if not TOOLCHAIN_CLASSES[toolchain].check_executable():
00240         search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
00241         args_error(parser, "Could not find executable for %s.\n"
00242                            "Currently set search path: %s"
00243                            %(toolchain, search_path))
00244 
00245     # Test
00246     build_data_blob = {} if options.build_data else None
00247     for test_no in p:
00248         test = Test(test_no)
00249         if options.automated is not None:    test.automated = options.automated
00250         if options.dependencies is not None: test.dependencies = options.dependencies
00251         if options.host_test is not None:    test.host_test = options.host_test;
00252         if options.peripherals is not None:  test.peripherals = options.peripherals;
00253         if options.duration is not None:     test.duration = options.duration;
00254         if options.extra is not None:        test.extra_files = options.extra
00255 
00256         if not test.is_supported(mcu, toolchain):
00257             print('The selected test is not supported on target %s with toolchain %s' % (mcu, toolchain))
00258             sys.exit()
00259 
00260         # Linking with extra libraries
00261         if options.rpc:      test.dependencies.append(RPC_LIBRARY)
00262         if options.usb:      test.dependencies.append(USB_LIBRARIES)
00263         if options.dsp:      test.dependencies.append(DSP_LIBRARIES)
00264         if options.testlib:  test.dependencies.append(TEST_MBED_LIB)
00265 
00266         build_dir = join(BUILD_DIR, "test", mcu, toolchain, test.id)
00267         if options.source_dir is not None:
00268             test.source_dir = options.source_dir
00269             build_dir = options.source_dir
00270 
00271         if options.build_dir is not None:
00272             build_dir = options.build_dir
00273 
00274         try:
00275             bin_file = build_project(test.source_dir, build_dir, mcu, toolchain,
00276                                      set(test.dependencies),
00277                                      linker_script=options.linker_script,
00278                                      clean=options.clean,
00279                                      notify=notify,
00280                                      report=build_data_blob,
00281                                      macros=options.macros,
00282                                      jobs=options.jobs,
00283                                      name=options.artifact_name,
00284                                      app_config=options.app_config,
00285                                      inc_dirs=[dirname(MBED_LIBRARIES)],
00286                                      build_profile=extract_profile(parser,
00287                                                                    options,
00288                                                                    toolchain),
00289                                      stats_depth=options.stats_depth,
00290                                      ignore=options.ignore)
00291             print('Image: %s'% bin_file)
00292 
00293             if options.disk:
00294                 # Simple copy to the mbed disk
00295                 copy(bin_file, options.disk)
00296 
00297             if options.serial:
00298                 # Import pyserial: https://pypi.python.org/pypi/pyserial
00299                 from serial import Serial
00300 
00301                 sleep(TARGET_MAP[mcu].program_cycle_s)
00302 
00303                 serial = Serial(options.serial, timeout = 1)
00304                 if options.baud:
00305                     serial.setBaudrate(options.baud)
00306 
00307                 serial.flushInput()
00308                 serial.flushOutput()
00309 
00310                 try:
00311                     serial.sendBreak()
00312                 except:
00313                     # In linux a termios.error is raised in sendBreak and in setBreak.
00314                     # The following setBreak() is needed to release the reset signal on the target mcu.
00315                     try:
00316                         serial.setBreak(False)
00317                     except:
00318                         pass
00319 
00320                 while True:
00321                     c = serial.read(512)
00322                     sys.stdout.write(c)
00323                     sys.stdout.flush()
00324 
00325         except KeyboardInterrupt as e:
00326             print("\n[CTRL+c] exit")
00327         except NotSupportedException as e:
00328             print("\nCould not compile for %s: %s" % (mcu, str(e)))
00329         except Exception as e:
00330             if options.verbose:
00331                 import traceback
00332                 traceback.print_exc(file=sys.stdout)
00333             else:
00334                 print("[ERROR] %s" % str(e))
00335 
00336             sys.exit(1)
00337     if options.build_data:
00338         merge_build_data(options.build_data, build_data_blob, "application")