diff --git a/HISTORY.rst b/HISTORY.rst index c37a85e2..3746622a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,26 @@ Release History =============== +1.0.0 (?) +--------- + +0.4.0 (2014-07-31) +------------------ + +* Implemented ``serialports`` command +* Allowed to put special build flags only for ``src`` files via + ``srcbuild_flags`` environment option +* Allowed to override some of settings via system environment variables + such as: ``$PIOSRCBUILD_FLAGS`` and ``$PIOENVS_DIR`` +* Added ``--upload-port`` option for ``platformio run`` command +* Implemented (especially for `SmartAnthill `_) + ``platformio run -t uploadlazy`` target (no dependencies to framework libs, + ELF and etc.) +* Allowed to skip default packages via ``platformio install --skip-default-package`` flag +* Added tools for Raspberry Pi platform +* Added support for Microduino and Raspduino boards in ``atmelavr`` platform + + 0.3.1 (2014-06-21) ------------------ diff --git a/README.rst b/README.rst index f89eed60..4d8dd770 100644 --- a/README.rst +++ b/README.rst @@ -17,6 +17,14 @@ PlatformIO :target: https://pypi.python.org/pypi/platformio/ :alt: License +`Quickstart <#quickstart>`_ | +`Installation <#installation>`_ | +`Documentation <#documentation>`_ | +`Examples `_ | +`Embedded Platform Boards <#embedded-platform-boards>`_ | +`IDE Integration <#ide-integration>`_ | +`Blog `_ + **PlatformIO** is a console tool to build code with different development platforms. @@ -70,6 +78,71 @@ IDE Integration * [Eclipse] `Building and debugging Atmel AVR (Arduino-based) project using Eclipse IDE+PlatformIO `_ +Embedded Platform Boards +------------------------ + +**PlatformIO** has pre-configured settings for most popular platform boards. You +have no need to specify in ``platformio.ini`` type or frequency of MCU, upload +protocol or etc. Please use ``board`` option (for +`example `_). + + +Platform ``atmelavr`` +~~~~~~~~~~~~~~~~~~~~~ + +* ``diecimilaatmega168`` Arduino Duemilanove or Diecimila (ATmega168) +* ``diecimilaatmega328`` Arduino Duemilanove or Diecimila (ATmega328) +* ``fio`` Arduino Fio +* ``leonardo`` Arduino Leonardo +* ``LilyPadUSB`` Arduino LilyPad USB +* ``lilypadatmega168`` Arduino LilyPad (ATmega168) +* ``lilypadatmega328`` Arduino LilyPad (ATmega328) +* ``megaatmega1280`` Arduino Mega (ATmega1280) +* ``megaatmega2560`` Arduino Mega (ATmega2560) +* ``megaADK`` Arduino Mega ADK +* ``micro`` Arduino Micro +* ``miniatmega168`` Arduino Mini (ATmega168) +* ``miniatmega328`` Arduino Mini (ATmega328) +* ``nanoatmega168`` Arduino Nano (ATmega168) +* ``nanoatmega328`` Arduino Nano (ATmega328) +* ``pro8MHzatmega168`` Arduino Pro or Pro Mini (ATmega168, 3.3V, 8MHz) +* ``pro16MHzatmega168`` Arduino Pro or Pro Mini (ATmega168, 5V, 16MHz) +* ``pro8MHzatmega328`` Arduino Pro or Pro Mini (ATmega328, 3.3V, 8MHz) +* ``pro16MHzatmega328`` Arduino Pro or Pro Mini (ATmega328, 5V, 16MHz) +* ``uno`` Arduino Uno +* ``raspduino`` Raspduino +* ``328p8m`` Microduino Core (ATmega328P, 3.3V, 8MHz) +* ``328p16m`` Microduino Core (Atmega328P, 5V, 16MHz) +* ``168pa8m`` Microduino Core (ATmega168PA, 3.3V, 8MHz) +* ``168pa16m`` Microduino Core (ATmega168PA, 5V, 16MHz) +* ``644pa8m`` Microduino Core+ (ATmega644PA, 3.3V, 8MHz) +* ``644pa16m`` Microduino Core+ (ATmega644PA, 5V, 16MHz) +* ``1284p8m`` Microduino-Core+ (ATmega1284P, 3.3V, 8MHz) +* ``1284p16m`` Microduino-Core+ (ATmega1284P, 5V, 16MHz) +* ``32u416m`` Microduino-Core USB (ATmega32U4, 5V, 16MHz) + + + +Platform ``timsp430`` +~~~~~~~~~~~~~~~~~~~~~ + +* ``lpmsp430g2231`` TI LaunchPad MSP430 (msp430g2231) +* ``lpmsp430g2452`` TI LaunchPad MSP430 (msp430g2452) +* ``lpmsp430g2553`` TI LaunchPad MSP430 (msp430g2553) +* ``lpmsp430f5529`` TI LaunchPad MSP430 (msp430f5529, 16MHz) +* ``lpmsp430f5529_25`` TI LaunchPad MSP430 (msp430f5529, 25MHz) +* ``lpmsp430fr5969`` TI LaunchPad MSP430 (msp430fr5969) +* ``lpmsp430fr5739`` TI FraunchPad MSP430 (msp430fr5739) + + +Platform ``titiva`` +~~~~~~~~~~~~~~~~~~~ + +* ``lplm4f120h5qr`` TI Stellaris LM4F120 LaunchPad +* ``lptm4c1230c3pm`` TI Tiva C Series TM4C123G LaunchPad +* ``lptm4c1294ncpdt`` TI Tiva C Series TM4C1294 Connected LaunchPad + + Python & OS Support ------------------- @@ -96,7 +169,7 @@ Quickstart $ platformio run For more detailed information please follow to `Installation <#installation>`_ -and `User Guide <#user-guide>`_ sections. +and `Documentation <#documentation>`_ sections. Installation @@ -127,6 +200,13 @@ Then run the following (which may require administrator access): $ python get-platformio.py +An alternative short version for *Mac/Linux* users: + +.. code-block:: bash + + $ curl -L http://bit.ly/1lpanta | python + + On *Windows OS* it may look like: .. code-block:: bash @@ -176,8 +256,8 @@ For upgrading the ``platformio`` to new version please use this command: $ pip install -U platformio -User Guide ----------- +Documentation +------------- To print all available commands and options: @@ -195,36 +275,42 @@ To print all available commands and options: --help Show this message and exit. Commands: - init Initialize new platformio based project - install Install new platforms - list List installed platforms - run Process project environments - search Search for development platforms - show Show details about an installed platforms - uninstall Uninstall the platforms - update Update installed platforms + init Initialize new PlatformIO based project + install Install new platforms + list List installed platforms + run Process project environments + search Search for development platforms + serialports List Serial ports + show Show details about an installed platforms + uninstall Uninstall platforms + update Update installed platforms -``platformio search`` -~~~~~~~~~~~~~~~~~~~~~ +``platformio init`` +~~~~~~~~~~~~~~~~~~~ -Search for development platforms: +Initialize new PlatformIO based project. .. code-block:: bash - # Print all available development platforms - $ platformio search all - - # Filter platforms by "Query" - $ platformio search "Query" + # Change directory to future project + $ cd /path/to/empty/directory + $ platformio init # Example - $ platformio search ti - timsp430 - An embedded platform for TI MSP430 microcontrollers (with Energia Framework) - titiva - An embedded platform for TI TIVA C ARM microcontrollers (with Energia Framework) + $ platformio init + Project has been initialized! + Please put your source code to `src` directory, external libraries to `lib` + and setup environments in `platformio.ini` file. + Then process project with `platformio run` command. - $ platformio search arduino - atmelavr - An embedded platform for Atmel AVR microcontrollers (with Arduino Framework) +After this command ``platformio`` will create: + +* ``.pioenvs`` - a temporary working directory. +* ``lib`` - a directory for project specific libraries. PlatformIO will + compile their to static libraries and link to executable file +* ``src`` - a source directory. Put code here. +* ``platformio.ini`` - a configuration file for project ``platformio install`` @@ -236,11 +322,12 @@ can install one of them: .. code-block:: bash $ platformio install SomePlatform - $ platformio install SomePlatform --with-package=PackageName - $ platformio install SomePlatform --without-package=PackageName + $ platformio install SomePlatform --with-package=toolchain|uploader|PackageName + $ platformio install SomePlatform --without-package=toolchain|uploader|PackageName + $ platformio install SomePlatform --skip-default-package # Example - $ platformio install timsp430 --with-package=framework-energiamsp430 + $ platformio install timsp430 Installing toolchain-timsp430 package: Downloading [####################################] 100% Unpacking [####################################] 100% @@ -252,6 +339,13 @@ can install one of them: Unpacking [####################################] 100% The platform 'timsp430' has been successfully installed! + # Skip default packages and install uploader utility only + $ platformio install timsp430 --skip-default-package --with-package=uploader + Installing tool-mspdebug package: + Downloading [####################################] 100% + Unpacking [####################################] 100% + The platform 'timsp430' has been successfully installed! + ``platformio list`` ~~~~~~~~~~~~~~~~~~~ @@ -267,76 +361,6 @@ To list installed platforms: timsp430 with packages: toolchain-timsp430, tool-mspdebug, framework-energiamsp430 -``platformio show`` -~~~~~~~~~~~~~~~~~~~ - -To show details about an installed platform: - -.. code-block:: bash - - $ platformio show SomePlatform - - # Example - $ platformio show timsp430 - timsp430 - An embedded platform for TI MSP430 microcontrollers (with Energia Framework) - ---------- - Package: toolchain-timsp430 - Location: /Users/ikravets/.platformio/timsp430/tools/toolchain - Version: 1 - ---------- - Package: tool-mspdebug - Location: /Users/ikravets/.platformio/timsp430/tools/mspdebug - Version: 1 - ---------- - Package: framework-energiamsp430 - Location: /Users/ikravets/.platformio/timsp430/frameworks/energia - Version: 1 - - -``platformio uninstall`` -~~~~~~~~~~~~~~~~~~~~~~~~ - -To uninstall platform: - -.. code-block:: bash - - $ platformio uninstall SomePlatform - - # Example - $ platformio uninstall timsp430 - Uninstalling toolchain-timsp430 package: [OK] - Uninstalling tool-mspdebug package: [OK] - Uninstalling framework-energiamsp430 package: [OK] - The platform 'timsp430' has been successfully uninstalled! - - -``platformio init`` -~~~~~~~~~~~~~~~~~~~ - -Initialize new platformio based project. - -.. code-block:: bash - - # Change directory to future project - $ cd /path/to/empty/directory - $ platformio init - - # Example - $ platformio init - Project successfully initialized. - Please put your source code to `src` directory, external libraries to `lib` - and setup environments in `platformio.ini` file. - Then process project with `platformio run` command. - -After this command ``platformio`` will create: - -* ``.pioenvs`` - a temporary working directory. -* ``lib`` - a directory for project specific libraries. PlatformIO will - compile their to static libraries and link to executable file -* ``src`` - a source directory. Put code here. -* ``platformio.ini`` - a configuration file for project - - ``platformio run`` ~~~~~~~~~~~~~~~~~~ @@ -372,7 +396,6 @@ Process specific environments: scons: `.pioenvs/arduino_pro5v/firmware.elf' is up to date. scons: `.pioenvs/arduino_pro5v/firmware.hex' is up to date. - Skipped launchpad_msp430g2 environment Processing launchpad_lm4f120 environment: scons: `.pioenvs/launchpad_lm4f120/firmware.elf' is up to date. scons: `.pioenvs/launchpad_lm4f120/firmware.hex' is up to date. @@ -382,7 +405,7 @@ Process specific target: .. code-block:: bash $ platformio run -t clean - $ platformio run -t upload + $ platformio run -t upload --upload-port=/dev/ttyUSBX # Example platformio run -t clean @@ -409,7 +432,6 @@ Mix environments and targets: # Example $ platformio run -e launchpad_msp430g2 -t upload - Skipped arduino_pro5v environment Processing launchpad_msp430g2 environment: /Users/ikravets/.platformio/timsp430/tools/mspdebug/mspdebug rf2500 --force-reset "prog .pioenvs/launchpad_msp430g2/firmware.hex" MSPDebug version 0.20 - debugging tool for MSP430 MCUs @@ -439,7 +461,106 @@ Mix environments and targets: Writing 32 bytes at ffe0... Done, 678 bytes total - Skipped launchpad_lm4f120 environment + +``platformio search`` +~~~~~~~~~~~~~~~~~~~~~ + +Search for development platforms: + +.. code-block:: bash + + # Print all available development platforms + $ platformio search all + + # Filter platforms by "Query" + $ platformio search "Query" + + # Example + $ platformio search ti + timsp430 - An embedded platform for TI MSP430 microcontrollers (with Energia Framework) + titiva - An embedded platform for TI TIVA C ARM microcontrollers (with Energia Framework) + + $ platformio search arduino + atmelavr - An embedded platform for Atmel AVR microcontrollers (with Arduino Framework) + + +``platformio serialports`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To list available `Serial Ports `_: + +.. code-block:: bash + + $ platformio serialports + + # Example (Posix) + $ platformio serialports + /dev/cu.SLAB_USBtoUART + ---------- + Hardware ID: USB VID:PID=10c4:ea60 SNR=0001 + Description: CP2102 USB to UART Bridge Controller + + /dev/cu.uart-1CFF4676258F4543 + ---------- + Hardware ID: USB VID:PID=451:f432 SNR=1CFF4676258F4543 + Description: Texas Instruments MSP-FET430UIF + + # Example (Windows) + $ platformio serialports + COM4 + ---------- + Hardware ID: USB VID:PID=0451:F432 + Description: MSP430 Application UART (COM4) + + COM3 + ---------- + Hardware ID: USB VID:PID=10C4:EA60 SNR=0001 + Description: Silicon Labs CP210x USB to UART Bridge (COM3) + + +``platformio show`` +~~~~~~~~~~~~~~~~~~~ + +To show details about an installed platform: + +.. code-block:: bash + + $ platformio show SomePlatform + + # Example + $ platformio show atmelavr + atmelavr - An embedded platform for Atmel AVR microcontrollers (with Arduino Framework) + ---------- + Package: toolchain-atmelavr + Alias: toolchain + Location: /Users/ikravets/.platformio/atmelavr/tools/toolchain + Version: 1 + ---------- + Package: tool-avrdude + Alias: uploader + Location: /Users/ikravets/.platformio/atmelavr/tools/avrdude + Version: 1 + ---------- + Package: framework-arduinoavr + Location: /Users/ikravets/.platformio/atmelavr/frameworks/arduino + Version: 1 + + +``platformio uninstall`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +To uninstall platform: + +.. code-block:: bash + + $ platformio uninstall SomePlatform + + # Example + $ platformio uninstall timsp430 + Uninstalling toolchain-timsp430 package: [OK] + Uninstalling tool-mspdebug package: [OK] + Uninstalling framework-energiamsp430 package: [OK] + The platform 'timsp430' has been successfully uninstalled! ``platformio update`` diff --git a/platformio/__init__.py b/platformio/__init__.py index 78c0b050..df358fd3 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -1,7 +1,7 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -VERSION = (0, 3, 1) +VERSION = (0, 4, 0) __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/__main__.py b/platformio/__main__.py index f1b052f8..bf8f26d0 100644 --- a/platformio/__main__.py +++ b/platformio/__main__.py @@ -6,7 +6,7 @@ from os.path import join from sys import exit as sys_exit from traceback import format_exc -from click import command, MultiCommand, style, version_option +from click import command, MultiCommand, version_option from platformio import __version__ from platformio.exception import PlatformioException, UnknownCLICommand @@ -35,7 +35,7 @@ class PlatformioCLI(MultiCommand): @command(cls=PlatformioCLI) -@version_option(__version__, prog_name="platformio") +@version_option(__version__, prog_name="PlatformIO") def cli(): pass @@ -45,7 +45,7 @@ def main(): cli() except Exception as e: # pylint: disable=W0703 if isinstance(e, PlatformioException): - sys_exit(style("Error: ", fg="red") + str(e)) + sys_exit("Error: " + str(e)) else: print format_exc() diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 15b0dab8..b9c05390 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -6,7 +6,8 @@ from os.path import isdir, join from SCons.Script import (DefaultEnvironment, Exit, SConscript, SConscriptChdir, Variables) -from platformio.util import get_home_dir, get_project_dir, get_source_dir +from platformio.util import (get_home_dir, get_pioenvs_dir, get_project_dir, + get_source_dir) # AllowSubstExceptions() @@ -17,6 +18,7 @@ commonvars.AddVariables( ("PLATFORM",), ("FRAMEWORK",), ("BUILD_FLAGS",), + ("SRCBUILD_FLAGS",), # board options ("BOARD",), @@ -36,13 +38,14 @@ DefaultEnvironment( PIOBUILDER_DIR=join(get_source_dir(), "builder"), PROJECT_DIR=get_project_dir(), + PIOENVS_DIR=get_pioenvs_dir(), PLATFORMIOHOME_DIR=get_home_dir(), PLATFORM_DIR=join("$PLATFORMIOHOME_DIR", "$PLATFORM"), PLATFORMFW_DIR=join("$PLATFORM_DIR", "frameworks", "$FRAMEWORK"), PLATFORMTOOLS_DIR=join("$PLATFORM_DIR", "tools"), - BUILD_DIR=join("$PROJECT_DIR", ".pioenvs", "$PIOENV"), + BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"), LIBSOURCE_DIRS=[ join("$PROJECT_DIR", "lib"), join("$PLATFORMFW_DIR", "libraries"), diff --git a/platformio/builder/scripts/atmelavr.py b/platformio/builder/scripts/atmelavr.py index 05b4f6b0..6cb008be 100644 --- a/platformio/builder/scripts/atmelavr.py +++ b/platformio/builder/scripts/atmelavr.py @@ -8,8 +8,9 @@ from os.path import join from SCons.Script import (AlwaysBuild, Builder, COMMAND_LINE_TARGETS, Default, - DefaultEnvironment, Exit, SConscript, - SConscriptChdir) + DefaultEnvironment, Exit) + +from platformio.util import reset_serialport env = DefaultEnvironment() @@ -66,9 +67,6 @@ env.Replace( UPLOADEEPCMD="$UPLOADER $UPLOADERFLAGS -U eeprom:w:$SOURCES:i" ) -if "BUILD_FLAGS" in env: - env.MergeFlags(env['BUILD_FLAGS']) - env.Append( BUILDERS=dict( ElfToEep=Builder( @@ -101,23 +99,7 @@ env.Append( ) ) -env.PrependENVPath( - "PATH", - join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") -) - -BUILT_LIBS = [] - -# -# Process framework script -# - -if "FRAMEWORK" in env: - SConscriptChdir(0) - flibs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", - "frameworks", "${FRAMEWORK}.py")), - exports="env") - BUILT_LIBS += flibs +BUILT_LIBS = env.ProcessGeneral() # # Target: Build executable and linkable firmware @@ -129,39 +111,48 @@ target_elf = env.BuildFirmware(BUILT_LIBS + ["m"]) # Target: Extract EEPROM data (from EEMEM directive) to .eep file # -target_eep = env.ElfToEep(join("$BUILD_DIR", "firmware"), target_elf) +target_eep = env.Alias("eep", env.ElfToEep(join("$BUILD_DIR", "firmware"), + target_elf)) # # Target: Build the .hex file # -target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf) +if "uploadlazy" in COMMAND_LINE_TARGETS: + target_hex = join("$BUILD_DIR", "firmware.hex") +else: + target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf) + +# +# Target: Upload by default .hex file +# + +upload = env.Alias(["upload", "uploadlazy"], target_hex, [ + lambda target, source, env: reset_serialport(env.subst("$UPLOAD_PORT")), + "$UPLOADHEXCMD"]) +AlwaysBuild(upload) # # Target: Upload .eep file # -eep = env.Alias("eep", target_eep, [ - lambda target, source, env: env.ResetDevice(), "$UPLOADEEPCMD"]) -AlwaysBuild(eep) +uploadeep = env.Alias("uploadeep", target_eep, [ + lambda target, source, env: reset_serialport(env.subst("$UPLOAD_PORT")), + "$UPLOADEEPCMD"]) +AlwaysBuild(uploadeep) # -# Target: Upload .hex file +# Check for $UPLOAD_PORT variable # -upload = env.Alias("upload", target_hex, [ - lambda target, source, env: env.ResetDevice(), "$UPLOADHEXCMD"]) -AlwaysBuild(upload) - -# -# Target: Define targets -# - -env.Alias("build-eep", [target_eep]) -Default([target_elf, target_hex]) - -# check for $UPLOAD_PORT variable -is_uptarget = ("eep" in COMMAND_LINE_TARGETS or "upload" in - COMMAND_LINE_TARGETS) +is_uptarget = (set(["upload", "uploadlazy", "uploadeep"]) & + set(COMMAND_LINE_TARGETS)) if is_uptarget and not env.subst("$UPLOAD_PORT"): - Exit("Please specify 'upload_port'") + Exit("Please specify environment 'upload_port' or use global " + "--upload-port option.") + +# +# Setup default targets +# + +Default(target_hex) diff --git a/platformio/builder/scripts/timsp430.py b/platformio/builder/scripts/timsp430.py index 4578de99..6a82a0e3 100644 --- a/platformio/builder/scripts/timsp430.py +++ b/platformio/builder/scripts/timsp430.py @@ -7,11 +7,10 @@ """ from os.path import join +from platform import system -from SCons.Script import (AlwaysBuild, Builder, Default, DefaultEnvironment, - SConscript, SConscriptChdir) - -from platformio.util import get_system +from SCons.Script import (AlwaysBuild, Builder, COMMAND_LINE_TARGETS, Default, + DefaultEnvironment) env = DefaultEnvironment() @@ -54,15 +53,12 @@ env.Replace( UPLOADER=join("$PLATFORMTOOLS_DIR", "mspdebug", "mspdebug"), UPLOADERFLAGS=[ - "$UPLOAD_PROTOCOL" if get_system() != "windows32" else "tilib", + "$UPLOAD_PROTOCOL" if system() != "Windows" else "tilib", "--force-reset" ], UPLOADCMD='$UPLOADER $UPLOADERFLAGS "prog $SOURCES"' ) -if "BUILD_FLAGS" in env: - env.MergeFlags(env['BUILD_FLAGS']) - env.Append( BUILDERS=dict( ElfToHex=Builder( @@ -79,24 +75,7 @@ env.Append( ) ) -env.PrependENVPath( - "PATH", - join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") -) - -BUILT_LIBS = [] - -# -# Process framework script -# - -if "FRAMEWORK" in env: - SConscriptChdir(0) - flibs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", - "frameworks", "${FRAMEWORK}.py")), - exports="env") - BUILT_LIBS += flibs - +BUILT_LIBS = env.ProcessGeneral() # # Target: Build executable and linkable firmware @@ -108,17 +87,20 @@ target_elf = env.BuildFirmware(BUILT_LIBS + ["m"]) # Target: Build the .hex # -target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf) +if "uploadlazy" in COMMAND_LINE_TARGETS: + target_hex = join("$BUILD_DIR", "firmware.hex") +else: + target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf) # # Target: Upload firmware # -upload = env.Alias("upload", target_hex, ["$UPLOADCMD"]) +upload = env.Alias(["upload", "uploadlazy"], target_hex, "$UPLOADCMD") AlwaysBuild(upload) # # Target: Define targets # -Default([target_elf, target_hex]) +Default(target_hex) diff --git a/platformio/builder/scripts/titiva.py b/platformio/builder/scripts/titiva.py index c5ad725f..ffb538d0 100644 --- a/platformio/builder/scripts/titiva.py +++ b/platformio/builder/scripts/titiva.py @@ -8,8 +8,8 @@ from os.path import join -from SCons.Script import (AlwaysBuild, Builder, Default, DefaultEnvironment, - SConscript, SConscriptChdir) +from SCons.Script import (AlwaysBuild, Builder, COMMAND_LINE_TARGETS, Default, + DefaultEnvironment) env = DefaultEnvironment() @@ -75,9 +75,6 @@ env.Replace( UPLOADCMD="$UPLOADER $SOURCES" ) -if "BUILD_FLAGS" in env: - env.MergeFlags(env['BUILD_FLAGS']) - env.Append( BUILDERS=dict( ElfToBin=Builder( @@ -87,28 +84,12 @@ env.Append( "binary", "$SOURCES", "$TARGET"]), - suffix=".hex" + suffix=".bin" ) ) ) -env.PrependENVPath( - "PATH", - join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") -) - -BUILT_LIBS = [] - -# -# Process framework script -# - -if "FRAMEWORK" in env: - SConscriptChdir(0) - flibs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", - "frameworks", "${FRAMEWORK}.py")), - exports="env") - BUILT_LIBS += flibs +BUILT_LIBS = env.ProcessGeneral() # # Target: Build executable and linkable firmware @@ -120,17 +101,20 @@ target_elf = env.BuildFirmware(BUILT_LIBS + ["c", "gcc", "m"]) # Target: Build the .bin file # -target_bin = env.ElfToBin(join("$BUILD_DIR", "firmware"), target_elf) +if "uploadlazy" in COMMAND_LINE_TARGETS: + target_bin = join("$BUILD_DIR", "firmware.bin") +else: + target_bin = env.ElfToBin(join("$BUILD_DIR", "firmware"), target_elf) # # Target: Upload firmware # -upload = env.Alias("upload", target_bin, ["$UPLOADCMD"]) +upload = env.Alias(["upload", "uploadlazy"], target_bin, "$UPLOADCMD") AlwaysBuild(upload) # # Target: Define targets # -Default([target_elf, target_bin]) +Default(target_bin) diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index fc8aa0b6..9216c606 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -2,11 +2,28 @@ # See LICENSE for details. import re -from os import listdir, walk +from os import getenv, listdir, walk from os.path import isdir, isfile, join -from time import sleep -from serial import Serial +from SCons.Script import SConscript, SConscriptChdir + + +def ProcessGeneral(env): + libs = [] + if "BUILD_FLAGS" in env: + env.MergeFlags(env['BUILD_FLAGS']) + + env.PrependENVPath( + "PATH", + join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") + ) + + if "FRAMEWORK" in env: + SConscriptChdir(0) + libs = SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", + "frameworks", "${FRAMEWORK}.py")), + exports="env") + return libs def BuildLibrary(env, variant_dir, library_dir): @@ -46,6 +63,8 @@ def BuildFirmware(env, libslist): if _libs: libslist += _libs + src.MergeFlags(getenv("PIOSRCBUILD_FLAGS", "$SRCBUILD_FLAGS")) + return src.Program( join("$BUILD_DIR", "firmware"), [src.GlobCXXFiles(vdir) for vdir in vdirs], @@ -116,23 +135,12 @@ def ParseBoardOptions(env, path, name): return data -def ResetDevice(env): - """ Pulse the DTR line and flush serial buffer """ - s = Serial(env.subst("$UPLOAD_PORT")) - s.flushInput() - s.setDTR(False) - s.setRTS(False) - sleep(0.1) - s.setDTR(True) - s.setRTS(True) - s.close() - - def exists(_): return True def generate(env): + env.AddMethod(ProcessGeneral) env.AddMethod(BuildLibrary) env.AddMethod(BuildDependentLibraries) env.AddMethod(BuildFirmware) @@ -140,5 +148,4 @@ def generate(env): env.AddMethod(GetDependentLibraries) env.AddMethod(VariantDirRecursive) env.AddMethod(ParseBoardOptions) - env.AddMethod(ResetDevice) return env diff --git a/platformio/commands/init.py b/platformio/commands/init.py index b1dd14bd..418783b2 100644 --- a/platformio/commands/init.py +++ b/platformio/commands/init.py @@ -11,18 +11,18 @@ from platformio.exception import ProjectInitialized from platformio.util import get_source_dir -@command("init", short_help="Initialize new platformio based project") +@command("init", short_help="Initialize new PlatformIO based project") def cli(): if isfile("platformio.ini") and isdir("src"): raise ProjectInitialized() - for d in (".pioenvs", "lib", "src"): + for d in ("lib", "src"): if not isdir(d): makedirs(d) if not isfile("platformio.ini"): copyfile(join(get_source_dir(), "projectconftpl.ini"), "platformio.ini") - secho("Project successfully initialized.\n" + secho("Project has been initialized!\n" "Please put your source code to `src` directory, " "external libraries to `lib` and " "setup environments in `platformio.ini` file.\n" diff --git a/platformio/commands/install.py b/platformio/commands/install.py index 09f75500..834ce14c 100644 --- a/platformio/commands/install.py +++ b/platformio/commands/install.py @@ -3,19 +3,18 @@ from click import argument, command, option, secho -from platformio.platforms._base import PlatformFactory +from platformio.platforms.base import PlatformFactory @command("install", short_help="Install new platforms") @argument("platforms", nargs=-1) -@option('--with-package', multiple=True, metavar="") -@option('--without-package', multiple=True, metavar="") -def cli(platforms, with_package, without_package): +@option("--with-package", multiple=True, metavar="") +@option("--without-package", multiple=True, metavar="") +@option("--skip-default-package", is_flag=True) +def cli(platforms, with_package, without_package, skip_default_package): for platform in platforms: - p = PlatformFactory().newPlatform(platform) - - if p.install(with_package, without_package): + if p.install(with_package, without_package, skip_default_package): secho("The platform '%s' has been successfully installed!" % platform, fg="green") diff --git a/platformio/commands/list.py b/platformio/commands/list.py index 699d2fb0..990429bf 100644 --- a/platformio/commands/list.py +++ b/platformio/commands/list.py @@ -9,7 +9,7 @@ from platformio.pkgmanager import PackageManager @command("list", short_help="List installed platforms") def cli(): - for name, pkgs in PackageManager.get_installed().iteritems(): + for name, pkgs in PackageManager.get_installed().items(): echo("{name:<20} with packages: {pkgs}".format( name=style(name, fg="cyan"), pkgs=", ".join(pkgs.keys()) diff --git a/platformio/commands/run.py b/platformio/commands/run.py index 5f88253f..4422c1d0 100644 --- a/platformio/commands/run.py +++ b/platformio/commands/run.py @@ -3,34 +3,46 @@ from click import command, echo, option, secho, style -from platformio.exception import ProjectEnvsNotAvaialable, UndefinedEnvPlatform -from platformio.platforms._base import PlatformFactory +from platformio.exception import (InvalidEnvName, ProjectEnvsNotAvaialable, + UndefinedEnvPlatform, UnknownEnvNames) +from platformio.platforms.base import PlatformFactory from platformio.util import get_project_config @command("run", short_help="Process project environments") @option("--environment", "-e", multiple=True, metavar="") @option("--target", "-t", multiple=True, metavar="") -def cli(environment, target): +@option("--upload-port", metavar="") +def cli(environment, target, upload_port): config = get_project_config() if not config.sections(): raise ProjectEnvsNotAvaialable() + unknown = set(environment) - set([s[4:] for s in config.sections()]) + if unknown: + raise UnknownEnvNames(", ".join(unknown)) + for section in config.sections(): if section[:4] != "env:": - continue + raise InvalidEnvName(section) envname = section[4:] if environment and envname not in environment: - echo("Skipped %s environment" % style(envname, fg="yellow")) + # echo("Skipped %s environment" % style(envname, fg="yellow")) continue echo("Processing %s environment:" % style(envname, fg="cyan")) - variables = ["%s=%s" % (o.upper(), v) for o, v in config.items(section) - if o != "targets"] - variables.append("PIOENV=" + envname) + + variables = ["PIOENV=" + envname] + if upload_port: + variables.append("UPLOAD_PORT=%s" % upload_port) + for k, v in config.items(section): + k = k.upper() + if k == "TARGETS" or (k == "UPLOAD_PORT" and upload_port): + continue + variables.append("%s=%s" % (k.upper(), v)) envtargets = [] if target: diff --git a/platformio/commands/search.py b/platformio/commands/search.py index 9990b488..2457b05e 100644 --- a/platformio/commands/search.py +++ b/platformio/commands/search.py @@ -3,7 +3,7 @@ from click import argument, command, echo, style -from platformio.platforms._base import PlatformFactory +from platformio.platforms.base import PlatformFactory from platformio.util import get_platforms diff --git a/platformio/commands/serialports.py b/platformio/commands/serialports.py new file mode 100644 index 00000000..79b3d67d --- /dev/null +++ b/platformio/commands/serialports.py @@ -0,0 +1,17 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +from click import command, echo, secho + +from platformio.util import get_serialports + + +@command("serialports", short_help="List Serial ports") +def cli(): + + for item in get_serialports(): + secho(item['port'], fg="cyan") + echo("----------") + echo("Hardware ID: %s" % item['hwid']) + echo("Description: %s" % item['description']) + echo("") diff --git a/platformio/commands/show.py b/platformio/commands/show.py index 9ae904c9..616a7a51 100644 --- a/platformio/commands/show.py +++ b/platformio/commands/show.py @@ -7,7 +7,7 @@ from click import argument, command, echo, style from platformio.exception import PlatformNotInstalledYet from platformio.pkgmanager import PackageManager -from platformio.platforms._base import PlatformFactory +from platformio.platforms.base import PlatformFactory @command("show", short_help="Show details about an installed platforms") @@ -22,8 +22,11 @@ def cli(platform): info=p.get_short_info())) pm = PackageManager(platform) - for name, data in pm.get_installed(platform).iteritems(): + for name, data in pm.get_installed(platform).items(): + pkgalias = p.get_pkg_alias(name) echo("----------") echo("Package: %s" % style(name, fg="yellow")) + if pkgalias: + echo("Alias: %s" % pkgalias) echo("Location: %s" % join(pm.get_platform_dir(), data['path'])) echo("Version: %d" % int(data['version'])) diff --git a/platformio/commands/uninstall.py b/platformio/commands/uninstall.py index 92c5b0cf..72765911 100644 --- a/platformio/commands/uninstall.py +++ b/platformio/commands/uninstall.py @@ -5,10 +5,10 @@ from click import argument, command, secho from platformio.exception import PlatformNotInstalledYet from platformio.pkgmanager import PackageManager -from platformio.platforms._base import PlatformFactory +from platformio.platforms.base import PlatformFactory -@command("uninstall", short_help="Uninstall the platforms") +@command("uninstall", short_help="Uninstall platforms") @argument("platforms", nargs=-1) def cli(platforms): diff --git a/platformio/commands/update.py b/platformio/commands/update.py index 6bd2432d..8fad8523 100644 --- a/platformio/commands/update.py +++ b/platformio/commands/update.py @@ -4,7 +4,7 @@ from click import command, echo, style from platformio.pkgmanager import PackageManager -from platformio.platforms._base import PlatformFactory +from platformio.platforms.base import PlatformFactory @command("update", short_help="Update installed platforms") diff --git a/platformio/exception.py b/platformio/exception.py index e58b35b3..7b7d08f1 100644 --- a/platformio/exception.py +++ b/platformio/exception.py @@ -85,3 +85,18 @@ class ProjectInitialized(PlatformioException): class ProjectEnvsNotAvaialable(PlatformioException): MESSAGE = "Please setup environments in `platformio.ini` file." + + +class InvalidEnvName(PlatformioException): + + MESSAGE = "Invalid environment '%s'. The name must start " "with 'env:'." + + +class UnknownEnvNames(PlatformioException): + + MESSAGE = "Unknown environment names '%s'." + + +class GetSerialPortsError(PlatformioException): + + MESSAGE = "No implementation for your platform ('%s') available" diff --git a/platformio/pkgmanager.py b/platformio/pkgmanager.py index 6822acbc..11c06991 100644 --- a/platformio/pkgmanager.py +++ b/platformio/pkgmanager.py @@ -14,7 +14,7 @@ from platformio.downloader import FileDownloader from platformio.exception import (InvalidPackageVersion, NonSystemPackage, UnknownPackage) from platformio.unpacker import FileUnpacker -from platformio.util import get_home_dir, get_system +from platformio.util import get_home_dir, get_systype class PackageManager(object): @@ -66,11 +66,11 @@ class PackageManager(object): raise UnknownPackage(name) # check system platform - system = get_system() - builds = ([b for b in manifest[name] if b['system'] == "all" or system + systype = get_systype() + builds = ([b for b in manifest[name] if b['system'] == "all" or systype in b['system']]) if not builds: - raise NonSystemPackage(name, system) + raise NonSystemPackage(name, systype) if version: for b in builds: diff --git a/platformio/platforms/atmelavr.py b/platformio/platforms/atmelavr.py index 676cb010..4ba6e117 100644 --- a/platformio/platforms/atmelavr.py +++ b/platformio/platforms/atmelavr.py @@ -3,7 +3,7 @@ from os.path import join -from platformio.platforms._base import BasePlatform +from platformio.platforms.base import BasePlatform class AtmelavrPlatform(BasePlatform): @@ -16,12 +16,14 @@ class AtmelavrPlatform(BasePlatform): "toolchain-atmelavr": { "path": join("tools", "toolchain"), + "alias": "toolchain", "default": True }, "tool-avrdude": { "path": join("tools", "avrdude"), - "default": True, + "alias": "uploader", + "default": True }, "framework-arduinoavr": { diff --git a/platformio/platforms/_base.py b/platformio/platforms/base.py similarity index 68% rename from platformio/platforms/_base.py rename to platformio/platforms/base.py index fc92a733..cbca3fea 100644 --- a/platformio/platforms/_base.py +++ b/platformio/platforms/base.py @@ -40,30 +40,49 @@ class BasePlatform(object): else: raise NotImplementedError() - def install(self, with_packages, without_packages): - requirements = [] - pm = PackageManager(self.get_name()) + def get_pkg_alias(self, pkgname): + return self.PACKAGES[pkgname].get("alias", None) - upkgs = set(with_packages + without_packages) + def pkg_aliases_to_names(self, aliases): + names = [] + for alias in aliases: + name = alias + # lookup by packages alias + if name not in self.PACKAGES: + for _name, _opts in self.PACKAGES.items(): + if _opts.get("alias", None) == alias: + name = _name + break + names.append(name) + return names + + def install(self, with_packages, without_packages, skip_default_packages): + with_packages = set(self.pkg_aliases_to_names(with_packages)) + without_packages = set(self.pkg_aliases_to_names(without_packages)) + + upkgs = with_packages | without_packages ppkgs = set(self.PACKAGES.keys()) if not upkgs.issubset(ppkgs): raise UnknownPackage(", ".join(upkgs - ppkgs)) - for name, opts in self.PACKAGES.iteritems(): + requirements = [] + for name, opts in self.PACKAGES.items(): if name in without_packages: continue - elif name in with_packages or opts["default"]: - requirements.append((name, opts["path"])) + elif (name in with_packages or (not skip_default_packages and + opts['default'])): + requirements.append((name, opts['path'])) + pm = PackageManager(self.get_name()) for (package, path) in requirements: pm.install(package, path) - return True + return len(requirements) def uninstall(self): platform = self.get_name() pm = PackageManager(platform) - for package, data in pm.get_installed(platform).iteritems(): + for package, data in pm.get_installed(platform).items(): pm.uninstall(package, data['path']) pm.unregister_platform(platform) diff --git a/platformio/platforms/timsp430.py b/platformio/platforms/timsp430.py index 34a859b5..7058af16 100644 --- a/platformio/platforms/timsp430.py +++ b/platformio/platforms/timsp430.py @@ -3,7 +3,7 @@ from os.path import join -from platformio.platforms._base import BasePlatform +from platformio.platforms.base import BasePlatform class Timsp430Platform(BasePlatform): @@ -16,12 +16,14 @@ class Timsp430Platform(BasePlatform): "toolchain-timsp430": { "path": join("tools", "toolchain"), + "alias": "toolchain", "default": True }, "tool-mspdebug": { "path": join("tools", "mspdebug"), - "default": True, + "alias": "uploader", + "default": True }, "framework-energiamsp430": { diff --git a/platformio/platforms/titiva.py b/platformio/platforms/titiva.py index ecdba125..ed89cb44 100644 --- a/platformio/platforms/titiva.py +++ b/platformio/platforms/titiva.py @@ -3,7 +3,7 @@ from os.path import join -from platformio.platforms._base import BasePlatform +from platformio.platforms.base import BasePlatform class TitivaPlatform(BasePlatform): @@ -16,12 +16,14 @@ class TitivaPlatform(BasePlatform): "toolchain-gccarmnoneeabi": { "path": join("tools", "toolchain"), + "alias": "toolchain", "default": True }, "tool-lm4flash": { "path": join("tools", "lm4flash"), - "default": True, + "alias": "uploader", + "default": True }, "framework-energiativa": { diff --git a/platformio/projectconftpl.ini b/platformio/projectconftpl.ini index 18348f52..06d414ba 100644 --- a/platformio/projectconftpl.ini +++ b/platformio/projectconftpl.ini @@ -14,7 +14,8 @@ # Environment with specific build flags #[env:specbuildflags] #platform = %INSTALLED_PLATFORM_NAME_HERE% -#build_flags = "-I/opt/include -L/opt/lib -lfoo -DMYDEFINE=13" +#build_flags = "-I/opt/include -L/opt/lib -lfoo" +#srcbuild_flags = "-DSPECIAL_DEFINE_FOR_MY_SRC_FILES=13" # # Atmel AVR based board diff --git a/platformio/util.py b/platformio/util.py index 87168a6f..3604c84d 100644 --- a/platformio/util.py +++ b/platformio/util.py @@ -1,12 +1,16 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -from os import getcwd, listdir, utime +from os import name as os_name +from os import getcwd, getenv, listdir, utime from os.path import dirname, expanduser, isfile, join, realpath -from platform import architecture, system +from platform import system, uname from subprocess import PIPE, Popen +from time import sleep -from platformio.exception import NotPlatformProject +from serial import Serial + +from platformio.exception import GetSerialPortsError, NotPlatformProject try: from configparser import ConfigParser @@ -14,8 +18,11 @@ except ImportError: from ConfigParser import ConfigParser -def get_system(): - return (system() + architecture()[0][:-3]).lower() +def get_systype(): + if system() == "Windows": + return "windows" + data = uname() + return ("%s_%s" % (data[0], data[4])).lower() def get_home_dir(): @@ -30,6 +37,10 @@ def get_project_dir(): return getcwd() +def get_pioenvs_dir(): + return getenv("PIOENVS_DIR", join(get_project_dir(), ".pioenvs")) + + def get_project_config(): path = join(get_project_dir(), "platformio.ini") if not isfile(path): @@ -53,7 +64,28 @@ def change_filemtime(path, time): def exec_command(args): - use_shell = get_system() == "windows32" + use_shell = system() == "Windows" p = Popen(args, stdout=PIPE, stderr=PIPE, shell=use_shell) out, err = p.communicate() return dict(out=out.strip(), err=err.strip()) + + +def reset_serialport(port): + s = Serial(port) + s.flushInput() + s.setDTR(False) + s.setRTS(False) + sleep(0.1) + s.setDTR(True) + s.setRTS(True) + s.close() + + +def get_serialports(): + if os_name == "nt": + from serial.tools.list_ports_windows import comports + elif os_name == "posix": + from serial.tools.list_ports_posix import comports + else: + raise GetSerialPortsError(os_name) + return[{"port": p, "description": d, "hwid": h} for p, d, h in comports()] diff --git a/requirements.txt b/requirements.txt index 3c510e96..ffd41083 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -click==2.1 +click==2.5 colorama==0.3.1 pyserial==2.7 requests==2.3.0