diff --git a/HISTORY.rst b/HISTORY.rst index 2b5c4c38..7fa2f93c 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -15,6 +15,8 @@ PlatformIO 2.0 (`issue #683 `_) * Added support for `Arduboy DevKit `__, the game system the size of a credit card +* Check program size before uploading to the board + (`issue #689 `_) * Fixed issue with ``-L relative/path`` when parsing ``build_flags`` (`issue #688 `_) diff --git a/platformio/__init__.py b/platformio/__init__.py index d5c24766..17199166 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (2, 9, "5.dev1") +VERSION = (2, 9, "5.dev2") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 8b01c7b2..d060aab2 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -171,3 +171,6 @@ if "envdump" in COMMAND_LINE_TARGETS: if "idedata" in COMMAND_LINE_TARGETS: print json.dumps(env.DumpIDEData()) env.Exit() + +if set(["upload", "uploadlazy", "program"]) & set(COMMAND_LINE_TARGETS): + env.CheckUploadSize() diff --git a/platformio/builder/tools/pioupload.py b/platformio/builder/tools/pioupload.py index b7fe229e..b75501c5 100644 --- a/platformio/builder/tools/pioupload.py +++ b/platformio/builder/tools/pioupload.py @@ -14,6 +14,7 @@ from __future__ import absolute_import +from os import environ from os.path import isfile, join from platform import system from shutil import copyfile @@ -21,7 +22,7 @@ from time import sleep from serial import Serial -from platformio.util import get_logicaldisks, get_serialports, get_systype +from platformio import util def FlushSerialBuffer(env, port): @@ -36,7 +37,7 @@ def FlushSerialBuffer(env, port): def TouchSerialPort(env, port, baudrate): - if "windows" not in get_systype(): + if system() != "Windows": try: s = Serial(env.subst(port)) s.close() @@ -54,7 +55,7 @@ def WaitForNewSerialPort(env, before): new_port = None elapsed = 0 while elapsed < 5 and new_port is None: - now = get_serialports() + now = util.get_serialports() for p in now: if p not in before: new_port = p['port'] @@ -84,7 +85,7 @@ def AutodetectUploadPort(env): if env.subst("$FRAMEWORK") == "mbed": msdlabels = ("mbed", "nucleo", "frdm") - for item in get_logicaldisks(): + for item in util.get_logicaldisks(): if (not item['name'] or not any([l in item['name'].lower() for l in msdlabels])): continue @@ -101,7 +102,7 @@ def AutodetectUploadPort(env): ) board_build_opts = env.get("BOARD_OPTIONS", {}).get("build", {}) - for item in get_serialports(): + for item in util.get_serialports(): if "VID:PID" not in item['hwid']: continue env.Replace(UPLOAD_PORT=item['port']) @@ -132,6 +133,30 @@ def UploadToDisk(_, target, source, env): # pylint: disable=W0613,W0621 "Please restart your board.") +def CheckUploadSize(env): + max_size = int(env.get("BOARD_OPTIONS", {}).get("upload", {}).get( + "maximum_size", 0)) + if max_size == 0 or "SIZETOOL" not in env: + return + + sysenv = environ.copy() + sysenv['PATH'] = str(env['ENV']['PATH']) + cmd = [env.subst("$SIZETOOL"), "-B"] + cmd.append(env.subst(join("$BUILD_DIR", "$PROGNAME$PROGSUFFIX"))) + result = util.exec_command(cmd, env=sysenv) + if result['returncode'] != 0: + return + + line = result['out'].strip().splitlines()[1] + values = [v.strip() for v in line.split("\t")] + used_size = int(values[0]) + int(values[1]) + + if used_size > max_size: + print result['out'] + env.Exit("Error: The program size (%d bytes) is greater " + "than maximum allowed (%s bytes)" % (used_size, max_size)) + + def exists(_): return True @@ -142,4 +167,5 @@ def generate(env): env.AddMethod(WaitForNewSerialPort) env.AddMethod(AutodetectUploadPort) env.AddMethod(UploadToDisk) + env.AddMethod(CheckUploadSize) return env