Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 """
kadonotakashi 0:8fdf9a60065b 2 mbed SDK
kadonotakashi 0:8fdf9a60065b 3 Copyright (c) 2011-2013 ARM Limited
kadonotakashi 0:8fdf9a60065b 4
kadonotakashi 0:8fdf9a60065b 5 Licensed under the Apache License, Version 2.0 (the "License");
kadonotakashi 0:8fdf9a60065b 6 you may not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 7 You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 8
kadonotakashi 0:8fdf9a60065b 9 http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 10
kadonotakashi 0:8fdf9a60065b 11 Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 12 distributed under the License is distributed on an "AS IS" BASIS,
kadonotakashi 0:8fdf9a60065b 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 14 See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 15 limitations under the License.
kadonotakashi 0:8fdf9a60065b 16 """
kadonotakashi 0:8fdf9a60065b 17 from __future__ import print_function, division, absolute_import
kadonotakashi 0:8fdf9a60065b 18 import sys
kadonotakashi 0:8fdf9a60065b 19 import inspect
kadonotakashi 0:8fdf9a60065b 20 import os
kadonotakashi 0:8fdf9a60065b 21 import argparse
kadonotakashi 0:8fdf9a60065b 22 import math
kadonotakashi 0:8fdf9a60065b 23 from os import listdir, remove, makedirs
kadonotakashi 0:8fdf9a60065b 24 from shutil import copyfile
kadonotakashi 0:8fdf9a60065b 25 from os.path import isdir, join, exists, split, relpath, splitext, abspath
kadonotakashi 0:8fdf9a60065b 26 from os.path import commonprefix, normpath, dirname
kadonotakashi 0:8fdf9a60065b 27 from subprocess import Popen, PIPE, STDOUT, call
kadonotakashi 0:8fdf9a60065b 28 from math import ceil
kadonotakashi 0:8fdf9a60065b 29 import json
kadonotakashi 0:8fdf9a60065b 30 from collections import OrderedDict
kadonotakashi 0:8fdf9a60065b 31 import logging
kadonotakashi 0:8fdf9a60065b 32 from intelhex import IntelHex
kadonotakashi 0:8fdf9a60065b 33
kadonotakashi 0:8fdf9a60065b 34 try:
kadonotakashi 0:8fdf9a60065b 35 unicode
kadonotakashi 0:8fdf9a60065b 36 except NameError:
kadonotakashi 0:8fdf9a60065b 37 unicode = str
kadonotakashi 0:8fdf9a60065b 38
kadonotakashi 0:8fdf9a60065b 39 def remove_if_in(lst, thing):
kadonotakashi 0:8fdf9a60065b 40 if thing in lst:
kadonotakashi 0:8fdf9a60065b 41 lst.remove(thing)
kadonotakashi 0:8fdf9a60065b 42
kadonotakashi 0:8fdf9a60065b 43 def compile_worker(job):
kadonotakashi 0:8fdf9a60065b 44 """Standard task runner used for compiling
kadonotakashi 0:8fdf9a60065b 45
kadonotakashi 0:8fdf9a60065b 46 Positional argumets:
kadonotakashi 0:8fdf9a60065b 47 job - a dict containing a list of commands and the remaining arguments
kadonotakashi 0:8fdf9a60065b 48 to run_cmd
kadonotakashi 0:8fdf9a60065b 49 """
kadonotakashi 0:8fdf9a60065b 50 results = []
kadonotakashi 0:8fdf9a60065b 51 for command in job['commands']:
kadonotakashi 0:8fdf9a60065b 52 try:
kadonotakashi 0:8fdf9a60065b 53 _, _stderr, _rc = run_cmd(command, work_dir=job['work_dir'],
kadonotakashi 0:8fdf9a60065b 54 chroot=job['chroot'])
kadonotakashi 0:8fdf9a60065b 55 except KeyboardInterrupt:
kadonotakashi 0:8fdf9a60065b 56 raise ToolException
kadonotakashi 0:8fdf9a60065b 57
kadonotakashi 0:8fdf9a60065b 58 results.append({
kadonotakashi 0:8fdf9a60065b 59 'code': _rc,
kadonotakashi 0:8fdf9a60065b 60 'output': _stderr,
kadonotakashi 0:8fdf9a60065b 61 'command': command
kadonotakashi 0:8fdf9a60065b 62 })
kadonotakashi 0:8fdf9a60065b 63
kadonotakashi 0:8fdf9a60065b 64 return {
kadonotakashi 0:8fdf9a60065b 65 'source': job['source'],
kadonotakashi 0:8fdf9a60065b 66 'object': job['object'],
kadonotakashi 0:8fdf9a60065b 67 'commands': job['commands'],
kadonotakashi 0:8fdf9a60065b 68 'results': results
kadonotakashi 0:8fdf9a60065b 69 }
kadonotakashi 0:8fdf9a60065b 70
kadonotakashi 0:8fdf9a60065b 71 def cmd(command, check=True, verbose=False, shell=False, cwd=None):
kadonotakashi 0:8fdf9a60065b 72 """A wrapper to run a command as a blocking job"""
kadonotakashi 0:8fdf9a60065b 73 text = command if shell else ' '.join(command)
kadonotakashi 0:8fdf9a60065b 74 if verbose:
kadonotakashi 0:8fdf9a60065b 75 print(text)
kadonotakashi 0:8fdf9a60065b 76 return_code = call(command, shell=shell, cwd=cwd)
kadonotakashi 0:8fdf9a60065b 77 if check and return_code != 0:
kadonotakashi 0:8fdf9a60065b 78 raise Exception('ERROR %d: "%s"' % (return_code, text))
kadonotakashi 0:8fdf9a60065b 79
kadonotakashi 0:8fdf9a60065b 80
kadonotakashi 0:8fdf9a60065b 81 def run_cmd(command, work_dir=None, chroot=None, redirect=False):
kadonotakashi 0:8fdf9a60065b 82 """Run a command in the foreground
kadonotakashi 0:8fdf9a60065b 83
kadonotakashi 0:8fdf9a60065b 84 Positional arguments:
kadonotakashi 0:8fdf9a60065b 85 command - the command to run
kadonotakashi 0:8fdf9a60065b 86
kadonotakashi 0:8fdf9a60065b 87 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 88 work_dir - the working directory to run the command in
kadonotakashi 0:8fdf9a60065b 89 chroot - the chroot to run the command in
kadonotakashi 0:8fdf9a60065b 90 redirect - redirect the stderr to a pipe to be used later
kadonotakashi 0:8fdf9a60065b 91 """
kadonotakashi 0:8fdf9a60065b 92 if chroot:
kadonotakashi 0:8fdf9a60065b 93 # Conventions managed by the web team for the mbed.org build system
kadonotakashi 0:8fdf9a60065b 94 chroot_cmd = [
kadonotakashi 0:8fdf9a60065b 95 '/usr/sbin/chroot', '--userspec=33:33', chroot
kadonotakashi 0:8fdf9a60065b 96 ]
kadonotakashi 0:8fdf9a60065b 97 for element in command:
kadonotakashi 0:8fdf9a60065b 98 chroot_cmd += [element.replace(chroot, '')]
kadonotakashi 0:8fdf9a60065b 99
kadonotakashi 0:8fdf9a60065b 100 logging.debug("Running command %s", ' '.join(chroot_cmd))
kadonotakashi 0:8fdf9a60065b 101 command = chroot_cmd
kadonotakashi 0:8fdf9a60065b 102 work_dir = None
kadonotakashi 0:8fdf9a60065b 103
kadonotakashi 0:8fdf9a60065b 104 try:
kadonotakashi 0:8fdf9a60065b 105 process = Popen(command, stdout=PIPE,
kadonotakashi 0:8fdf9a60065b 106 stderr=STDOUT if redirect else PIPE, cwd=work_dir)
kadonotakashi 0:8fdf9a60065b 107 _stdout, _stderr = process.communicate()
kadonotakashi 0:8fdf9a60065b 108 except OSError:
kadonotakashi 0:8fdf9a60065b 109 print("[OS ERROR] Command: "+(' '.join(command)))
kadonotakashi 0:8fdf9a60065b 110 raise
kadonotakashi 0:8fdf9a60065b 111
kadonotakashi 0:8fdf9a60065b 112 return _stdout, _stderr, process.returncode
kadonotakashi 0:8fdf9a60065b 113
kadonotakashi 0:8fdf9a60065b 114
kadonotakashi 0:8fdf9a60065b 115 def run_cmd_ext(command):
kadonotakashi 0:8fdf9a60065b 116 """ A version of run command that checks if the command exists befor running
kadonotakashi 0:8fdf9a60065b 117
kadonotakashi 0:8fdf9a60065b 118 Positional arguments:
kadonotakashi 0:8fdf9a60065b 119 command - the command line you are trying to invoke
kadonotakashi 0:8fdf9a60065b 120 """
kadonotakashi 0:8fdf9a60065b 121 assert is_cmd_valid(command[0])
kadonotakashi 0:8fdf9a60065b 122 process = Popen(command, stdout=PIPE, stderr=PIPE)
kadonotakashi 0:8fdf9a60065b 123 _stdout, _stderr = process.communicate()
kadonotakashi 0:8fdf9a60065b 124 return _stdout, _stderr, process.returncode
kadonotakashi 0:8fdf9a60065b 125
kadonotakashi 0:8fdf9a60065b 126
kadonotakashi 0:8fdf9a60065b 127 def is_cmd_valid(command):
kadonotakashi 0:8fdf9a60065b 128 """ Verify that a command exists and is executable
kadonotakashi 0:8fdf9a60065b 129
kadonotakashi 0:8fdf9a60065b 130 Positional arguments:
kadonotakashi 0:8fdf9a60065b 131 command - the command to check
kadonotakashi 0:8fdf9a60065b 132 """
kadonotakashi 0:8fdf9a60065b 133 caller = get_caller_name()
kadonotakashi 0:8fdf9a60065b 134 cmd_path = find_cmd_abspath(command)
kadonotakashi 0:8fdf9a60065b 135 if not cmd_path:
kadonotakashi 0:8fdf9a60065b 136 error("%s: Command '%s' can't be found" % (caller, command))
kadonotakashi 0:8fdf9a60065b 137 if not is_exec(cmd_path):
kadonotakashi 0:8fdf9a60065b 138 error("%s: Command '%s' resolves to file '%s' which is not executable"
kadonotakashi 0:8fdf9a60065b 139 % (caller, command, cmd_path))
kadonotakashi 0:8fdf9a60065b 140 return True
kadonotakashi 0:8fdf9a60065b 141
kadonotakashi 0:8fdf9a60065b 142
kadonotakashi 0:8fdf9a60065b 143 def is_exec(path):
kadonotakashi 0:8fdf9a60065b 144 """A simple check to verify that a path to an executable exists
kadonotakashi 0:8fdf9a60065b 145
kadonotakashi 0:8fdf9a60065b 146 Positional arguments:
kadonotakashi 0:8fdf9a60065b 147 path - the executable
kadonotakashi 0:8fdf9a60065b 148 """
kadonotakashi 0:8fdf9a60065b 149 return os.access(path, os.X_OK) or os.access(path+'.exe', os.X_OK)
kadonotakashi 0:8fdf9a60065b 150
kadonotakashi 0:8fdf9a60065b 151
kadonotakashi 0:8fdf9a60065b 152 def find_cmd_abspath(command):
kadonotakashi 0:8fdf9a60065b 153 """ Returns the absolute path to a command.
kadonotakashi 0:8fdf9a60065b 154 None is returned if no absolute path was found.
kadonotakashi 0:8fdf9a60065b 155
kadonotakashi 0:8fdf9a60065b 156 Positional arguhments:
kadonotakashi 0:8fdf9a60065b 157 command - the command to find the path of
kadonotakashi 0:8fdf9a60065b 158 """
kadonotakashi 0:8fdf9a60065b 159 if exists(command) or exists(command + '.exe'):
kadonotakashi 0:8fdf9a60065b 160 return os.path.abspath(command)
kadonotakashi 0:8fdf9a60065b 161 if not 'PATH' in os.environ:
kadonotakashi 0:8fdf9a60065b 162 raise Exception("Can't find command path for current platform ('%s')"
kadonotakashi 0:8fdf9a60065b 163 % sys.platform)
kadonotakashi 0:8fdf9a60065b 164 path_env = os.environ['PATH']
kadonotakashi 0:8fdf9a60065b 165 for path in path_env.split(os.pathsep):
kadonotakashi 0:8fdf9a60065b 166 cmd_path = '%s/%s' % (path, command)
kadonotakashi 0:8fdf9a60065b 167 if exists(cmd_path) or exists(cmd_path + '.exe'):
kadonotakashi 0:8fdf9a60065b 168 return cmd_path
kadonotakashi 0:8fdf9a60065b 169
kadonotakashi 0:8fdf9a60065b 170
kadonotakashi 0:8fdf9a60065b 171 def mkdir(path):
kadonotakashi 0:8fdf9a60065b 172 """ a wrapped makedirs that only tries to create a directory if it does not
kadonotakashi 0:8fdf9a60065b 173 exist already
kadonotakashi 0:8fdf9a60065b 174
kadonotakashi 0:8fdf9a60065b 175 Positional arguments:
kadonotakashi 0:8fdf9a60065b 176 path - the path to maybe create
kadonotakashi 0:8fdf9a60065b 177 """
kadonotakashi 0:8fdf9a60065b 178 if not exists(path):
kadonotakashi 0:8fdf9a60065b 179 makedirs(path)
kadonotakashi 0:8fdf9a60065b 180
kadonotakashi 0:8fdf9a60065b 181
kadonotakashi 0:8fdf9a60065b 182 def write_json_to_file(json_data, file_name):
kadonotakashi 0:8fdf9a60065b 183 """
kadonotakashi 0:8fdf9a60065b 184 Write json content in file
kadonotakashi 0:8fdf9a60065b 185 :param json_data:
kadonotakashi 0:8fdf9a60065b 186 :param file_name:
kadonotakashi 0:8fdf9a60065b 187 :return:
kadonotakashi 0:8fdf9a60065b 188 """
kadonotakashi 0:8fdf9a60065b 189 # Create the target dir for file if necessary
kadonotakashi 0:8fdf9a60065b 190 test_spec_dir = os.path.dirname(file_name)
kadonotakashi 0:8fdf9a60065b 191
kadonotakashi 0:8fdf9a60065b 192 if test_spec_dir:
kadonotakashi 0:8fdf9a60065b 193 mkdir(test_spec_dir)
kadonotakashi 0:8fdf9a60065b 194
kadonotakashi 0:8fdf9a60065b 195 try:
kadonotakashi 0:8fdf9a60065b 196 with open(file_name, 'w') as f:
kadonotakashi 0:8fdf9a60065b 197 f.write(json.dumps(json_data, indent=2))
kadonotakashi 0:8fdf9a60065b 198 except IOError as e:
kadonotakashi 0:8fdf9a60065b 199 print("[ERROR] Error writing test spec to file")
kadonotakashi 0:8fdf9a60065b 200 print(e)
kadonotakashi 0:8fdf9a60065b 201
kadonotakashi 0:8fdf9a60065b 202
kadonotakashi 0:8fdf9a60065b 203 def copy_file(src, dst):
kadonotakashi 0:8fdf9a60065b 204 """ Implement the behaviour of "shutil.copy(src, dst)" without copying the
kadonotakashi 0:8fdf9a60065b 205 permissions (this was causing errors with directories mounted with samba)
kadonotakashi 0:8fdf9a60065b 206
kadonotakashi 0:8fdf9a60065b 207 Positional arguments:
kadonotakashi 0:8fdf9a60065b 208 src - the source of the copy operation
kadonotakashi 0:8fdf9a60065b 209 dst - the destination of the copy operation
kadonotakashi 0:8fdf9a60065b 210 """
kadonotakashi 0:8fdf9a60065b 211 if isdir(dst):
kadonotakashi 0:8fdf9a60065b 212 _, base = split(src)
kadonotakashi 0:8fdf9a60065b 213 dst = join(dst, base)
kadonotakashi 0:8fdf9a60065b 214 copyfile(src, dst)
kadonotakashi 0:8fdf9a60065b 215
kadonotakashi 0:8fdf9a60065b 216
kadonotakashi 0:8fdf9a60065b 217 def delete_dir_files(directory):
kadonotakashi 0:8fdf9a60065b 218 """ A function that does rm -rf
kadonotakashi 0:8fdf9a60065b 219
kadonotakashi 0:8fdf9a60065b 220 Positional arguments:
kadonotakashi 0:8fdf9a60065b 221 directory - the directory to remove
kadonotakashi 0:8fdf9a60065b 222 """
kadonotakashi 0:8fdf9a60065b 223 if not exists(directory):
kadonotakashi 0:8fdf9a60065b 224 return
kadonotakashi 0:8fdf9a60065b 225
kadonotakashi 0:8fdf9a60065b 226 for element in listdir(directory):
kadonotakashi 0:8fdf9a60065b 227 to_remove = join(directory, element)
kadonotakashi 0:8fdf9a60065b 228 if not isdir(to_remove):
kadonotakashi 0:8fdf9a60065b 229 remove(to_remove)
kadonotakashi 0:8fdf9a60065b 230
kadonotakashi 0:8fdf9a60065b 231
kadonotakashi 0:8fdf9a60065b 232 def get_caller_name(steps=2):
kadonotakashi 0:8fdf9a60065b 233 """
kadonotakashi 0:8fdf9a60065b 234 When called inside a function, it returns the name
kadonotakashi 0:8fdf9a60065b 235 of the caller of that function.
kadonotakashi 0:8fdf9a60065b 236
kadonotakashi 0:8fdf9a60065b 237 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 238 steps - the number of steps up the stack the calling function is
kadonotakashi 0:8fdf9a60065b 239 """
kadonotakashi 0:8fdf9a60065b 240 return inspect.stack()[steps][3]
kadonotakashi 0:8fdf9a60065b 241
kadonotakashi 0:8fdf9a60065b 242
kadonotakashi 0:8fdf9a60065b 243 def error(msg):
kadonotakashi 0:8fdf9a60065b 244 """Fatal error, abort hard
kadonotakashi 0:8fdf9a60065b 245
kadonotakashi 0:8fdf9a60065b 246 Positional arguments:
kadonotakashi 0:8fdf9a60065b 247 msg - the message to print before crashing
kadonotakashi 0:8fdf9a60065b 248 """
kadonotakashi 0:8fdf9a60065b 249 print("ERROR: %s" % msg)
kadonotakashi 0:8fdf9a60065b 250 sys.exit(1)
kadonotakashi 0:8fdf9a60065b 251
kadonotakashi 0:8fdf9a60065b 252
kadonotakashi 0:8fdf9a60065b 253 def rel_path(path, base, dot=False):
kadonotakashi 0:8fdf9a60065b 254 """Relative path calculation that optionaly always starts with a dot
kadonotakashi 0:8fdf9a60065b 255
kadonotakashi 0:8fdf9a60065b 256 Positional arguments:
kadonotakashi 0:8fdf9a60065b 257 path - the path to make relative
kadonotakashi 0:8fdf9a60065b 258 base - what to make the path relative to
kadonotakashi 0:8fdf9a60065b 259
kadonotakashi 0:8fdf9a60065b 260 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 261 dot - if True, the path will always start with a './'
kadonotakashi 0:8fdf9a60065b 262 """
kadonotakashi 0:8fdf9a60065b 263 final_path = relpath(path, base)
kadonotakashi 0:8fdf9a60065b 264 if dot and not final_path.startswith('.'):
kadonotakashi 0:8fdf9a60065b 265 final_path = './' + final_path
kadonotakashi 0:8fdf9a60065b 266 return final_path
kadonotakashi 0:8fdf9a60065b 267
kadonotakashi 0:8fdf9a60065b 268
kadonotakashi 0:8fdf9a60065b 269 class ToolException(Exception):
kadonotakashi 0:8fdf9a60065b 270 """A class representing an exception throw by the tools"""
kadonotakashi 0:8fdf9a60065b 271 pass
kadonotakashi 0:8fdf9a60065b 272
kadonotakashi 0:8fdf9a60065b 273 class NotSupportedException(Exception):
kadonotakashi 0:8fdf9a60065b 274 """A class a toolchain not supporting a particular target"""
kadonotakashi 0:8fdf9a60065b 275 pass
kadonotakashi 0:8fdf9a60065b 276
kadonotakashi 0:8fdf9a60065b 277 class InvalidReleaseTargetException(Exception):
kadonotakashi 0:8fdf9a60065b 278 pass
kadonotakashi 0:8fdf9a60065b 279
kadonotakashi 0:8fdf9a60065b 280 def split_path(path):
kadonotakashi 0:8fdf9a60065b 281 """spilt a file name into it's directory name, base name, and extension
kadonotakashi 0:8fdf9a60065b 282
kadonotakashi 0:8fdf9a60065b 283 Positional arguments:
kadonotakashi 0:8fdf9a60065b 284 path - the file name to split
kadonotakashi 0:8fdf9a60065b 285 """
kadonotakashi 0:8fdf9a60065b 286 base, has_ext = split(path)
kadonotakashi 0:8fdf9a60065b 287 name, ext = splitext(has_ext)
kadonotakashi 0:8fdf9a60065b 288 return base, name, ext
kadonotakashi 0:8fdf9a60065b 289
kadonotakashi 0:8fdf9a60065b 290
kadonotakashi 0:8fdf9a60065b 291 def get_path_depth(path):
kadonotakashi 0:8fdf9a60065b 292 """ Given a path, return the number of directory levels present.
kadonotakashi 0:8fdf9a60065b 293 This roughly translates to the number of path separators (os.sep) + 1.
kadonotakashi 0:8fdf9a60065b 294 Ex. Given "path/to/dir", this would return 3
kadonotakashi 0:8fdf9a60065b 295 Special cases: "." and "/" return 0
kadonotakashi 0:8fdf9a60065b 296
kadonotakashi 0:8fdf9a60065b 297 Positional arguments:
kadonotakashi 0:8fdf9a60065b 298 path - the path to calculate the depth of
kadonotakashi 0:8fdf9a60065b 299 """
kadonotakashi 0:8fdf9a60065b 300 normalized_path = normpath(path)
kadonotakashi 0:8fdf9a60065b 301 path_depth = 0
kadonotakashi 0:8fdf9a60065b 302 head, tail = split(normalized_path)
kadonotakashi 0:8fdf9a60065b 303
kadonotakashi 0:8fdf9a60065b 304 while tail and tail != '.':
kadonotakashi 0:8fdf9a60065b 305 path_depth += 1
kadonotakashi 0:8fdf9a60065b 306 head, tail = split(head)
kadonotakashi 0:8fdf9a60065b 307
kadonotakashi 0:8fdf9a60065b 308 return path_depth
kadonotakashi 0:8fdf9a60065b 309
kadonotakashi 0:8fdf9a60065b 310
kadonotakashi 0:8fdf9a60065b 311 def args_error(parser, message):
kadonotakashi 0:8fdf9a60065b 312 """Abort with an error that was generated by the arguments to a CLI program
kadonotakashi 0:8fdf9a60065b 313
kadonotakashi 0:8fdf9a60065b 314 Positional arguments:
kadonotakashi 0:8fdf9a60065b 315 parser - the ArgumentParser object that parsed the command line
kadonotakashi 0:8fdf9a60065b 316 message - what went wrong
kadonotakashi 0:8fdf9a60065b 317 """
kadonotakashi 0:8fdf9a60065b 318 parser.error(message)
kadonotakashi 0:8fdf9a60065b 319 sys.exit(2)
kadonotakashi 0:8fdf9a60065b 320
kadonotakashi 0:8fdf9a60065b 321
kadonotakashi 0:8fdf9a60065b 322 def construct_enum(**enums):
kadonotakashi 0:8fdf9a60065b 323 """ Create your own pseudo-enums
kadonotakashi 0:8fdf9a60065b 324
kadonotakashi 0:8fdf9a60065b 325 Keyword arguments:
kadonotakashi 0:8fdf9a60065b 326 * - a member of the Enum you are creating and it's value
kadonotakashi 0:8fdf9a60065b 327 """
kadonotakashi 0:8fdf9a60065b 328 return type('Enum', (), enums)
kadonotakashi 0:8fdf9a60065b 329
kadonotakashi 0:8fdf9a60065b 330
kadonotakashi 0:8fdf9a60065b 331 def check_required_modules(required_modules, verbose=True):
kadonotakashi 0:8fdf9a60065b 332 """ Function checks for Python modules which should be "importable"
kadonotakashi 0:8fdf9a60065b 333 before test suite can be used.
kadonotakashi 0:8fdf9a60065b 334 @return returns True if all modules are installed already
kadonotakashi 0:8fdf9a60065b 335 """
kadonotakashi 0:8fdf9a60065b 336 import imp
kadonotakashi 0:8fdf9a60065b 337 not_installed_modules = []
kadonotakashi 0:8fdf9a60065b 338 for module_name in required_modules:
kadonotakashi 0:8fdf9a60065b 339 try:
kadonotakashi 0:8fdf9a60065b 340 imp.find_module(module_name)
kadonotakashi 0:8fdf9a60065b 341 except ImportError:
kadonotakashi 0:8fdf9a60065b 342 # We also test against a rare case: module is an egg file
kadonotakashi 0:8fdf9a60065b 343 try:
kadonotakashi 0:8fdf9a60065b 344 __import__(module_name)
kadonotakashi 0:8fdf9a60065b 345 except ImportError as exc:
kadonotakashi 0:8fdf9a60065b 346 not_installed_modules.append(module_name)
kadonotakashi 0:8fdf9a60065b 347 if verbose:
kadonotakashi 0:8fdf9a60065b 348 print("Error: %s" % exc)
kadonotakashi 0:8fdf9a60065b 349
kadonotakashi 0:8fdf9a60065b 350 if verbose:
kadonotakashi 0:8fdf9a60065b 351 if not_installed_modules:
kadonotakashi 0:8fdf9a60065b 352 print("Warning: Module(s) %s not installed. Please install "
kadonotakashi 0:8fdf9a60065b 353 "required module(s) before using this script."
kadonotakashi 0:8fdf9a60065b 354 % (', '.join(not_installed_modules)))
kadonotakashi 0:8fdf9a60065b 355
kadonotakashi 0:8fdf9a60065b 356 if not_installed_modules:
kadonotakashi 0:8fdf9a60065b 357 return False
kadonotakashi 0:8fdf9a60065b 358 else:
kadonotakashi 0:8fdf9a60065b 359 return True
kadonotakashi 0:8fdf9a60065b 360
kadonotakashi 0:8fdf9a60065b 361 def json_file_to_dict(fname):
kadonotakashi 0:8fdf9a60065b 362 """ Read a JSON file and return its Python representation, transforming all
kadonotakashi 0:8fdf9a60065b 363 the strings from Unicode to ASCII. The order of keys in the JSON file is
kadonotakashi 0:8fdf9a60065b 364 preserved.
kadonotakashi 0:8fdf9a60065b 365
kadonotakashi 0:8fdf9a60065b 366 Positional arguments:
kadonotakashi 0:8fdf9a60065b 367 fname - the name of the file to parse
kadonotakashi 0:8fdf9a60065b 368 """
kadonotakashi 0:8fdf9a60065b 369 try:
kadonotakashi 0:8fdf9a60065b 370 with open(fname, "r") as file_obj:
kadonotakashi 0:8fdf9a60065b 371 return json.loads(file_obj.read().encode('ascii', 'ignore'),
kadonotakashi 0:8fdf9a60065b 372 object_pairs_hook=OrderedDict)
kadonotakashi 0:8fdf9a60065b 373 except (ValueError, IOError):
kadonotakashi 0:8fdf9a60065b 374 sys.stderr.write("Error parsing '%s':\n" % fname)
kadonotakashi 0:8fdf9a60065b 375 raise
kadonotakashi 0:8fdf9a60065b 376
kadonotakashi 0:8fdf9a60065b 377 # Wowza, double closure
kadonotakashi 0:8fdf9a60065b 378 def argparse_type(casedness, prefer_hyphen=False):
kadonotakashi 0:8fdf9a60065b 379 def middle(lst, type_name):
kadonotakashi 0:8fdf9a60065b 380 def parse_type(string):
kadonotakashi 0:8fdf9a60065b 381 """ validate that an argument passed in (as string) is a member of
kadonotakashi 0:8fdf9a60065b 382 the list of possible arguments. Offer a suggestion if the case of
kadonotakashi 0:8fdf9a60065b 383 the string, or the hyphens/underscores do not match the expected
kadonotakashi 0:8fdf9a60065b 384 style of the argument.
kadonotakashi 0:8fdf9a60065b 385 """
kadonotakashi 0:8fdf9a60065b 386 if not isinstance(string, unicode):
kadonotakashi 0:8fdf9a60065b 387 string = string.decode()
kadonotakashi 0:8fdf9a60065b 388 if prefer_hyphen:
kadonotakashi 0:8fdf9a60065b 389 newstring = casedness(string).replace("_", "-")
kadonotakashi 0:8fdf9a60065b 390 else:
kadonotakashi 0:8fdf9a60065b 391 newstring = casedness(string).replace("-", "_")
kadonotakashi 0:8fdf9a60065b 392 if string in lst:
kadonotakashi 0:8fdf9a60065b 393 return string
kadonotakashi 0:8fdf9a60065b 394 elif string not in lst and newstring in lst:
kadonotakashi 0:8fdf9a60065b 395 raise argparse.ArgumentTypeError(
kadonotakashi 0:8fdf9a60065b 396 "{0} is not a supported {1}. Did you mean {2}?".format(
kadonotakashi 0:8fdf9a60065b 397 string, type_name, newstring))
kadonotakashi 0:8fdf9a60065b 398 else:
kadonotakashi 0:8fdf9a60065b 399 raise argparse.ArgumentTypeError(
kadonotakashi 0:8fdf9a60065b 400 "{0} is not a supported {1}. Supported {1}s are:\n{2}".
kadonotakashi 0:8fdf9a60065b 401 format(string, type_name, columnate(lst)))
kadonotakashi 0:8fdf9a60065b 402 return parse_type
kadonotakashi 0:8fdf9a60065b 403 return middle
kadonotakashi 0:8fdf9a60065b 404
kadonotakashi 0:8fdf9a60065b 405 # short cuts for the argparse_type versions
kadonotakashi 0:8fdf9a60065b 406 argparse_uppercase_type = argparse_type(unicode.upper, False)
kadonotakashi 0:8fdf9a60065b 407 argparse_lowercase_type = argparse_type(unicode.lower, False)
kadonotakashi 0:8fdf9a60065b 408 argparse_uppercase_hyphen_type = argparse_type(unicode.upper, True)
kadonotakashi 0:8fdf9a60065b 409 argparse_lowercase_hyphen_type = argparse_type(unicode.lower, True)
kadonotakashi 0:8fdf9a60065b 410
kadonotakashi 0:8fdf9a60065b 411 def argparse_force_type(case):
kadonotakashi 0:8fdf9a60065b 412 """ validate that an argument passed in (as string) is a member of the list
kadonotakashi 0:8fdf9a60065b 413 of possible arguments after converting it's case.
kadonotakashi 0:8fdf9a60065b 414 """
kadonotakashi 0:8fdf9a60065b 415 def middle(lst, type_name):
kadonotakashi 0:8fdf9a60065b 416 """ The parser type generator"""
kadonotakashi 0:8fdf9a60065b 417 if not isinstance(lst[0], unicode):
kadonotakashi 0:8fdf9a60065b 418 lst = [o.decode() for o in lst]
kadonotakashi 0:8fdf9a60065b 419 def parse_type(string):
kadonotakashi 0:8fdf9a60065b 420 """ The parser type"""
kadonotakashi 0:8fdf9a60065b 421 if not isinstance(string, unicode):
kadonotakashi 0:8fdf9a60065b 422 string = string.decode()
kadonotakashi 0:8fdf9a60065b 423 for option in lst:
kadonotakashi 0:8fdf9a60065b 424 if case(string) == case(option):
kadonotakashi 0:8fdf9a60065b 425 return option
kadonotakashi 0:8fdf9a60065b 426 raise argparse.ArgumentTypeError(
kadonotakashi 0:8fdf9a60065b 427 "{0} is not a supported {1}. Supported {1}s are:\n{2}".
kadonotakashi 0:8fdf9a60065b 428 format(string, type_name, columnate(lst)))
kadonotakashi 0:8fdf9a60065b 429 return parse_type
kadonotakashi 0:8fdf9a60065b 430 return middle
kadonotakashi 0:8fdf9a60065b 431
kadonotakashi 0:8fdf9a60065b 432 # these two types convert the case of their arguments _before_ validation
kadonotakashi 0:8fdf9a60065b 433 argparse_force_uppercase_type = argparse_force_type(unicode.upper)
kadonotakashi 0:8fdf9a60065b 434 argparse_force_lowercase_type = argparse_force_type(unicode.lower)
kadonotakashi 0:8fdf9a60065b 435
kadonotakashi 0:8fdf9a60065b 436 def argparse_many(func):
kadonotakashi 0:8fdf9a60065b 437 """ An argument parser combinator that takes in an argument parser and
kadonotakashi 0:8fdf9a60065b 438 creates a new parser that accepts a comma separated list of the same thing.
kadonotakashi 0:8fdf9a60065b 439 """
kadonotakashi 0:8fdf9a60065b 440 def wrap(string):
kadonotakashi 0:8fdf9a60065b 441 """ The actual parser"""
kadonotakashi 0:8fdf9a60065b 442 return [func(s) for s in string.split(",")]
kadonotakashi 0:8fdf9a60065b 443 return wrap
kadonotakashi 0:8fdf9a60065b 444
kadonotakashi 0:8fdf9a60065b 445 def argparse_filestring_type(string):
kadonotakashi 0:8fdf9a60065b 446 """ An argument parser that verifies that a string passed in corresponds
kadonotakashi 0:8fdf9a60065b 447 to a file"""
kadonotakashi 0:8fdf9a60065b 448 if exists(string):
kadonotakashi 0:8fdf9a60065b 449 return string
kadonotakashi 0:8fdf9a60065b 450 else:
kadonotakashi 0:8fdf9a60065b 451 raise argparse.ArgumentTypeError(
kadonotakashi 0:8fdf9a60065b 452 "{0}"" does not exist in the filesystem.".format(string))
kadonotakashi 0:8fdf9a60065b 453
kadonotakashi 0:8fdf9a60065b 454 def argparse_profile_filestring_type(string):
kadonotakashi 0:8fdf9a60065b 455 """ An argument parser that verifies that a string passed in is either
kadonotakashi 0:8fdf9a60065b 456 absolute path or a file name (expanded to
kadonotakashi 0:8fdf9a60065b 457 mbed-os/tools/profiles/<fname>.json) of a existing file"""
kadonotakashi 0:8fdf9a60065b 458 fpath = join(dirname(__file__), "profiles/{}.json".format(string))
kadonotakashi 0:8fdf9a60065b 459 if exists(string):
kadonotakashi 0:8fdf9a60065b 460 return string
kadonotakashi 0:8fdf9a60065b 461 elif exists(fpath):
kadonotakashi 0:8fdf9a60065b 462 return fpath
kadonotakashi 0:8fdf9a60065b 463 else:
kadonotakashi 0:8fdf9a60065b 464 raise argparse.ArgumentTypeError(
kadonotakashi 0:8fdf9a60065b 465 "{0} does not exist in the filesystem.".format(string))
kadonotakashi 0:8fdf9a60065b 466
kadonotakashi 0:8fdf9a60065b 467 def columnate(strings, separator=", ", chars=80):
kadonotakashi 0:8fdf9a60065b 468 """ render a list of strings as a in a bunch of columns
kadonotakashi 0:8fdf9a60065b 469
kadonotakashi 0:8fdf9a60065b 470 Positional arguments:
kadonotakashi 0:8fdf9a60065b 471 strings - the strings to columnate
kadonotakashi 0:8fdf9a60065b 472
kadonotakashi 0:8fdf9a60065b 473 Keyword arguments;
kadonotakashi 0:8fdf9a60065b 474 separator - the separation between the columns
kadonotakashi 0:8fdf9a60065b 475 chars - the maximum with of a row
kadonotakashi 0:8fdf9a60065b 476 """
kadonotakashi 0:8fdf9a60065b 477 col_width = max(len(s) for s in strings)
kadonotakashi 0:8fdf9a60065b 478 total_width = col_width + len(separator)
kadonotakashi 0:8fdf9a60065b 479 columns = math.floor(chars / total_width)
kadonotakashi 0:8fdf9a60065b 480 output = ""
kadonotakashi 0:8fdf9a60065b 481 for i, string in zip(range(len(strings)), strings):
kadonotakashi 0:8fdf9a60065b 482 append = string
kadonotakashi 0:8fdf9a60065b 483 if i != len(strings) - 1:
kadonotakashi 0:8fdf9a60065b 484 append += separator
kadonotakashi 0:8fdf9a60065b 485 if i % columns == columns - 1:
kadonotakashi 0:8fdf9a60065b 486 append += "\n"
kadonotakashi 0:8fdf9a60065b 487 else:
kadonotakashi 0:8fdf9a60065b 488 append = append.ljust(total_width)
kadonotakashi 0:8fdf9a60065b 489 output += append
kadonotakashi 0:8fdf9a60065b 490 return output
kadonotakashi 0:8fdf9a60065b 491
kadonotakashi 0:8fdf9a60065b 492 def argparse_dir_not_parent(other):
kadonotakashi 0:8fdf9a60065b 493 """fail if argument provided is a parent of the specified directory"""
kadonotakashi 0:8fdf9a60065b 494 def parse_type(not_parent):
kadonotakashi 0:8fdf9a60065b 495 """The parser type"""
kadonotakashi 0:8fdf9a60065b 496 abs_other = abspath(other)
kadonotakashi 0:8fdf9a60065b 497 abs_not_parent = abspath(not_parent)
kadonotakashi 0:8fdf9a60065b 498 if abs_not_parent == commonprefix([abs_not_parent, abs_other]):
kadonotakashi 0:8fdf9a60065b 499 raise argparse.ArgumentTypeError(
kadonotakashi 0:8fdf9a60065b 500 "{0} may not be a parent directory of {1}".format(
kadonotakashi 0:8fdf9a60065b 501 not_parent, other))
kadonotakashi 0:8fdf9a60065b 502 else:
kadonotakashi 0:8fdf9a60065b 503 return not_parent
kadonotakashi 0:8fdf9a60065b 504 return parse_type
kadonotakashi 0:8fdf9a60065b 505
kadonotakashi 0:8fdf9a60065b 506 def argparse_deprecate(replacement_message):
kadonotakashi 0:8fdf9a60065b 507 """fail if argument is provided with deprecation warning"""
kadonotakashi 0:8fdf9a60065b 508 def parse_type(_):
kadonotakashi 0:8fdf9a60065b 509 """The parser type"""
kadonotakashi 0:8fdf9a60065b 510 raise argparse.ArgumentTypeError("Deprecated." + replacement_message)
kadonotakashi 0:8fdf9a60065b 511 return parse_type
kadonotakashi 0:8fdf9a60065b 512
kadonotakashi 0:8fdf9a60065b 513 def print_large_string(large_string):
kadonotakashi 0:8fdf9a60065b 514 """ Breaks a string up into smaller pieces before print them
kadonotakashi 0:8fdf9a60065b 515
kadonotakashi 0:8fdf9a60065b 516 This is a limitation within Windows, as detailed here:
kadonotakashi 0:8fdf9a60065b 517 https://bugs.python.org/issue11395
kadonotakashi 0:8fdf9a60065b 518
kadonotakashi 0:8fdf9a60065b 519 Positional arguments:
kadonotakashi 0:8fdf9a60065b 520 large_string - the large string to print
kadonotakashi 0:8fdf9a60065b 521 """
kadonotakashi 0:8fdf9a60065b 522 string_limit = 1000
kadonotakashi 0:8fdf9a60065b 523 large_string_len = len(large_string)
kadonotakashi 0:8fdf9a60065b 524 num_parts = int(ceil(float(large_string_len) / float(string_limit)))
kadonotakashi 0:8fdf9a60065b 525 for string_part in range(num_parts):
kadonotakashi 0:8fdf9a60065b 526 start_index = string_part * string_limit
kadonotakashi 0:8fdf9a60065b 527 if string_part == num_parts - 1:
kadonotakashi 0:8fdf9a60065b 528 sys.stdout.write(large_string[start_index:])
kadonotakashi 0:8fdf9a60065b 529 else:
kadonotakashi 0:8fdf9a60065b 530 sys.stdout.write(large_string[start_index:
kadonotakashi 0:8fdf9a60065b 531 start_index + string_limit])
kadonotakashi 0:8fdf9a60065b 532 sys.stdout.write("\n")
kadonotakashi 0:8fdf9a60065b 533
kadonotakashi 0:8fdf9a60065b 534 def intelhex_offset(filename, offset):
kadonotakashi 0:8fdf9a60065b 535 """Load a hex or bin file at a particular offset"""
kadonotakashi 0:8fdf9a60065b 536 _, inteltype = splitext(filename)
kadonotakashi 0:8fdf9a60065b 537 ih = IntelHex()
kadonotakashi 0:8fdf9a60065b 538 if inteltype == ".bin":
kadonotakashi 0:8fdf9a60065b 539 ih.loadbin(filename, offset=offset)
kadonotakashi 0:8fdf9a60065b 540 elif inteltype == ".hex":
kadonotakashi 0:8fdf9a60065b 541 ih.loadhex(filename)
kadonotakashi 0:8fdf9a60065b 542 else:
kadonotakashi 0:8fdf9a60065b 543 raise ToolException("File %s does not have a known binary file type"
kadonotakashi 0:8fdf9a60065b 544 % filename)
kadonotakashi 0:8fdf9a60065b 545 return ih
kadonotakashi 0:8fdf9a60065b 546
kadonotakashi 0:8fdf9a60065b 547 def integer(maybe_string, base):
kadonotakashi 0:8fdf9a60065b 548 """Make an integer of a number or a string"""
kadonotakashi 0:8fdf9a60065b 549 if isinstance(maybe_string, int):
kadonotakashi 0:8fdf9a60065b 550 return maybe_string
kadonotakashi 0:8fdf9a60065b 551 else:
kadonotakashi 0:8fdf9a60065b 552 return int(maybe_string, base)
kadonotakashi 0:8fdf9a60065b 553
kadonotakashi 0:8fdf9a60065b 554 def generate_update_filename(name, target):
kadonotakashi 0:8fdf9a60065b 555 return "%s_update.%s" % (
kadonotakashi 0:8fdf9a60065b 556 name,
kadonotakashi 0:8fdf9a60065b 557 getattr(target, "OUTPUT_EXT_UPDATE", "bin")
kadonotakashi 0:8fdf9a60065b 558 )