Nicolas Borla / Mbed OS BBR_1Ebene
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("-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     notify = TerminalNotifier(options.verbose, options.silent, options.color)
00236 
00237     if not TOOLCHAIN_CLASSES[toolchain].check_executable():
00238         search_path = TOOLCHAIN_PATHS[toolchain] or "No path set"
00239         args_error(parser, "Could not find executable for %s.\n"
00240                            "Currently set search path: %s"
00241                            %(toolchain, search_path))
00242 
00243     # Test
00244     build_data_blob = {} if options.build_data else None
00245     for test_no in p:
00246         test = Test(test_no)
00247         if options.automated is not None:    test.automated = options.automated
00248         if options.dependencies is not None: test.dependencies = options.dependencies
00249         if options.host_test is not None:    test.host_test = options.host_test;
00250         if options.peripherals is not None:  test.peripherals = options.peripherals;
00251         if options.duration is not None:     test.duration = options.duration;
00252         if options.extra is not None:        test.extra_files = options.extra
00253 
00254         if not test.is_supported(mcu, toolchain):
00255             print('The selected test is not supported on target %s with toolchain %s' % (mcu, toolchain))
00256             sys.exit()
00257 
00258         # Linking with extra libraries
00259         if options.rpc:      test.dependencies.append(RPC_LIBRARY)
00260         if options.usb:      test.dependencies.append(USB_LIBRARIES)
00261         if options.dsp:      test.dependencies.append(DSP_LIBRARIES)
00262         if options.testlib:  test.dependencies.append(TEST_MBED_LIB)
00263 
00264         build_dir = join(BUILD_DIR, "test", mcu, toolchain, test.id)
00265         if options.source_dir is not None:
00266             test.source_dir = options.source_dir
00267             build_dir = options.source_dir
00268 
00269         if options.build_dir is not None:
00270             build_dir = options.build_dir
00271 
00272         try:
00273             bin_file = build_project(test.source_dir, build_dir, mcu, toolchain,
00274                                      set(test.dependencies),
00275                                      linker_script=options.linker_script,
00276                                      clean=options.clean,
00277                                      notify=notify,
00278                                      report=build_data_blob,
00279                                      macros=options.macros,
00280                                      jobs=options.jobs,
00281                                      name=options.artifact_name,
00282                                      app_config=options.app_config,
00283                                      inc_dirs=[dirname(MBED_LIBRARIES)],
00284                                      build_profile=extract_profile(parser,
00285                                                                    options,
00286                                                                    toolchain),
00287                                      stats_depth=options.stats_depth)
00288             print('Image: %s'% bin_file)
00289 
00290             if options.disk:
00291                 # Simple copy to the mbed disk
00292                 copy(bin_file, options.disk)
00293 
00294             if options.serial:
00295                 # Import pyserial: https://pypi.python.org/pypi/pyserial
00296                 from serial import Serial
00297 
00298                 sleep(TARGET_MAP[mcu].program_cycle_s)
00299 
00300                 serial = Serial(options.serial, timeout = 1)
00301                 if options.baud:
00302                     serial.setBaudrate(options.baud)
00303 
00304                 serial.flushInput()
00305                 serial.flushOutput()
00306 
00307                 try:
00308                     serial.sendBreak()
00309                 except:
00310                     # In linux a termios.error is raised in sendBreak and in setBreak.
00311                     # The following setBreak() is needed to release the reset signal on the target mcu.
00312                     try:
00313                         serial.setBreak(False)
00314                     except:
00315                         pass
00316 
00317                 while True:
00318                     c = serial.read(512)
00319                     sys.stdout.write(c)
00320                     sys.stdout.flush()
00321 
00322         except KeyboardInterrupt as e:
00323             print("\n[CTRL+c] exit")
00324         except NotSupportedException as e:
00325             print("\nCould not compile for %s: %s" % (mcu, str(e)))
00326         except Exception as e:
00327             if options.verbose:
00328                 import traceback
00329                 traceback.print_exc(file=sys.stdout)
00330             else:
00331                 print("[ERROR] %s" % str(e))
00332 
00333             sys.exit(1)
00334     if options.build_data:
00335         merge_build_data(options.build_data, build_data_blob, "application")