From 020c1c797592c318ea1ee523c3eaea2b4965ac6a Mon Sep 17 00:00:00 2001 From: hoosierEE Date: Tue, 17 Nov 2015 13:26:42 -0500 Subject: [PATCH 01/43] Slight grammar/wording tweaks --- README.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index a272fce8..c0130649 100644 --- a/README.rst +++ b/README.rst @@ -32,7 +32,7 @@ PlatformIO `Home & Demo `_ | `Project Examples `_ | `Source Code `_ | -`Documentation `_ || +`Documentation `_ | `Blog `_ | `Twitter `_ | `Hackaday `_ | @@ -43,8 +43,8 @@ PlatformIO :target: http://platformio.org `PlatformIO `_ is an open-source cross-platform code -builder and the missing library manager (Ready for embedded development, IDE -and Continuous integration, Arduino and MBED compatible). +builder and library manager. For embedded development, IDE +and Continuous integration. Arduino and MBED compatible. *Atmel AVR & SAM, Espressif, Freescale Kinetis, Nordic nRF51, NXP LPC, Silicon Labs EFM32, ST STM32, TI MSP430 & Tiva, Teensy, Arduino, mbed, @@ -66,15 +66,15 @@ libOpenCM3, etc.* * `FAQ `_ * `Release History `_ -You have **no need** to install any *IDE* or compile any tool chains. *PlatformIO* -has pre-built different development platforms and pre-configured settings for +You have **no need** to install any *IDE* or compile any toolchains. *PlatformIO* +has pre-built development platforms and pre-configured settings for the most popular embedded boards. For further details, please refer to `What is PlatformIO? `_ Use whenever. *Run everywhere.* ------------------------------- *PlatformIO* is written in pure *Python* and **doesn't depend** on any -additional libraries/tools from an operation system. It allows you to use +additional libraries/tools from an operating system. It allows you to use *PlatformIO* beginning from *PC (Mac, Linux, Win)* and ending with credit-card sized computers (`Raspberry Pi `_, `BeagleBone `_, @@ -134,8 +134,8 @@ cross-platform substitute for the classic *Make* utility. Single source code. *Multiple platforms.* ----------------------------------------- -*PlatformIO* allows developer to compile the same code with different -development platforms using the *Only One Command* +*PlatformIO* allows the developer to compile the same code with different +development platforms using only *One Command* `platformio run `_. This happens due to `Project Configuration File (platformio.ini) `_ From 159c0a93d29eba18289b52f62905ed573bfef735 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 18 Nov 2015 20:14:16 +0200 Subject: [PATCH 02/43] Start 2.4.0 --- HISTORY.rst | 3 +++ platformio/__init__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index 6ab8840d..3126c337 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,6 +4,9 @@ Release History PlatformIO 2.0 -------------- +2.4.0 (2015-??-??) +~~~~~~~~~~~~~~~~~~ + 2.3.5 (2015-11-18) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/__init__.py b/platformio/__init__.py index 4c084e76..230d8e85 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 3, 5) +VERSION = (2, 4, "0.dev5") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 5a83ebe48ee1e33c1fa8b04047eedc1afe1932aa Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 20 Nov 2015 22:41:36 +0200 Subject: [PATCH 03/43] Add new article by @joshglendenning about "@Armstrap Eagle and @PlatformIO" --- docs/articles.rst | 1 + docs/projectconf.rst | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/articles.rst b/docs/articles.rst index 26b5291e..0ab570dc 100644 --- a/docs/articles.rst +++ b/docs/articles.rst @@ -27,6 +27,7 @@ Here are recent articles about PlatformIO: * Nov 06, 2015 - **nocd5** - `PlatformIOでmbedをオフラインビルドしSTM32 Nucleoボードでmrubyを使う (Use mruby in the offline build for STM32 Nucleo board with mbed and PlatformIO, Japanese) `_ * Oct 18, 2015 - **Nico Coetzee** - `First Arduino I2C Experience with PlatformIO `_ * Sep 01, 2015 - **Thomas P. Weldon, Ph.D.** - `Improvised MBED FRDM-K64F Eclipse/PlatformIO Setup and Software Installation `_ +* Aug 08, 2015 - **Josh Glendenning** - `Armstrap Eagle and PlatformIO `_ * Aug 01, 2015 - **Russell Davis** - `PlatformIO on the Raspberry Pi `_ * Jul 25, 2015 - **DinoTools** - `Erste Schritte mit PlatformIO (Getting Started with PlatformIO, German) `_ * Jul 20, 2015 - **Eli Fatsi** - `Arduino Development in Atom Editor `_ diff --git a/docs/projectconf.rst b/docs/projectconf.rst index ea1d5768..b259395f 100644 --- a/docs/projectconf.rst +++ b/docs/projectconf.rst @@ -530,6 +530,8 @@ Then upload firmware using :option:`platformio run --target program` board = armstrap_eagle512 upload_protocol = gdb +Also, take a look at this article `Armstrap Eagle and PlatformIO `_. + 5. :ref:`platform_ststm32`: Upload firmware using ST-Link instead mbed's media disk From c0eded84a09e1a9c9dbd8e45427717b2a357bf3d Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 23 Nov 2015 17:27:02 +0200 Subject: [PATCH 04/43] Only bug fixes in 2.3.6 --- HISTORY.rst | 2 +- platformio/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 3126c337..b5f837ab 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,7 +4,7 @@ Release History PlatformIO 2.0 -------------- -2.4.0 (2015-??-??) +2.3.6 (2015-??-??) ~~~~~~~~~~~~~~~~~~ 2.3.5 (2015-11-18) diff --git a/platformio/__init__.py b/platformio/__init__.py index 230d8e85..f0250033 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 4, "0.dev5") +VERSION = (2, 3, "6.dev0") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 970ddd44bf7d5748691a2956ee286cfd60629fb5 Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Mon, 23 Nov 2015 18:39:56 +0200 Subject: [PATCH 05/43] Fix maximum_size for ESP-12E board // Resolve #333 --- platformio/boards/espressif.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/boards/espressif.json b/platformio/boards/espressif.json index b42f129b..249733d2 100644 --- a/platformio/boards/espressif.json +++ b/platformio/boards/espressif.json @@ -35,7 +35,7 @@ "platform": "espressif", "upload": { "maximum_ram_size": 32768, - "maximum_size": 524288, + "maximum_size": 4194304, "protocol": "arduino", "require_upload_port" : true, "speed": 115200 From dd5a509a992f54faf7eedf071fc074270bd1373f Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 24 Nov 2015 13:14:41 +0200 Subject: [PATCH 06/43] Fix ESP-12E flash size // Resolve #333 --- HISTORY.rst | 3 +++ platformio/builder/scripts/espressif.py | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index b5f837ab..9f8561b6 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,6 +7,9 @@ PlatformIO 2.0 2.3.6 (2015-??-??) ~~~~~~~~~~~~~~~~~~ +* Fixed ESP-12E flash size + (`pull #333 `_) + 2.3.5 (2015-11-18) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/builder/scripts/espressif.py b/platformio/builder/scripts/espressif.py index fde0f7b6..2496111c 100644 --- a/platformio/builder/scripts/espressif.py +++ b/platformio/builder/scripts/espressif.py @@ -103,6 +103,8 @@ if "FRAMEWORK" in env: ] ) +_board_max_rom = int( + env.get("BOARD_OPTIONS", {}).get("upload", {}).get("maximum_size", 0)) env.Append( BUILDERS=dict( ElfToBin=Builder( @@ -113,8 +115,9 @@ env.Append( "-bo", "$TARGET", "-bm", "dio", "-bf", "${BOARD_OPTIONS['build']['f_cpu'][:2]}", - "-bz", str(int(env.get("BOARD_OPTIONS", {}).get( - "upload", {}).get("maximum_size") / 1024)) + "K", + "-bz", + "%dK" % (_board_max_rom / 1024) if _board_max_rom < 1048576 + else "%dM" % (_board_max_rom / 1048576), "-bs", ".text", "-bp", "4096", "-ec", From c8b6bd1c2cbad4d4516ec18ca309b9f36610d0f8 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 24 Nov 2015 17:17:25 +0200 Subject: [PATCH 07/43] Add new article "Using PlatformIO to get started with Arduino in CLion IDE" by @mseroczynski --- docs/articles.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/articles.rst b/docs/articles.rst index 0ab570dc..98c4666a 100644 --- a/docs/articles.rst +++ b/docs/articles.rst @@ -23,6 +23,7 @@ Here are recent articles about PlatformIO: 2015 ^^^^ +* Nov 22, 2015 - **Michał Seroczyński** - `Using PlatformIO to get started with Arduino in CLion IDE `_ * Nov 09, 2015 - **ÁLvaro García Gómez** - `Programar con Arduino "The good way" (Programming with Arduino "The good way", Spanish) `_ * Nov 06, 2015 - **nocd5** - `PlatformIOでmbedをオフラインビルドしSTM32 Nucleoボードでmrubyを使う (Use mruby in the offline build for STM32 Nucleo board with mbed and PlatformIO, Japanese) `_ * Oct 18, 2015 - **Nico Coetzee** - `First Arduino I2C Experience with PlatformIO `_ From 238ce2e85813db8841f6e6d975ed507222c8b027 Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Tue, 24 Nov 2015 19:08:19 +0200 Subject: [PATCH 08/43] fix moteinomega configuration // Resolve #335 --- platformio/boards/misc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/boards/misc.json b/platformio/boards/misc.json index ed4fde29..a5080010 100644 --- a/platformio/boards/misc.json +++ b/platformio/boards/misc.json @@ -434,7 +434,7 @@ "extra_flags": "-DARDUINO_ARCH_AVR -DAVR_MOTEINOMEGA", "f_cpu": "16000000L", "mcu": "atmega1284p", - "variant": "moteinoMega" + "variant": "moteinomega" }, "frameworks": ["arduino"], "name": "LowPowerLab MoteinoMEGA", From 354fbf625351c3afca46b933cd2ad7083903dc94 Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Tue, 24 Nov 2015 19:20:20 +0200 Subject: [PATCH 09/43] Add new board with mbed framework support --- platformio/boards/atmelsam.json | 50 ++++++++++ platformio/boards/ststm32.json | 96 +++++++++++++++++++ platformio/builder/scripts/frameworks/mbed.py | 7 +- 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 platformio/boards/atmelsam.json diff --git a/platformio/boards/atmelsam.json b/platformio/boards/atmelsam.json new file mode 100644 index 00000000..bb2561ee --- /dev/null +++ b/platformio/boards/atmelsam.json @@ -0,0 +1,50 @@ +{ + "samr21_xpro": { + "build": { + "f_cpu": "48000000L", + "cpu": "cortex-m0plus", + "mcu": "atsamr21g18a" + }, + "frameworks": ["mbed"], + "name": "Atmel ATSAMR21-XPRO", + "platform": "atmelsam", + "upload": { + "maximum_ram_size": 32768, + "maximum_size": 262144 + }, + "url": "https://developer.mbed.org/platforms/SAMR21-XPRO/", + "vendor": "Atmel" + }, + "saml21_xpro_b": { + "build": { + "f_cpu": "48000000L", + "cpu": "cortex-m0plus", + "mcu": "atsaml21j18b" + }, + "frameworks": ["mbed"], + "name": "Atmel SAML21-XPRO-B", + "platform": "atmelsam", + "upload": { + "maximum_ram_size": 32768, + "maximum_size": 262144 + }, + "url": "https://developer.mbed.org/platforms/SAML21-XPRO/", + "vendor": "Atmel" + }, + "samd21_xpro": { + "build": { + "f_cpu": "48000000L", + "cpu": "cortex-m0plus", + "mcu": "atsamd21j18a" + }, + "frameworks": ["mbed"], + "name": "Atmel SAMD21-XPRO", + "platform": "atmelsam", + "upload": { + "maximum_ram_size": 32768, + "maximum_size": 262144 + }, + "url": "https://developer.mbed.org/platforms/SAMD21-XPRO/", + "vendor": "Atmel" + } +} diff --git a/platformio/boards/ststm32.json b/platformio/boards/ststm32.json index 4eef729d..cd5483a3 100644 --- a/platformio/boards/ststm32.json +++ b/platformio/boards/ststm32.json @@ -441,5 +441,101 @@ }, "url": "http://www.st.com/web/en/catalog/tools/PF260318", "vendor": "ST" + }, + "disco_f469ni": { + "build": { + "f_cpu": "180000000L", + "cpu": "cortex-m4", + "mcu": "stm32f469nih6" + }, + "frameworks": ["mbed"], + "name": "ST 32F469IDISCOVERY", + "platform": "ststm32", + "upload": { + "maximum_ram_size": 393216, + "maximum_size": 1048576 + }, + "url": "http://www.st.com/web/catalog/tools/FM116/CL1620/SC959/SS1532/LN1848/PF262395", + "vendor": "ST" + }, + "disco_l476vg": { + "build": { + "f_cpu": "80000000L", + "cpu": "cortex-m4", + "mcu": "stm32l476vgt6" + }, + "frameworks": ["mbed"], + "name": "ST 32L476GDISCOVERY", + "platform": "ststm32", + "upload": { + "maximum_ram_size": 131072, + "maximum_size": 1048576 + }, + "url": "http://www.st.com/web/catalog/tools/FM116/CL1620/SC959/SS1532/LN1848/PF261635", + "vendor": "ST" + }, + "nucleo_f031k6": { + "build": { + "f_cpu": "48000000L", + "cpu": "cortex-m0", + "mcu": "stm32f031k6t6" + }, + "frameworks": ["mbed"], + "name": "ST Nucleo F031K6", + "platform": "ststm32", + "upload": { + "maximum_ram_size": 4096, + "maximum_size": 32768 + }, + "url": "https://developer.mbed.org/platforms/ST-Nucleo-F031K6/", + "vendor": "ST" + }, + "nucleo_f042k6": { + "build": { + "f_cpu": "48000000L", + "cpu": "cortex-m0", + "mcu": "stm32f042k6t6" + }, + "frameworks": ["mbed"], + "name": "ST Nucleo F042K6", + "platform": "ststm32", + "upload": { + "maximum_ram_size": 6144, + "maximum_size": 32768 + }, + "url": "https://developer.mbed.org/platforms/ST-Nucleo-F042K6/", + "vendor": "ST" + }, + "nucleo_f303k8": { + "build": { + "f_cpu": "72000000L", + "cpu": "cortex-m4", + "mcu": "stm32f303k8t6" + }, + "frameworks": ["mbed"], + "name": "ST Nucleo F303K8", + "platform": "ststm32", + "upload": { + "maximum_ram_size": 16384, + "maximum_size": 65536 + }, + "url": "https://developer.mbed.org/platforms/ST-Nucleo-F303K8/", + "vendor": "ST" + }, + "nucleo_l476rg": { + "build": { + "f_cpu": "80000000L", + "cpu": "cortex-m4", + "mcu": "stm32l476rgt6" + }, + "frameworks": ["mbed"], + "name": "ST Nucleo L476RG", + "platform": "ststm32", + "upload": { + "maximum_ram_size": 131072, + "maximum_size": 1048576 + }, + "url": "https://developer.mbed.org/platforms/ST-Nucleo-L476RG/", + "vendor": "ST" } } diff --git a/platformio/builder/scripts/frameworks/mbed.py b/platformio/builder/scripts/frameworks/mbed.py index fbd86801..a5f9b76e 100644 --- a/platformio/builder/scripts/frameworks/mbed.py +++ b/platformio/builder/scripts/frameworks/mbed.py @@ -54,7 +54,7 @@ MBED_VARIANTS = { "seeedTinyBLE": "SEEED_TINY_BLE", "redBearLab": "RBLAB_NRF51822", "nrf51-dt": "NRF51_DK", - "redBearLabBLENano": "RBLAB_NRF51822", + "redBearLabBLENano": "RBLAB_BLENANO", "wallBotBLE": "NRF51822", "frdm_kl25z": "KL25Z", "frdm_kl46z": "KL46Z", @@ -63,7 +63,10 @@ MBED_VARIANTS = { "frdm_k20d50m": "K20D50M", "frdm_k22f": "K22F", "teensy31": "TEENSY3_1", - "dfcm_nnn40": "DELTA_DFCM_NNN40" + "dfcm_nnn40": "DELTA_DFCM_NNN40", + "samr21_xpro": "SAMR21G18A", + "saml21_xpro_b": "SAML21J18A", + "samd21_xpro": "SAMD21J18A" } MBED_LIBS_MAP = { From d63f6cff080a67095be76f1881e45ce295fa6b05 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 24 Nov 2015 19:58:24 +0200 Subject: [PATCH 10/43] Update FAQ & History // Resolve #331 --- HISTORY.rst | 8 +++++++ docs/faq.rst | 67 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 9f8561b6..40d0c7d8 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,8 +7,16 @@ PlatformIO 2.0 2.3.6 (2015-??-??) ~~~~~~~~~~~~~~~~~~ +* Added support for the new boards: Atmel ATSAMR21-XPRO, Atmel SAML21-XPRO-B, + Atmel SAMD21-XPRO, ST 32F469IDISCOVERY, ST 32L476GDISCOVERY, ST Nucleo F031K6, + ST Nucleo F042K6, ST Nucleo F303K8 and ST Nucleo L476RG +* Added to FAQ explanation of `Can not compile a library that compiles without issue + with Arduino IDE `_ + (`issue #331 `_) * Fixed ESP-12E flash size (`pull #333 `_) +* Fixed configuration for LowPowerLab MoteinoMEGA board + (`issue #335 `_) 2.3.5 (2015-11-18) ~~~~~~~~~~~~~~~~~~ diff --git a/docs/faq.rst b/docs/faq.rst index 9a11def4..be85c3f4 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -132,25 +132,15 @@ Answered in `issue #279 `_. Answered in `issue #295 `_. -.. _faq_troubleshooting_pioblocksprompt: +Windows AttributeError: 'module' object has no attribute 'packages' +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -PlatformIO blocks command execution using user prompt -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you are going to run *PlatformIO* from **subprocess**, you **MUST -DISABLE** all prompts. It will allow you to avoid blocking. -There are a few options: - -- using :option:`platformio --force` option before each command -- using environment variable :envvar:`PLATFORMIO_SETTING_ENABLE_PROMPTS=No ` -- disable global setting ``enable_prompts`` via :ref:`cmd_settings` command -- masking under Continuous Integration system via environment variable - :envvar:`CI=true `. +Answered in `issue #252 `_. .. _faq_troubleshooting_pionotfoundinpath: Program ``platformio`` not found in PATH -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'''''''''''''''''''''''''''''''''''''''' Where is ``platformio`` binary installed? Run this command in Terminal @@ -173,18 +163,12 @@ programs to the ``bin`` directory which is included in ``$PATH``. For example, see `issue #272 `_. Windows UnicodeDecodeError: 'ascii' codec can't decode byte -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Answered in `issue #143 `_. -Serial does not work with panStampAVR board -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Answered in `issue #144 `_. - - -PlatformIO: command not found || An error ``pkg_resources.DistributionNotFound`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +PlatformIO: command not found || An error "pkg_resources.DistributionNotFound" +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Please upgrade *SetupTools* package: @@ -197,18 +181,45 @@ Please upgrade *SetupTools* package: [sudo] pip uninstall platformio [sudo] pip install platformio -Windows AttributeError: 'module' object has no attribute 'packages' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Miscellaneous +~~~~~~~~~~~~~ -Answered in `issue #252 `_. +.. _faq_troubleshooting_pioblocksprompt: + +PlatformIO blocks command execution using user prompt +''''''''''''''''''''''''''''''''''''''''''''''''''''' + +If you are going to run *PlatformIO* from **subprocess**, you **MUST +DISABLE** all prompts. It will allow you to avoid blocking. +There are a few options: + +- using :option:`platformio --force` option before each command +- using environment variable :envvar:`PLATFORMIO_SETTING_ENABLE_PROMPTS=No ` +- disable global setting ``enable_prompts`` via :ref:`cmd_settings` command +- masking under Continuous Integration system via environment variable + :envvar:`CI=true `. + +Serial does not work with panStampAVR board +''''''''''''''''''''''''''''''''''''''''''' + +Answered in `issue #144 `_. + +Building +~~~~~~~~ + +Can not compile a library that compiles without issue with Arduino IDE +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +* `#298: Unable to use Souliss library `_ +* `#331: Unable to use MySensors library `_ ARM toolchain: cc1plus: error while loading shared libraries -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' See related answers for `error while loading shared libraries `_. Archlinux: libncurses.so.5: cannot open shared object file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Answered in `issue #291 `_. From aef06e837a5cce1dfb8f49abab411db766d5abdb Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 25 Nov 2015 19:54:06 +0200 Subject: [PATCH 11/43] Fix "LockFailed: failed to create appstate.json.lock" error for Windows --- HISTORY.rst | 1 + platformio/__init__.py | 2 +- platformio/app.py | 31 ++++++++++++++++++------------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 40d0c7d8..cee52cd5 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -17,6 +17,7 @@ PlatformIO 2.0 (`pull #333 `_) * Fixed configuration for LowPowerLab MoteinoMEGA board (`issue #335 `_) +* Fixed "LockFailed: failed to create appstate.json.lock" error for Windows 2.3.5 (2015-11-18) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/__init__.py b/platformio/__init__.py index f0250033..452e9841 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 3, "6.dev0") +VERSION = (2, 3, "6.dev1") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/app.py b/platformio/app.py index 0fc162ee..9a59e130 100644 --- a/platformio/app.py +++ b/platformio/app.py @@ -13,6 +13,7 @@ # limitations under the License. import json +from copy import deepcopy from os import environ, getenv from os.path import getmtime, isfile, join from time import time @@ -23,6 +24,7 @@ from platformio import __version__ from platformio.exception import InvalidSettingName, InvalidSettingValue from platformio.util import get_home_dir, is_ci + DEFAULT_SETTINGS = { "check_platformio_interval": { "description": "Check for the new PlatformIO interval (days)", @@ -70,13 +72,14 @@ SESSION_VARS = { class State(object): - def __init__(self, path=None): + def __init__(self, path=None, lock=False): self.path = path + self.lock = lock if not self.path: self.path = join(get_home_dir(), "appstate.json") self._state = {} self._prev_state = {} - self._lock = None + self._lockfile = None def __enter__(self): try: @@ -86,7 +89,7 @@ class State(object): self._state = json.load(fp) except ValueError: self._state = {} - self._prev_state = self._state.copy() + self._prev_state = deepcopy(self._state) return self._state def __exit__(self, type_, value, traceback): @@ -99,17 +102,19 @@ class State(object): self._unlock_state_file() def _lock_state_file(self): - self._lock = LockFile(self.path) + if not self.lock: + return + self._lockfile = LockFile(self.path) - if (self._lock.is_locked() and - (time() - getmtime(self._lock.lock_file)) > 10): - self._lock.break_lock() + if (self._lockfile.is_locked() and + (time() - getmtime(self._lockfile.lock_file)) > 10): + self._lockfile.break_lock() - self._lock.acquire() + self._lockfile.acquire() def _unlock_state_file(self): - if self._lock: - self._lock.release() + if self._lockfile: + self._lockfile.release() def sanitize_setting(name, value): @@ -136,7 +141,7 @@ def get_state_item(name, default=None): def set_state_item(name, value): - with State() as data: + with State(lock=True) as data: data[name] = value @@ -159,14 +164,14 @@ def get_setting(name): def set_setting(name, value): - with State() as data: + with State(lock=True) as data: if "settings" not in data: data['settings'] = {} data['settings'][name] = sanitize_setting(name, value) def reset_settings(): - with State() as data: + with State(lock=True) as data: if "settings" in data: del data['settings'] From f17d2d7f90d123c8e4955dc10626b4266604ef7f Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 25 Nov 2015 22:27:57 +0200 Subject: [PATCH 12/43] @circleci doesn't support matrix builds --- circle.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/circle.yml b/circle.yml index a2ec6207..ccc55a3a 100644 --- a/circle.yml +++ b/circle.yml @@ -1,11 +1,6 @@ machine: python: version: 2.7 - environment: - TOX_ENV: docs - TOX_ENV: lint - TOX_ENV: py26 - TOX_ENV: py27 checkout: post: @@ -18,4 +13,4 @@ dependencies: test: override: - - tox -e $TOX_ENV + - tox -e py27 From 8023b85085f4fb152669e312279d597574f208b1 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 26 Nov 2015 00:10:36 +0200 Subject: [PATCH 13/43] Improve @circleci doc --- docs/ci/circleci.rst | 170 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 145 insertions(+), 25 deletions(-) diff --git a/docs/ci/circleci.rst b/docs/ci/circleci.rst index 773d7769..cd07c9bf 100644 --- a/docs/ci/circleci.rst +++ b/docs/ci/circleci.rst @@ -37,49 +37,169 @@ different :ref:`platforms`. Integration ----------- -Put ``circle.yml`` to the root directory of the GitHub repository. +Please make sure to read Circle CI `Getting Started `_ +guide first. + +.. code-block:: yaml + + dependencies: + pre: + # Install the latest stable PlatformIO + - sudo pip install -U platformio + + test: + override: + - platformio ci path/to/test/file.c --board=TYPE_1 --board=TYPE_2 --board=TYPE_N + - platformio ci examples/file.ino --board=TYPE_1 --board=TYPE_2 --board=TYPE_N + - platformio ci path/to/test/directory --board=TYPE_1 --board=TYPE_2 --board=TYPE_N + + +For more details as for PlatformIO build process please look into :ref:`cmd_ci`. + +Project as a library +~~~~~~~~~~~~~~~~~~~~ + +When project is written as a library (where own examples or testing code use +it), please use ``--lib="."`` option for :ref:`cmd_ci` command + +.. code-block:: yaml + + script: + - platformio ci --lib="." --board=TYPE_1 --board=TYPE_2 --board=TYPE_N + +Library dependecies +~~~~~~~~~~~~~~~~~~~ + +There 2 options to test source code with dependent libraries: + +Install dependent library using :ref:`librarymanager` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: yaml + + dependencies: + pre: + # Install the latest stable PlatformIO + - sudo pip install -U platformio + + # OneWire Library with ID=1 http://platformio.org/#!/lib/show/1/OneWire + - platformio lib install 1 + + test: + override: + - platformio ci path/to/test/file.c --board=TYPE_1 --board=TYPE_2 --board=TYPE_N + +Manually download dependent library and include in build process via ``--lib`` option +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: yaml + + dependencies: + pre: + # Install the latest stable PlatformIO + - sudo pip install -U platformio + + # download library to the temporary directory + - wget https://github.com/PaulStoffregen/OneWire/archive/master.zip -O /tmp/onewire_source.zip + - unzip /tmp/onewire_source.zip -d /tmp/ + + test: + override: + - platformio ci path/to/test/file.c --lib="/tmp/OneWire-master" --board=TYPE_1 --board=TYPE_2 --board=TYPE_N + +Custom Build Flags +~~~~~~~~~~~~~~~~~~ + +PlatformIO allows to specify own build flags using :envvar:`PLATFORMIO_BUILD_FLAGS` environment .. code-block:: yaml machine: environment: - PLATFORMIO_CI_SRC: path/to/source/file.c - PLATFORMIO_CI_SRC: path/to/source/file.ino - PLATFORMIO_CI_SRC: path/to/source/directory + PLATFORMIO_BUILD_FLAGS: -D SPECIFIC_MACROS -I/extra/inc - dependencies: - pre: - - sudo apt-get install python2.7-dev - - sudo python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" + +For the more details, please follow to +:ref:`available build flags/options `. + + +Advanced configuration +~~~~~~~~~~~~~~~~~~~~~~ + +PlatformIO allows to configure multiple build environments for the single +source code using :ref:`projectconf`. + +Instead of ``--board`` option, please use :option:`platformio ci --project-conf` + +.. code-block:: yaml test: override: - - platformio ci --board=TYPE_1 --board=TYPE_2 --board=TYPE_N - - -For more details as for PlatformIO build process please look into :ref:`cmd_ci` -command. + - platformio ci path/to/test/file.c --project-conf=/path/to/platoformio.ini Examples -------- -1. Integration for `USB_Host_Shield_2.0 `_ - project. The ``circle.yml`` configuration file: +1. Custom build flags .. code-block:: yaml - machine: - environment: - PLATFORMIO_CI_SRC: examples/Bluetooth/PS3SPP/PS3SPP.ino - PLATFORMIO_CI_SRC: examples/pl2303/pl2303_gps/pl2303_gps.ino - dependencies: + cache_directories: + - "~/.platformio" + pre: - - sudo apt-get install python2.7-dev - - sudo python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" - - wget https://github.com/xxxajk/spi4teensy3/archive/master.zip -O /tmp/spi4teensy3.zip - - unzip /tmp/spi4teensy3.zip -d /tmp + - sudo pip install -U platformio + + # pre-install PlatformIO development platforms, they will be cached + - platformio platforms install atmelavr atmelsam teensy + + # + # Libraries from PlatformIO Library Registry: + # + # http://platformio.org/#!/lib/show/416/TinyGPS + # http://platformio.org/#!/lib/show/417/SPI4Teensy3 + - platformio lib install 416 417 test: override: - - platformio ci --lib="." --lib="/tmp/spi4teensy3-master" --board=uno --board=teensy31 --board=due + - platformio ci examples/acm/acm_terminal --board=uno --board=teensy31 --board=due --lib="." + - platformio ci examples/adk/adk_barcode --board=uno --board=teensy31 --board=due --lib="." + - platformio ci examples/adk/ArduinoBlinkLED --board=uno --board=teensy31 --board=due --lib="." + - platformio ci examples/adk/demokit_20 --board=uno --board=teensy31 --board=due --lib="." + # ... + - platformio ci examples/Xbox/XBOXUSB --board=uno --board=teensy31 --board=due --lib="." + +* Configuration file: https://github.com/ivankravets/USB_Host_Shield_2.0/blob/master/circle.yml +* Build History: https://circleci.com/gh/ivankravets/USB_Host_Shield_2.0/tree/master + +2. Dependency on external libraries + +.. code-block:: yaml + + dependencies: + pre: + # Install the latest stable PlatformIO + - sudo pip install -U platformio + + # download dependent libraries + - wget https://github.com/jcw/jeelib/archive/master.zip -O /tmp/jeelib.zip + - unzip /tmp/jeelib.zip -d /tmp + + - wget https://github.com/Rodot/Gamebuino/archive/master.zip -O /tmp/gamebuino.zip + - unzip /tmp/gamebuino.zip -d /tmp + + test: + override: + - platformio ci examples/backSoon/backSoon.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + - platformio ci examples/etherNode/etherNode.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + - platformio ci examples/getDHCPandDNS/getDHCPandDNS.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + - platformio ci examples/getStaticIP/getStaticIP.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + # ... + - platformio ci examples/twitter/twitter.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + - platformio ci examples/udpClientSendOnly/udpClientSendOnly.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + - platformio ci examples/udpListener/udpListener.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + - platformio ci examples/webClient/webClient.ino --lib="." --lib="/tmp/jeelib-master" --lib="/tmp/Gamebuino-master/libraries/tinyFAT" --board=uno --board=megaatmega2560 + +* Configuration file: hhttps://github.com/ivankravets/ethercard/blob/master/circle.yaml +* Build History: https://circleci.com/gh/ivankravets/ethercard/tree/master From a085d90af2667890424241456230653be49e08bf Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 26 Nov 2015 00:32:23 +0200 Subject: [PATCH 14/43] Fix broken link --- docs/ci/circleci.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ci/circleci.rst b/docs/ci/circleci.rst index cd07c9bf..dd87976c 100644 --- a/docs/ci/circleci.rst +++ b/docs/ci/circleci.rst @@ -37,7 +37,7 @@ different :ref:`platforms`. Integration ----------- -Please make sure to read Circle CI `Getting Started `_ +Please make sure to read Circle CI `Getting Started `_ guide first. .. code-block:: yaml From 426b276b086c7e3b7d4f13ccf1c93601ac860506 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 26 Nov 2015 13:28:48 +0200 Subject: [PATCH 15/43] Rename to Custom Board/Platform --- docs/platforms/creating_board.rst | 4 ++-- docs/platforms/creating_platform.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/platforms/creating_board.rst b/docs/platforms/creating_board.rst index 51dabba3..cfe19f14 100644 --- a/docs/platforms/creating_board.rst +++ b/docs/platforms/creating_board.rst @@ -11,8 +11,8 @@ .. _board_creating: -Creating Board -============== +Custom Board +============ *PlatformIO* has pre-built settings for the most popular embedded boards. This list is available: diff --git a/docs/platforms/creating_platform.rst b/docs/platforms/creating_platform.rst index 2eb22c8d..3f5a29d2 100644 --- a/docs/platforms/creating_platform.rst +++ b/docs/platforms/creating_platform.rst @@ -11,8 +11,8 @@ .. _platform_creating: -Creating Platform -================= +Custom Platform +=============== *PlatformIO* was developed like a tool which would build the same source code for the different development platforms via single command :ref:`cmd_run` From fb4d605e3364664a80573d0ebd2d7d589c342dc5 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 26 Nov 2015 13:31:41 +0200 Subject: [PATCH 16/43] Rename to Custom Board/Platform --- docs/platforms/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/platforms/index.rst b/docs/platforms/index.rst index 2509b8c5..bb890287 100644 --- a/docs/platforms/index.rst +++ b/docs/platforms/index.rst @@ -52,8 +52,8 @@ Desktop linux_x86_64 windows_x86 -Own Platform/Board ------------------- +Custom Platform & Board +----------------------- .. toctree:: :maxdepth: 2 From 25f57cc6837edcb8fec794c78c877f62c68f39e8 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 26 Nov 2015 14:44:44 +0200 Subject: [PATCH 17/43] Add logo to the docs --- docs/_static/favicon.ico | Bin 0 -> 32038 bytes docs/_static/platformio-logo.png | Bin 13461 -> 28410 bytes docs/conf.py | 26 +++++++++++++------------- docs/index.rst | 3 --- 4 files changed, 13 insertions(+), 16 deletions(-) create mode 100644 docs/_static/favicon.ico diff --git a/docs/_static/favicon.ico b/docs/_static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2dd9609c3e98fea6e50ab277306b8e2cdb4882a8 GIT binary patch literal 32038 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 Pu$hB;8o(%Tq=f(g9kN7D literal 0 HcmV?d00001 diff --git a/docs/_static/platformio-logo.png b/docs/_static/platformio-logo.png index 8cbe937ad619a01ebec6b0d8830e5bff2498a7d2..a8b025d5addf39fc485342f2cae03a41f6e846f8 100644 GIT binary patch delta 28085 zcmbQ5`RgvDduM>3J1>_M7Xt$WucwDg5Ca3lJ`m<$V_;zDF4;Plfq{XsILO_JVcj{I zmkbOHoCO|{#S9GG!XV7ZFl&wk0|QIfL@()yvvq_cd;=7m^NUgyO!Z9k43zA+6ci@2 zGdi(xDS*IaPewT&2ouCrP?(&~sD~;rmC;rVS%pGHZcbjYRY_*rvaF3nBN zD*@$ z`g)$#*Q+aommfNNBm2ramQQJts}qe+-wI!&I@wTf>(W2sxjnsG0%K%PnoZ1Ydzz!> z|Mq}cr@GqDQrX$P&ud!pBUe8QFMO?AIq&A7{Jr^UuXlc`=PJKe^sh_)d9G^Ao)cSD z>+a?l*O$&boh$r2S7UvJ{w5>6XAkVpdvANR`z-VNOOqA;gl9hLp8R$}rL{n_(f*Co zzWn`jJ$KI4TPCZwyluGRcOaAT`*Y^ab1mnc{pixi&X=~faJ7TZqq*llZA-VPlj@ru zwRmsN;@rw-GPe(WWqNwP{)1COS?|+Z+Iw0X)^BPKH~kR1TKn+Qo84O$XMfhZee_f= zpKF5nfvwgFw@?1odY9+@ytOrb*PQgr7yH>6XVo?yxtCMFyVyqj z@R6ARtNAWWd(UJLmtL`B-%0aNE1a%LrXJYPGkZtwLkso~#v)BUwue62Klt5vX6d#y z7EA873uS@j4xvvz&8fLWV7_JiNkjiv< z9{bt;!27LtcJiifu)CwOi%-O5&;GT4#L^FLo3w7NkwHD{fw=bCxU}UHPi&v~ve
yh59&O^iMy0GuW$Z(gcUwRg5>Rny0=>^f@Yd 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 Q7#J8lUHx3vIVCg!07EFO$N&HU delta 13070 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 * `Web 2.0 Library Search `_ | `Embedded Boards Explorer `_ From 9bd1f99b69c667b22721accafdb06e9a20bbaa3a Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Thu, 26 Nov 2015 20:19:36 +0200 Subject: [PATCH 18/43] Improve espressif platform for RC version of framework --- platformio/boards/espressif.json | 2 +- platformio/builder/scripts/espressif.py | 5 ++++- platformio/builder/scripts/frameworks/arduino.py | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/platformio/boards/espressif.json b/platformio/boards/espressif.json index 249733d2..f2c4e3f5 100644 --- a/platformio/boards/espressif.json +++ b/platformio/boards/espressif.json @@ -3,7 +3,7 @@ "build": { "core": "esp8266", "extra_flags": "-DARDUINO_ESP8266_ESP01 -DARDUINO_ARCH_ESP8266 -DESP8266", - "f_cpu": "40000000L", + "f_cpu": "80000000L", "ldscript": "esp8266.flash.512k.ld", "mcu": "esp8266", "variant": "generic" diff --git a/platformio/builder/scripts/espressif.py b/platformio/builder/scripts/espressif.py index 2496111c..8515cabd 100644 --- a/platformio/builder/scripts/espressif.py +++ b/platformio/builder/scripts/espressif.py @@ -75,7 +75,10 @@ env.Replace( "-nostdlib", "-Wl,--no-check-sections", "-u", "call_user_start", - "-Wl,-static" + "-Wl,-static", + "-Wl,--gc-sections", + "-Wl,-wrap,system_restart_local", + "-Wl,-wrap,register_chipv6_phy" ], SIZEPRINTCMD='"$SIZETOOL" -B -d $SOURCES', diff --git a/platformio/builder/scripts/frameworks/arduino.py b/platformio/builder/scripts/frameworks/arduino.py index b534f8ac..f6637e36 100644 --- a/platformio/builder/scripts/frameworks/arduino.py +++ b/platformio/builder/scripts/frameworks/arduino.py @@ -55,10 +55,10 @@ elif env.get("PLATFORM") == "timsp430": ) elif env.get("PLATFORM") == "espressif": env.Prepend( - CPPPATH=[join("$PLATFORMFW_DIR", "sdk", "include")], - LIBPATH=[join("$PLATFORMFW_DIR", "sdk", "lib")], + CPPPATH=[join("$PLATFORMFW_DIR", "tools", "sdk", "include")], + LIBPATH=[join("$PLATFORMFW_DIR", "tools", "sdk", "lib")], LIBS=["smartconfig", "pp", "main", "wpa", "lwip", - "net80211", "wps", "crypto", "phy", "hal", "gcc", "m"] + "net80211", "wps", "crypto", "phy", "hal", "axtls", "gcc", "m"] ) env.Replace(PLATFORMFW_DIR=PLATFORMFW_DIR) From ed32e07e34823ddd2c987df3f25f3e58990277db Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 26 Nov 2015 22:02:59 +0200 Subject: [PATCH 19/43] Better exceptions handling --- platformio/__main__.py | 13 +++++++++++++ platformio/commands/lib.py | 2 +- platformio/commands/upgrade.py | 6 +++--- platformio/exception.py | 23 +++++++++-------------- platformio/libmanager.py | 10 +++++----- platformio/maintenance.py | 7 +------ platformio/platforms/base.py | 2 +- platformio/telemetry.py | 5 ++++- 8 files changed, 37 insertions(+), 31 deletions(-) diff --git a/platformio/__main__.py b/platformio/__main__.py index b437e760..299ee5eb 100644 --- a/platformio/__main__.py +++ b/platformio/__main__.py @@ -103,6 +103,19 @@ def main(): error_str += str(e) else: error_str += format_exc() + + error_str += """ +============================================================ + +An unexpected error occurred. Further steps: + +* Verify that you have the latest version of PlatformIO using + `platformio upgrade` command +* Report this problem to the developers + https://github.com/platformio/platformio/issues + +============================================================ +""" click.secho(error_str, fg="red", err=True) return 1 return 0 diff --git a/platformio/commands/lib.py b/platformio/commands/lib.py index 72c21737..883f2c9f 100644 --- a/platformio/commands/lib.py +++ b/platformio/commands/lib.py @@ -135,7 +135,7 @@ def lib_install(ctx, libid, version): except AssertionError: raise exception.LibInstallDependencyError(str(item)) - except exception.LibAlreadyInstalledError: + except exception.LibAlreadyInstalled: click.secho("Already installed", fg="yellow") diff --git a/platformio/commands/upgrade.py b/platformio/commands/upgrade.py index 438e5dc2..761644bb 100644 --- a/platformio/commands/upgrade.py +++ b/platformio/commands/upgrade.py @@ -56,9 +56,9 @@ def cli(): click.echo("Release notes: ", nl=False) click.secho("http://docs.platformio.org/en/latest/history.html", fg="cyan") - except (OSError, AssertionError) as e: + except Exception as e: # pylint: disable=W0703 if not r: - raise exception.PlatformioUpgradeError( + raise exception.UpgradeError( "\n".join([str(cmd), str(e)])) if ("Permission denied" in r['err'] and "windows" not in util.get_systype()): @@ -74,7 +74,7 @@ WARNING! Don't use `sudo` for the rest PlatformIO commands. """, fg="yellow", err=True) raise exception.ReturnErrorCode() else: - raise exception.PlatformioUpgradeError( + raise exception.UpgradeError( "\n".join([str(cmd), r['out'], r['err']])) diff --git a/platformio/exception.py b/platformio/exception.py index e0378083..74491f70 100644 --- a/platformio/exception.py +++ b/platformio/exception.py @@ -149,11 +149,11 @@ class APIRequestError(PlatformioException): MESSAGE = "[API] %s" -class LibAlreadyInstalledError(PlatformioException): +class LibAlreadyInstalled(PlatformioException): pass -class LibNotInstalledError(PlatformioException): +class LibNotInstalled(PlatformioException): MESSAGE = "Library #%d has not been installed yet" @@ -183,11 +183,6 @@ class InvalidSettingValue(PlatformioException): MESSAGE = "Invalid value '%s' for the setting '%s'" -class UpgraderFailed(PlatformioException): - - MESSAGE = "An error occurred while upgrading PlatformIO" - - class CIBuildEnvsEmpty(PlatformioException): MESSAGE = "Can't find PlatformIO build environments.\n"\ @@ -195,20 +190,20 @@ class CIBuildEnvsEmpty(PlatformioException): "predefined environments using `--project-conf` option" -class SConsNotInstalled(PlatformioException): +class SConsNotInstalledError(PlatformioException): MESSAGE = "The PlatformIO and `scons` aren't installed properly. "\ "More details in FAQ/Troubleshooting section: "\ "http://docs.platformio.org/en/latest/faq.html" -class PlatformioUpgradeError(PlatformioException): +class UpgradeError(PlatformioException): - MESSAGE = "%s \n\n"\ - "1. Please report this issue here: "\ - "https://github.com/platformio/platformio/issues \n"\ - "2. Try different installation/upgrading steps: "\ - "http://docs.platformio.org/en/latest/installation.html" + MESSAGE = """%s + +* Try different installation/upgrading steps: + http://docs.platformio.org/en/latest/installation.html +""" class CygwinEnvDetected(PlatformioException): diff --git a/platformio/libmanager.py b/platformio/libmanager.py index 0dbe0df0..cd0b57fa 100644 --- a/platformio/libmanager.py +++ b/platformio/libmanager.py @@ -21,7 +21,7 @@ from tempfile import gettempdir from platformio import telemetry, util from platformio.downloader import FileDownloader -from platformio.exception import LibAlreadyInstalledError, LibNotInstalledError +from platformio.exception import LibAlreadyInstalled, LibNotInstalled from platformio.unpacker import FileUnpacker @@ -73,17 +73,17 @@ class LibraryManager(object): for item in self.get_installed().values(): if "id" in item and item['id'] == id_: return item - raise LibNotInstalledError(id_) + raise LibNotInstalled(id_) def is_installed(self, id_): try: return int(self.get_info(id_)['id']) == id_ - except LibNotInstalledError: + except LibNotInstalled: return False def install(self, id_, version=None): if self.is_installed(id_): - raise LibAlreadyInstalledError() + raise LibAlreadyInstalled() dlinfo = util.get_api_result( "/lib/download/" + str(id_), @@ -120,4 +120,4 @@ class LibraryManager(object): label="#%d %s" % (id_, item['name']) ) return True - raise LibNotInstalledError(id_) + raise LibNotInstalled(id_) diff --git a/platformio/maintenance.py b/platformio/maintenance.py index a60e90d9..dc5a2861 100644 --- a/platformio/maintenance.py +++ b/platformio/maintenance.py @@ -145,11 +145,6 @@ def after_upgrade(ctx): click.style("give", fg="cyan"), click.style("https://github.com/platformio/platformio", fg="cyan") )) - click.echo("- %s for the new features/issues on Bountysource > %s" % ( - click.style("vote", fg="cyan"), - click.style("https://www.bountysource.com/teams/platformio/issues", - fg="cyan") - )) click.echo("*" * terminal_width) click.echo("") @@ -171,7 +166,7 @@ def after_upgrade(ctx): telemetry.on_event(category="Auto", action="Upgrade", label="%s > %s" % (last_version, __version__)) else: - raise exception.UpgraderFailed() + raise exception.UpgradeError("Auto upgrading...") click.echo("") diff --git a/platformio/platforms/base.py b/platformio/platforms/base.py index 2fcaf8cd..c4488dd1 100644 --- a/platformio/platforms/base.py +++ b/platformio/platforms/base.py @@ -395,7 +395,7 @@ class BasePlatform(object): stderr=util.AsyncPipe(self.on_run_err) ) except (OSError, AssertionError): - raise exception.SConsNotInstalled() + raise exception.SConsNotInstalledError() assert "returncode" in result # if self._found_error: diff --git a/platformio/telemetry.py b/platformio/telemetry.py index 17dccb38..43a501dd 100644 --- a/platformio/telemetry.py +++ b/platformio/telemetry.py @@ -291,7 +291,10 @@ def on_exception(e): return mp = MeasurementProtocol() mp['exd'] = "%s: %s" % (type(e).__name__, e) - mp['exf'] = int(not isinstance(e, exception.PlatformioException)) + mp['exf'] = int(any([ + not isinstance(e, exception.PlatformioException), + "Error" in e.__class__.__name__ + ])) mp.send("exception") From e85bc3931520aa0e13441f2a56ce11d8bbfea13b Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 26 Nov 2015 22:15:57 +0200 Subject: [PATCH 20/43] Fix inaccurate Vim instructions // Issue #340 --- docs/ide/vim.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/ide/vim.rst b/docs/ide/vim.rst index fd147487..d97d3912 100644 --- a/docs/ide/vim.rst +++ b/docs/ide/vim.rst @@ -56,6 +56,10 @@ Now, in VIM ``cd /path/to/this/project`` and press ``Ctrl+B`` or ``Cmd+B`` (Mac). *PlatformIO* should compile your source code from the ``src`` directory, make firmware and upload it. +.. note:: + If hotkey doesn't work for you, try to add this line + ``nnoremap :make`` to ``~/.vimrc`` + Screenshot ---------- From bf9c9b8985a9f54d322a3938d19aa5c3590fd985 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 00:37:46 +0200 Subject: [PATCH 21/43] Add navbar to doc --- docs/_static/extra.css | 254 ++++++++++++++++++++++++++++++++++++ docs/_templates/layout.html | 48 +++++++ docs/conf.py | 2 +- 3 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 docs/_static/extra.css create mode 100644 docs/_templates/layout.html diff --git a/docs/_static/extra.css b/docs/_static/extra.css new file mode 100644 index 00000000..846e05d9 --- /dev/null +++ b/docs/_static/extra.css @@ -0,0 +1,254 @@ +/** + * Copyright 2014-2015 Ivan Kravets + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +header, +nav { + display: block; +} + +#pionav { + display: none; +} + +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + #pionav { + display: block !important; + } + body { + padding-top: 50px; + } + .wy-nav-side { + top: 50px; + } + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after { + display: table; + content: " "; +} +.container:after, +.container-fluid:after, +.nav:after, +.navbar:after, +.navbar-header:after { + clear: both; +} + +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li > a > img { + max-width: none; +} + +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} + +@media (min-width: 768px) { + .navbar-fixed-top { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top { + max-height: 340px; +} +.container > .navbar-header, +.container-fluid > .navbar-header { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header { + margin-right: 0; + margin-left: 0; + } +} + +.navbar-fixed-top { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} + +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} + +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} + +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} + +.navbar-header .navbar-brand { + color: #e0e0e0; +} diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 00000000..2ff727f3 --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,48 @@ +{% extends "!layout.html" %} +{%- set extra_css_files = ["_static/extra.css"] %} + +{% block sidebartitle %} + {% if theme_display_version %} + {%- set nav_version = version %} + {% if READTHEDOCS and current_version %} + {%- set nav_version = current_version %} + {% endif %} + {% if nav_version %} +

+ {{ nav_version }} +
+ {% endif %} + {% endif %} + + {% include "searchbox.html" %} +{% endblock %} + +{% block footer %} + + + +{% endblock %} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index cb04d018..f73c94ea 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -119,7 +119,7 @@ html_theme = 'default' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = '_static/platformio-logo.png' +#html_logo = '_static/platformio-logo.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 From 304339e30971ce22422920ffcd903d29e7f44f5f Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 13:22:06 +0200 Subject: [PATCH 22/43] Try navbar over footer --- docs/_templates/{layout.html => footer.html} | 25 ++++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) rename docs/_templates/{layout.html => footer.html} (72%) diff --git a/docs/_templates/layout.html b/docs/_templates/footer.html similarity index 72% rename from docs/_templates/layout.html rename to docs/_templates/footer.html index 2ff727f3..0e85bc9c 100644 --- a/docs/_templates/layout.html +++ b/docs/_templates/footer.html @@ -1,24 +1,7 @@ -{% extends "!layout.html" %} -{%- set extra_css_files = ["_static/extra.css"] %} - -{% block sidebartitle %} - {% if theme_display_version %} - {%- set nav_version = version %} - {% if READTHEDOCS and current_version %} - {%- set nav_version = current_version %} - {% endif %} - {% if nav_version %} -
- {{ nav_version }} -
- {% endif %} - {% endif %} - - {% include "searchbox.html" %} -{% endblock %} - -{% block footer %} +{% extends "!footer.html" %} +{% block extrafooter %} + - +{{ super() }} {% endblock %} \ No newline at end of file From 221b7ed188d69e9ba28a01318cc841b6891f4bd3 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 21:15:09 +0200 Subject: [PATCH 23/43] Fix relative include path for preprocessor using "build_flags" // Resolve #271 --- HISTORY.rst | 2 ++ platformio/__init__.py | 2 +- platformio/builder/tools/platformio.py | 32 +++++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index cee52cd5..46545814 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -18,6 +18,8 @@ PlatformIO 2.0 * Fixed configuration for LowPowerLab MoteinoMEGA board (`issue #335 `_) * Fixed "LockFailed: failed to create appstate.json.lock" error for Windows +* Fixed relative include path for preprocessor using ``build_flags`` + (`issue #271 `_) 2.3.5 (2015-11-18) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/__init__.py b/platformio/__init__.py index 452e9841..7b30378b 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 3, "6.dev1") +VERSION = (2, 3, "6.dev2") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index c74ce530..ec98e587 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -15,7 +15,7 @@ import re from glob import glob from os import getenv, listdir, sep, walk -from os.path import basename, dirname, isdir, isfile, join, normpath +from os.path import basename, dirname, isdir, isfile, join, normpath, realpath from SCons.Script import (COMMAND_LINE_TARGETS, DefaultEnvironment, Exit, SConscript) @@ -39,7 +39,11 @@ def BuildProgram(env): ASCOM="$ASPPCOM" ) - env.ProcessFlags() + env.ProcessFlags([ + env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags", None), + env.get("BUILD_FLAGS"), + getenv("PLATFORMIO_BUILD_FLAGS", None), + ]) env.BuildFramework() # build dependent libs @@ -62,10 +66,10 @@ def BuildProgram(env): ) # Handle SRC_BUILD_FLAGS - if getenv("PLATFORMIO_SRC_BUILD_FLAGS", None): - env.MergeFlags(getenv("PLATFORMIO_SRC_BUILD_FLAGS")) - if "SRC_BUILD_FLAGS" in env: - env.MergeFlags(env['SRC_BUILD_FLAGS']) + env.ProcessFlags([ + env.get("SRC_BUILD_FLAGS"), + getenv("PLATFORMIO_SRC_BUILD_FLAGS", None), + ]) env.Append( CPPDEFINES=["PLATFORMIO={0:02d}{1:02d}{2:02d}".format( @@ -83,15 +87,15 @@ def BuildProgram(env): ) -def ProcessFlags(env): - if "extra_flags" in env.get("BOARD_OPTIONS", {}).get("build", {}): - env.MergeFlags(env.subst("${BOARD_OPTIONS['build']['extra_flags']}")) +def ProcessFlags(env, flags): + for f in flags: + if f: + env.MergeFlags(f) - # Handle BUILD_FLAGS - if getenv("PLATFORMIO_BUILD_FLAGS", None): - env.MergeFlags(getenv("PLATFORMIO_BUILD_FLAGS")) - if "BUILD_FLAGS" in env: - env.MergeFlags(env['BUILD_FLAGS']) + # fix relative CPPPATH + for i, p in enumerate(env.get("CPPPATH", [])): + if isdir(p): + env['CPPPATH'][i] = realpath(p) # Cancel any previous definition of name, either built in or # provided with a -D option // Issue #191 From 774ea5240e851669b28f8fd9ae3692e6f7f6141a Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 21:16:20 +0200 Subject: [PATCH 24/43] Update click to 6.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2207d695..c6882dd1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ bottle==0.12.9 -click==5.1 +click==6.1 colorama==0.3.3 lockfile==0.11.0 pyserial==2.7 From 332b19f35b9f89f1166c0cbe5c0d790cc6011756 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 21:19:19 +0200 Subject: [PATCH 25/43] Update requirements.txt --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index c6882dd1..ef8dd85c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ bottle==0.12.9 -click==6.1 +click==6.2 colorama==0.3.3 -lockfile==0.11.0 +lockfile==0.12.2 pyserial==2.7 requests==2.8.1 scons==2.4.1 From 7ce1dd4f5c5382bd35da61e9bf8d44326f15cda3 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 21:59:08 +0200 Subject: [PATCH 26/43] Fix ParseFlags for mbed --- platformio/__init__.py | 2 +- platformio/builder/scripts/frameworks/mbed.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index 7b30378b..4a829ad3 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 3, "6.dev2") +VERSION = (2, 3, "6.dev3") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/builder/scripts/frameworks/mbed.py b/platformio/builder/scripts/frameworks/mbed.py index a5f9b76e..a0454b07 100644 --- a/platformio/builder/scripts/frameworks/mbed.py +++ b/platformio/builder/scripts/frameworks/mbed.py @@ -29,7 +29,7 @@ http://mbed.org/ import re import xml.etree.ElementTree as ElementTree from binascii import crc32 -from os import walk +from os import getenv, walk from os.path import basename, isfile, join, normpath from SCons.Script import DefaultEnvironment, Exit @@ -226,7 +226,11 @@ env.Replace( ) # restore external build flags -env.ProcessFlags() +env.ProcessFlags([ + env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags", None), + env.get("BUILD_FLAGS"), + getenv("PLATFORMIO_BUILD_FLAGS", None), +]) # Hook for K64F and K22F if board_type in ("frdm_k22f", "frdm_k64f"): From 304c023b4ec63dd126aaca88cced3a6cd72a45b5 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 23:49:49 +0200 Subject: [PATCH 27/43] Fix unicode issue for Python 2.6 --- platformio/builder/scripts/frameworks/mbed.py | 4 ++-- platformio/builder/tools/platformio.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platformio/builder/scripts/frameworks/mbed.py b/platformio/builder/scripts/frameworks/mbed.py index a0454b07..be0e4da2 100644 --- a/platformio/builder/scripts/frameworks/mbed.py +++ b/platformio/builder/scripts/frameworks/mbed.py @@ -227,9 +227,9 @@ env.Replace( # restore external build flags env.ProcessFlags([ - env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags", None), + env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags"), env.get("BUILD_FLAGS"), - getenv("PLATFORMIO_BUILD_FLAGS", None), + getenv("PLATFORMIO_BUILD_FLAGS"), ]) # Hook for K64F and K22F diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index ec98e587..ef3469cc 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -40,9 +40,9 @@ def BuildProgram(env): ) env.ProcessFlags([ - env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags", None), + env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags"), env.get("BUILD_FLAGS"), - getenv("PLATFORMIO_BUILD_FLAGS", None), + getenv("PLATFORMIO_BUILD_FLAGS"), ]) env.BuildFramework() @@ -67,8 +67,8 @@ def BuildProgram(env): # Handle SRC_BUILD_FLAGS env.ProcessFlags([ - env.get("SRC_BUILD_FLAGS"), - getenv("PLATFORMIO_SRC_BUILD_FLAGS", None), + env.get("SRC_BUILD_FLAGS", None), + getenv("PLATFORMIO_SRC_BUILD_FLAGS"), ]) env.Append( @@ -81,7 +81,7 @@ def BuildProgram(env): env.LookupSources( "$BUILDSRC_DIR", "$PROJECTSRC_DIR", duplicate=False, src_filter=getenv("PLATFORMIO_SRC_FILTER", - env.get("SRC_FILTER", None))), + env.get("SRC_FILTER"))), LIBS=env.get("LIBS", []) + deplibs, LIBPATH=env.get("LIBPATH", []) + ["$BUILD_DIR"] ) @@ -90,7 +90,7 @@ def BuildProgram(env): def ProcessFlags(env, flags): for f in flags: if f: - env.MergeFlags(f) + env.MergeFlags(str(f)) # fix relative CPPPATH for i, p in enumerate(env.get("CPPPATH", [])): @@ -99,7 +99,7 @@ def ProcessFlags(env, flags): # Cancel any previous definition of name, either built in or # provided with a -D option // Issue #191 - undefines = [f for f in env.get("CCFLAGS", []) if f.startswith("-U")] + undefines = [u for u in env.get("CCFLAGS", []) if u.startswith("-U")] if undefines: for undef in undefines: env['CCFLAGS'].remove(undef) From 98ad4adcf327476868be0a18dc7d79d913637e2c Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Nov 2015 23:56:30 +0200 Subject: [PATCH 28/43] Numerate installation methods --- docs/installation.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 02d0227c..0f45b4fe 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -38,7 +38,7 @@ application (Terminal): * Mac OS X / Linux – *Terminal* application * Windows – ``cmd.exe`` application. -Installation options +Installation Methods -------------------- .. warning:: @@ -47,10 +47,10 @@ Installation options **DON'T FORGET** to select ``Add python.exe to Path`` feature on the "Customize" stage. -Please *choose one of* the following installation options: +Please *choose ONE of* the following methods: -Python Package Manager -~~~~~~~~~~~~~~~~~~~~~~ +a) Python Package Manager +~~~~~~~~~~~~~~~~~~~~~~~~~ The latest stable version of PlatformIO may be installed/upgraded via `pip `_ as follows: @@ -74,8 +74,8 @@ a few options here: .. _installation_installer_script: -Installer Script -~~~~~~~~~~~~~~~~ +b) Installer Script +~~~~~~~~~~~~~~~~~~~ Super-Quick (Mac / Linux) ''''''''''''''''''''''''' @@ -114,8 +114,8 @@ On *Windows OS* it may look like: # run it C:\Python27\python.exe get-platformio.py -Full Guide -~~~~~~~~~~ +c) Full Guide +~~~~~~~~~~~~~ 1. Check a ``python`` version (only 2.6-2.7 is supported): @@ -144,8 +144,8 @@ For upgrading ``platformio`` to the latest version: pip install -U platformio -Development Version -~~~~~~~~~~~~~~~~~~~ +d) Development Version +~~~~~~~~~~~~~~~~~~~~~~ Install the latest PlatformIO from the ``develop`` branch: From 5713a6233f7f4122fd9e488e5e4572c88fe57028 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 28 Nov 2015 17:14:42 +0200 Subject: [PATCH 29/43] PlatformIO is an open source ecosystem for IoT development --- README.rst | 25 ++++++++++++++++--------- docs/faq.rst | 4 ++-- docs/index.rst | 29 ++++++++++++++++++----------- platformio/__init__.py | 6 +++--- setup.py | 2 +- 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/README.rst b/README.rst index f7ca6988..3930b519 100644 --- a/README.rst +++ b/README.rst @@ -42,9 +42,20 @@ PlatformIO .. image:: https://raw.githubusercontent.com/platformio/platformio/develop/docs/_static/platformio-logo.png :target: http://platformio.org -`PlatformIO `_ is an open-source cross-platform code -builder and library manager. For embedded development, IDE -and Continuous integration. Arduino and MBED compatible. +`PlatformIO `_ is an open source ecosystem for IoT +development. Cross-platform, IDE and Continuous integration, Arduino and MBED +compatible. Ready for Cloud compiling. + +* **Development Platforms** - Embedded and Desktop development platforms with + pre-built toolchains, debuggers, uploaders and frameworks which work under + popular host OS: Mac, Windows, Linux (+ARM) +* **Embedded Boards** - Rapid Embedded Programming, IDE and Continuous + Integration in a few steps with PlatformIO thanks to built-in project + generator for the most popular embedded boards and IDE +* **Library Manager** - Hundreds Popular Libraries are organized into single + Web 2.0 platform: list by categories, keywords, authors, compatible + platforms and frameworks; learn via examples; be up-to-date with the latest + version *Atmel AVR & SAM, Espressif, Freescale Kinetis, Nordic nRF51, NXP LPC, Silicon Labs EFM32, ST STM32, TI MSP430 & Tiva, Teensy, Arduino, mbed, @@ -66,11 +77,6 @@ libOpenCM3, etc.* * `FAQ `_ * `Release History `_ -You have **no need** to install any *IDE* or compile any toolchains. *PlatformIO* -has pre-built development platforms and pre-configured settings for -the most popular embedded boards. For further details, please -refer to `What is PlatformIO? `_ - Use whenever. *Run everywhere.* ------------------------------- *PlatformIO* is written in pure *Python* and **doesn't depend** on any @@ -88,7 +94,7 @@ settings for most popular `Embedded Boards `_. * Colourful `command-line output `_ * `IDE Integration `_ with *Arduino, Eclipse, Energia, Qt Creator, Sublime Text, Vim, Visual Studio* -* `Continuous Integration `_ +* Cloud compiling and `Continuous Integration `_ with *AppVeyor, Circle CI, Drone, Shippable, Travis CI* * Built-in `Serial Port Monitor `_ and configurable `build -flags/-options `_ @@ -166,6 +172,7 @@ Frameworks: * `SPL `_ * `mbed `_ +For further details, please refer to `What is PlatformIO? `_ Licence ------- diff --git a/docs/faq.rst b/docs/faq.rst index be85c3f4..9a63ee97 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -24,8 +24,8 @@ General What is PlatformIO? ~~~~~~~~~~~~~~~~~~~ -`PlatformIO `_ is an open-source cross-platform code -builder and the missing library manager. +`PlatformIO `_ is an open source ecosystem for IoT +development. PlatformIO is independent from the platform, in which it is running. In fact, the only requirement is Python, which exists pretty much everywhere. What this diff --git a/docs/index.rst b/docs/index.rst index 9f6611fa..60c0c749 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -9,15 +9,26 @@ See the License for the specific language governing permissions and limitations under the License. -PlatformIO is an open-source cross-platform code builder and the missing library manager -======================================================================================== +PlatformIO is an open source ecosystem for IoT development +========================================================== -**Ready for embedded development, IDE and Continuous integration, Arduino and -MBED compatible** +**Cross-platform, IDE and Continuous integration, Arduino and MBED +compatible. Ready for Cloud compiling.** + +* **Development Platforms** - Embedded and Desktop development platforms with + pre-built toolchains, debuggers, uploaders and frameworks which work under + popular host OS: Mac, Windows, Linux (+ARM) +* **Embedded Boards** - Rapid Embedded Programming, IDE and Continuous + Integration in a few steps with PlatformIO thanks to built-in project + generator for the most popular embedded boards and IDE +* **Library Manager** - Hundreds Popular Libraries are organized into single + Web 2.0 platform: list by categories, keywords, authors, compatible + platforms and frameworks; learn via examples; be up-to-date with the latest + version *Atmel AVR & SAM, Espressif, Freescale Kinetis, Nordic nRF51, NXP LPC, Silicon Labs EFM32, ST STM32, TI MSP430 & Tiva, Teensy, Arduino, mbed, -libOpenCM3, etc.* +libOpenCM3, etc.** * `Website `_ * `Web 2.0 Library Search `_ | @@ -31,18 +42,13 @@ libOpenCM3, etc.* `Facebook `_ | `Reddit `_ -You have **no need** to install any *IDE* or compile any tool chains. *PlatformIO* -has pre-built different development platforms and pre-configured settings for -the most popular embedded boards. For further details, please -refer to :ref:`faq_what_is_platformio` - Embedded Development. *Easier Than Ever.* ----------------------------------------- * Colourful command-line output * :ref:`IDE Integration ` with *Arduino, Eclipse, Energia, Qt Creator, Sublime Text, Vim, Visual Studio* -* :ref:`ci` with *AppVeyor, Circle CI, Drone, Shippable, Travis CI* +* Cloud compiling and :ref:`ci` with *AppVeyor, Circle CI, Drone, Shippable, Travis CI* * Built-in :ref:`Serial Port Monitor ` and configurable build :ref:`-flags/-options ` * Pre-built tool chains, :ref:`frameworks` for the @@ -65,6 +71,7 @@ The Missing Library Manager. *It's here!* * Automatic library updating * It runs on Windows, Mac OS X, and Linux (+ARM). +For further details, please refer to :ref:`faq_what_is_platformio` Contents -------- diff --git a/platformio/__init__.py b/platformio/__init__.py index 4a829ad3..9fd589ec 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -17,9 +17,9 @@ __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" __description__ = ( - "An open-source cross-platform code builder and the missing library " - "manager (Ready for embedded development, IDE and Continuous integration, " - "Arduino and MBED compatible)" + "An open source ecosystem for IoT development. Cross-platform, IDE and " + "Continuous integration, Arduino and MBED compatible. " + "Ready for Cloud compiling" ) __url__ = "http://platformio.org" diff --git a/setup.py b/setup.py index 8649b2e6..9d2d1452 100644 --- a/setup.py +++ b/setup.py @@ -72,7 +72,7 @@ setup( "Topic :: Software Development :: Compilers" ], keywords=( - "builder library manager embedded development ide continuous " + "iot builder library manager embedded development ide continuous " "integration atmel avr sam espressif esp freescale kinetis nordic " "nrf51 nxp lpc silicon labs efm32 st stm32 ti msp430 tiva teensy " "arduino mbed libopencm3" From 5264d85a787cc93aca0f2d9fa5b73fbc5a614e2d Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 29 Nov 2015 17:56:26 +0200 Subject: [PATCH 30/43] Fix broken link to extra css --- docs/_templates/footer.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_templates/footer.html b/docs/_templates/footer.html index 0e85bc9c..b10e6ac0 100644 --- a/docs/_templates/footer.html +++ b/docs/_templates/footer.html @@ -1,7 +1,7 @@ {% extends "!footer.html" %} {% block extrafooter %} - + {{ super() }} -{% endblock %} \ No newline at end of file +{% endblock %} From 786b9776031cb6d5648496bfc0d9008fd85ed189 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 29 Nov 2015 19:05:02 +0200 Subject: [PATCH 31/43] Print "unexpected block" for non-PlatformIO exceptions --- platformio/__main__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platformio/__main__.py b/platformio/__main__.py index 299ee5eb..e5e35aee 100644 --- a/platformio/__main__.py +++ b/platformio/__main__.py @@ -103,8 +103,7 @@ def main(): error_str += str(e) else: error_str += format_exc() - - error_str += """ + error_str += """ ============================================================ An unexpected error occurred. Further steps: From bcb4e1abfdbe50ec4a16e124a4ea979f0c3a76e9 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 29 Nov 2015 23:23:31 +0200 Subject: [PATCH 32/43] Add new article by Mistan --- docs/articles.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/articles.rst b/docs/articles.rst index 98c4666a..85172f83 100644 --- a/docs/articles.rst +++ b/docs/articles.rst @@ -27,6 +27,7 @@ Here are recent articles about PlatformIO: * Nov 09, 2015 - **ÁLvaro García Gómez** - `Programar con Arduino "The good way" (Programming with Arduino "The good way", Spanish) `_ * Nov 06, 2015 - **nocd5** - `PlatformIOでmbedをオフラインビルドしSTM32 Nucleoボードでmrubyを使う (Use mruby in the offline build for STM32 Nucleo board with mbed and PlatformIO, Japanese) `_ * Oct 18, 2015 - **Nico Coetzee** - `First Arduino I2C Experience with PlatformIO `_ +* Oct 01, 2015 - **Mistan** - `Compile and Upload Arduino Sketch with PlatformIO for Raspberry Pi Running Arch Linux `_ * Sep 01, 2015 - **Thomas P. Weldon, Ph.D.** - `Improvised MBED FRDM-K64F Eclipse/PlatformIO Setup and Software Installation `_ * Aug 08, 2015 - **Josh Glendenning** - `Armstrap Eagle and PlatformIO `_ * Aug 01, 2015 - **Russell Davis** - `PlatformIO on the Raspberry Pi `_ From cd11171e3302c13950f683499307218d82182667 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 30 Nov 2015 01:11:57 +0200 Subject: [PATCH 33/43] Lint code with the latest PyLint --- .pylintrc | 270 +----------------- platformio/app.py | 1 - platformio/builder/main.py | 4 +- .../builder/scripts/frameworks/libopencm3.py | 2 + platformio/builder/tools/piomisc.py | 2 + platformio/builder/tools/pioupload.py | 4 +- platformio/builder/tools/platformio.py | 2 + platformio/unpacker.py | 2 +- platformio/util.py | 2 + 9 files changed, 21 insertions(+), 268 deletions(-) diff --git a/.pylintrc b/.pylintrc index 5e3b1e69..bdf25c27 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,29 +1,9 @@ -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Profiled execution. -profile=no - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - - [MESSAGES CONTROL] +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time. See also the "--disable" option for examples. @@ -38,244 +18,6 @@ load-plugins= # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" -disable=C0103,C0111,E0611,F0401,I0011,R0801,R0903,R0922 +# disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Tells whether to display a full report or only the messages -reports=yes - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Add a comment according to your evaluation note. This is used by the global -# evaluation report (RP0004). -comment=no - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= -msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} - - -[BASIC] - -# Required attributes for module, separated by a comma -required-attributes= - -# List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter,apply,input - -# Regular expression which should only match correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression which should only match correct module level names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Regular expression which should only match correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression which should only match correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct instance attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct attribute names in class -# bodies -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression which should only match correct list comprehension / -# generator expression variable names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=__.*__ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - - -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=80 - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - -# List of optional constructs for which whitespace checking is disabled -no-space-check=trailing-comma,dict-separator - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of classes names for which member attributes should not be checked -# (useful for classes with attributes dynamically set). -ignored-classes=SQLObject - -# When zope mode is activated, add a predefined set of Zope acquired attributes -# to generated-members. -zope=no - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E0201 when accessed. Python regular -# expressions are accepted. -generated-members=REQUEST,acl_users,aq_parent - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the beginning of the name of dummy variables -# (i.e. not used). -dummy-variables-rgx=_$|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - - -[CLASSES] - -# List of interface methods to ignore, separated by a comma. This is used for -# instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception +disable=locally-disabled,missing-docstring,invalid-name,too-few-public-methods,redefined-variable-type,import-error,similarities,unsupported-membership-test,unsubscriptable-object,ungrouped-imports diff --git a/platformio/app.py b/platformio/app.py index 9a59e130..8b2d9417 100644 --- a/platformio/app.py +++ b/platformio/app.py @@ -24,7 +24,6 @@ from platformio import __version__ from platformio.exception import InvalidSettingName, InvalidSettingValue from platformio.util import get_home_dir, is_ci - DEFAULT_SETTINGS = { "check_platformio_interval": { "description": "Check for the new PlatformIO interval (days)", diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 7d61b529..b3c1b34a 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=wrong-import-position,wrong-import-order,unused-import + try: from platformio import util except ImportError: @@ -29,7 +31,7 @@ except ImportError: sys.path.insert(0, _p) try: from platformio import util - import lockfile # NOQA pylint: disable=unused-import + import lockfile # NOQA break except ImportError: pass diff --git a/platformio/builder/scripts/frameworks/libopencm3.py b/platformio/builder/scripts/frameworks/libopencm3.py index 8255c442..c523b0d8 100644 --- a/platformio/builder/scripts/frameworks/libopencm3.py +++ b/platformio/builder/scripts/frameworks/libopencm3.py @@ -23,6 +23,8 @@ including ST STM32, Ti Tiva and Stellaris, NXP LPC 11xx, 13xx, 15xx, http://www.libopencm3.org/wiki/Main_Page """ +from __future__ import absolute_import + import re from os import listdir, sep, walk from os.path import isfile, join, normpath diff --git a/platformio/builder/tools/piomisc.py b/platformio/builder/tools/piomisc.py index 95e78e24..94743cec 100644 --- a/platformio/builder/tools/piomisc.py +++ b/platformio/builder/tools/piomisc.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import absolute_import + import atexit import re from glob import glob diff --git a/platformio/builder/tools/pioupload.py b/platformio/builder/tools/pioupload.py index 8bb33b9f..8fdeb40b 100644 --- a/platformio/builder/tools/pioupload.py +++ b/platformio/builder/tools/pioupload.py @@ -12,7 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from os.path import join, isfile +from __future__ import absolute_import + +from os.path import isfile, join from shutil import copyfile from time import sleep diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index ef3469cc..c9e82a22 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import absolute_import + import re from glob import glob from os import getenv, listdir, sep, walk diff --git a/platformio/unpacker.py b/platformio/unpacker.py index 80d66b9e..3cd15903 100644 --- a/platformio/unpacker.py +++ b/platformio/unpacker.py @@ -64,7 +64,7 @@ class ZIPArchive(ArchiveBase): def preserve_mtime(item, dest_dir): util.change_filemtime( join(dest_dir, item.filename), - mktime(list(item.date_time) + [0]*3) + mktime(list(item.date_time) + [0] * 3) ) def get_items(self): diff --git a/platformio/util.py b/platformio/util.py index 6f2001b5..4eefbecb 100644 --- a/platformio/util.py +++ b/platformio/util.py @@ -27,6 +27,7 @@ from threading import Thread from platformio import __apiurl__, __version__, exception +# pylint: disable=wrong-import-order try: from configparser import ConfigParser except ImportError: @@ -67,6 +68,7 @@ class AsyncPipe(Thread): class cd(object): + def __init__(self, new_path): self.new_path = new_path self.prev_path = os.getcwd() From 8aedc50f303a57d1266d153d1f0f3541078ded7e Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 30 Nov 2015 18:05:32 +0200 Subject: [PATCH 34/43] Rephrase slogan --- README.rst | 4 ++-- docs/index.rst | 4 ++-- platformio/__init__.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 3930b519..caec3e08 100644 --- a/README.rst +++ b/README.rst @@ -43,8 +43,8 @@ PlatformIO :target: http://platformio.org `PlatformIO `_ is an open source ecosystem for IoT -development. Cross-platform, IDE and Continuous integration, Arduino and MBED -compatible. Ready for Cloud compiling. +development. Cross-platform code builder. Continuous and IDE integration. +Arduino and MBED compatible. Ready for Cloud compiling. * **Development Platforms** - Embedded and Desktop development platforms with pre-built toolchains, debuggers, uploaders and frameworks which work under diff --git a/docs/index.rst b/docs/index.rst index 60c0c749..c9ae12d9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,8 +12,8 @@ PlatformIO is an open source ecosystem for IoT development ========================================================== -**Cross-platform, IDE and Continuous integration, Arduino and MBED -compatible. Ready for Cloud compiling.** +**Cross-platform code builder. Continuous and IDE integration. +Arduino and MBED compatible. Ready for Cloud compiling.** * **Development Platforms** - Embedded and Desktop development platforms with pre-built toolchains, debuggers, uploaders and frameworks which work under diff --git a/platformio/__init__.py b/platformio/__init__.py index 9fd589ec..06925c76 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -17,9 +17,9 @@ __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" __description__ = ( - "An open source ecosystem for IoT development. Cross-platform, IDE and " - "Continuous integration, Arduino and MBED compatible. " - "Ready for Cloud compiling" + "An open source ecosystem for IoT development. " + "Cross-platform code builder. Continuous and IDE integration. " + "Arduino and MBED compatible. Ready for Cloud compiling." ) __url__ = "http://platformio.org" From 20b214f3a49a287b562407d3d263f2830511ff68 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 30 Nov 2015 18:29:30 +0200 Subject: [PATCH 35/43] Rephrase slogan (add library manager) --- README.rst | 4 ++-- docs/index.rst | 4 ++-- platformio/__init__.py | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index caec3e08..b637490f 100644 --- a/README.rst +++ b/README.rst @@ -43,8 +43,8 @@ PlatformIO :target: http://platformio.org `PlatformIO `_ is an open source ecosystem for IoT -development. Cross-platform code builder. Continuous and IDE integration. -Arduino and MBED compatible. Ready for Cloud compiling. +development. Cross-platform code builder and library manager. Continuous and +IDE integration. Arduino and MBED compatible. Ready for Cloud compiling. * **Development Platforms** - Embedded and Desktop development platforms with pre-built toolchains, debuggers, uploaders and frameworks which work under diff --git a/docs/index.rst b/docs/index.rst index c9ae12d9..d393c262 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,8 +12,8 @@ PlatformIO is an open source ecosystem for IoT development ========================================================== -**Cross-platform code builder. Continuous and IDE integration. -Arduino and MBED compatible. Ready for Cloud compiling.** +**Cross-platform code builder and library manager. Continuous and IDE +integration. Arduino and MBED compatible. Ready for Cloud compiling.** * **Development Platforms** - Embedded and Desktop development platforms with pre-built toolchains, debuggers, uploaders and frameworks which work under diff --git a/platformio/__init__.py b/platformio/__init__.py index 06925c76..d2792d6a 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -18,7 +18,8 @@ __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" __description__ = ( "An open source ecosystem for IoT development. " - "Cross-platform code builder. Continuous and IDE integration. " + "Cross-platform code builder and library manager. " + "Continuous and IDE integration. " "Arduino and MBED compatible. Ready for Cloud compiling." ) __url__ = "http://platformio.org" From 946f21879c241b91d8467db591a11eee435b1965 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 30 Nov 2015 21:46:21 +0200 Subject: [PATCH 36/43] Add new article by Keith Hughes --- docs/articles.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/articles.rst b/docs/articles.rst index 85172f83..8e2262a5 100644 --- a/docs/articles.rst +++ b/docs/articles.rst @@ -23,6 +23,7 @@ Here are recent articles about PlatformIO: 2015 ^^^^ +* Nov 29, 2015 - **Keith Hughes** - `Using PlatformIO for Embedded Projects `_ * Nov 22, 2015 - **Michał Seroczyński** - `Using PlatformIO to get started with Arduino in CLion IDE `_ * Nov 09, 2015 - **ÁLvaro García Gómez** - `Programar con Arduino "The good way" (Programming with Arduino "The good way", Spanish) `_ * Nov 06, 2015 - **nocd5** - `PlatformIOでmbedをオフラインビルドしSTM32 Nucleoボードでmrubyを使う (Use mruby in the offline build for STM32 Nucleo board with mbed and PlatformIO, Japanese) `_ From db42863f54930b132d0507671976bfc33d41a51e Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Tue, 1 Dec 2015 11:21:23 +0200 Subject: [PATCH 37/43] Update build flags for espressif platform. --- platformio/builder/scripts/espressif.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platformio/builder/scripts/espressif.py b/platformio/builder/scripts/espressif.py index 8515cabd..49feea70 100644 --- a/platformio/builder/scripts/espressif.py +++ b/platformio/builder/scripts/espressif.py @@ -56,6 +56,8 @@ env.Replace( "-mtext-section-literals", "-falign-functions=4", "-U__STRICT_ANSI__", + "-ffunction-sections", + "-fdata-sections", "-MMD" # output dependancy info ], @@ -76,9 +78,7 @@ env.Replace( "-Wl,--no-check-sections", "-u", "call_user_start", "-Wl,-static", - "-Wl,--gc-sections", - "-Wl,-wrap,system_restart_local", - "-Wl,-wrap,register_chipv6_phy" + "-Wl,--gc-sections" ], SIZEPRINTCMD='"$SIZETOOL" -B -d $SOURCES', From 9f4b73d82178e7c0c8a62b5cf5160a4254ad3606 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Dec 2015 12:04:41 +0200 Subject: [PATCH 38/43] Update Arduino core for Espressif platform to 2.0.0 // Resolve #345 --- HISTORY.rst | 4 +++- platformio/__init__.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 46545814..681efde6 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,12 +4,14 @@ Release History PlatformIO 2.0 -------------- -2.3.6 (2015-??-??) +2.4.0 (2015-??-??) ~~~~~~~~~~~~~~~~~~ * Added support for the new boards: Atmel ATSAMR21-XPRO, Atmel SAML21-XPRO-B, Atmel SAMD21-XPRO, ST 32F469IDISCOVERY, ST 32L476GDISCOVERY, ST Nucleo F031K6, ST Nucleo F042K6, ST Nucleo F303K8 and ST Nucleo L476RG +* Updated Arduino core for Espressif platform to 2.0.0 + (`issue #345 `_) * Added to FAQ explanation of `Can not compile a library that compiles without issue with Arduino IDE `_ (`issue #331 `_) diff --git a/platformio/__init__.py b/platformio/__init__.py index d2792d6a..ec5077f2 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 3, "6.dev3") +VERSION = (2, 4, "b1") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From d806097b6006cb66f63aafa6b2fbac583a016535 Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Tue, 1 Dec 2015 13:47:56 +0200 Subject: [PATCH 39/43] Fix PlatformIO version. --- platformio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index ec5077f2..f640b554 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 4, "b1") +VERSION = (2, 4, "0.b1") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From a7a82b1c0a69d25ec4bb884b4e61d548d79c7ac7 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Dec 2015 16:28:47 +0200 Subject: [PATCH 40/43] Fix PlatformIO version --- platformio/__init__.py | 2 +- platformio/builder/main.py | 6 ++++++ platformio/builder/tools/platformio.py | 7 ------- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index f640b554..4c2ddbb9 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 4, "0.b1") +VERSION = (2, 4, "0b1") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/builder/main.py b/platformio/builder/main.py index b3c1b34a..5b45692e 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -114,6 +114,12 @@ DefaultEnvironment( env = DefaultEnvironment() +# Append PlatformIO version +env.Append( + CPPDEFINES=["PLATFORMIO={0:02d}{1:02d}{2:02d}".format( + *util.pioversion_to_intstr())] +) + if "BOARD" in env: try: env.Replace(BOARD_OPTIONS=util.get_boards(env.subst("$BOARD"))) diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index c9e82a22..ec9d4049 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -23,8 +23,6 @@ from SCons.Script import (COMMAND_LINE_TARGETS, DefaultEnvironment, Exit, SConscript) from SCons.Util import case_sensitive_suffixes -from platformio.util import pioversion_to_intstr - SRC_BUILD_EXT = ["c", "cpp", "S", "spp", "SPP", "sx", "s", "asm", "ASM"] SRC_HEADER_EXT = ["h", "hpp"] SRC_DEFAULT_FILTER = " ".join([ @@ -73,11 +71,6 @@ def BuildProgram(env): getenv("PLATFORMIO_SRC_BUILD_FLAGS"), ]) - env.Append( - CPPDEFINES=["PLATFORMIO={0:02d}{1:02d}{2:02d}".format( - *pioversion_to_intstr())] - ) - return env.Program( join("$BUILD_DIR", env.subst("$PROGNAME")), env.LookupSources( From 306f2f980dfa23fd65778caae390f9ab4ec7d9ee Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Dec 2015 17:41:10 +0200 Subject: [PATCH 41/43] Drop Click to <6 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9d2d1452..6696f001 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ from platformio import (__author__, __description__, __email__, __license__, install_requires = [ "bottle", - "click>=3.2", + "click>=3.2,<6", "lockfile>=0.9.1", "pyserial", "requests>=2.4.0" From 14fc21c37926659d6824d4eddab32e63d5313529 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Dec 2015 17:43:16 +0200 Subject: [PATCH 42/43] Drop Click to (5.1) <6 // Issue #346 --- .../builder/scripts/frameworks/platformio.py | 61 +++++++++++++++++++ platformio/builder/tools/platformio.py | 33 +++++----- requirements.txt | 2 +- 3 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 platformio/builder/scripts/frameworks/platformio.py diff --git a/platformio/builder/scripts/frameworks/platformio.py b/platformio/builder/scripts/frameworks/platformio.py new file mode 100644 index 00000000..927001e7 --- /dev/null +++ b/platformio/builder/scripts/frameworks/platformio.py @@ -0,0 +1,61 @@ +# Copyright 2014-2015 Ivan Kravets +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +PlatformIO + +PlatformIO Framework is an open source light-weight framework with +high-level API for cross-platform embedded programming. It lies above popular +middleware (HAL, SDK) and leverages all its benefits. This approach allowed to +incorporate different development platforms ranging from 8-bits AVR to powerful +32-bit ARM into the one embedded ecosystem. + +http://platformio.org +""" + +from os.path import join + +from SCons.Script import DefaultEnvironment + +env = DefaultEnvironment() + +env.Replace( + PLATFORMFW_DIR=join("$PIOPACKAGES_DIR", "framework-platformio") +) + +env.VariantDirWrap( + join("$BUILD_DIR", "FrameworkPlatformIO"), + join("$PLATFORMFW_DIR", "src", "api") +) + +env.Append( + CPPPATH=[ + join("$BUILD_DIR", "FrameworkCMSIS"), + join("$BUILD_DIR", "FrameworkCMSISVariant") + ] +) + +envsafe = env.Clone() + +# +# Target: Build Core Library +# + +libs = [] +libs.append(envsafe.BuildLibrary( + join("$BUILD_DIR", "FrameworkCMSISVariant"), + join("$PLATFORMFW_DIR", "variants", "${BOARD_OPTIONS['build']['variant']}") +)) + +env.Append(LIBS=libs) diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index ec9d4049..790ea4ad 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -44,7 +44,9 @@ def BuildProgram(env): env.get("BUILD_FLAGS"), getenv("PLATFORMIO_BUILD_FLAGS"), ]) - env.BuildFramework() + + env.BuildFrameworks([ + f.lower().strip() for f in env.get("FRAMEWORK", "").split(",")]) # build dependent libs deplibs = env.BuildDependentLibraries("$PROJECTSRC_DIR") @@ -164,23 +166,24 @@ def LookupSources(env, variant_dir, src_dir, duplicate=True, src_filter=None): return sources -def BuildFramework(env): - if "FRAMEWORK" not in env or "uploadlazy" in COMMAND_LINE_TARGETS: +def BuildFrameworks(env, frameworks): + if not frameworks or "uploadlazy" in COMMAND_LINE_TARGETS: return - if env['FRAMEWORK'].lower() in ("arduino", "energia"): - env.ConvertInoToCpp() + board_frameworks = env.get("BOARD_OPTIONS", {}).get("frameworks") + if frameworks == ["platformio"]: + if board_frameworks: + frameworks.insert(0, board_frameworks[0]) - for f in env['FRAMEWORK'].split(","): - framework = f.strip().lower() - if framework in env.get("BOARD_OPTIONS", {}).get("frameworks"): - SConscript( - env.subst(join("$PIOBUILDER_DIR", "scripts", "frameworks", - "%s.py" % framework)) - ) + for f in frameworks: + if f in ("arduino", "energia"): + env.ConvertInoToCpp() + + if f in board_frameworks: + SConscript(env.subst( + join("$PIOBUILDER_DIR", "scripts", "frameworks", "%s.py" % f))) else: - Exit("Error: This board doesn't support %s framework!" % - framework) + Exit("Error: This board doesn't support %s framework!" % f) def BuildLibrary(env, variant_dir, src_dir, src_filter=None): @@ -344,7 +347,7 @@ def generate(env): env.AddMethod(IsFileWithExt) env.AddMethod(VariantDirWrap) env.AddMethod(LookupSources) - env.AddMethod(BuildFramework) + env.AddMethod(BuildFrameworks) env.AddMethod(BuildLibrary) env.AddMethod(BuildDependentLibraries) return env diff --git a/requirements.txt b/requirements.txt index ef8dd85c..2294e807 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ bottle==0.12.9 -click==6.2 +click==5.1 colorama==0.3.3 lockfile==0.12.2 pyserial==2.7 From 50ba2359176d941f634cb6575469676db8dc1a81 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Dec 2015 17:50:35 +0200 Subject: [PATCH 43/43] Version bump to 2.4.0 (issues #271, #334, #335, #336, #339, #340, #343, #345, #346) --- HISTORY.rst | 2 +- platformio/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 681efde6..652cbffd 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,7 +4,7 @@ Release History PlatformIO 2.0 -------------- -2.4.0 (2015-??-??) +2.4.0 (2015-12-01) ~~~~~~~~~~~~~~~~~~ * Added support for the new boards: Atmel ATSAMR21-XPRO, Atmel SAML21-XPRO-B, diff --git a/platformio/__init__.py b/platformio/__init__.py index 4c2ddbb9..0ef276d8 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -VERSION = (2, 4, "0b1") +VERSION = (2, 4, 0) __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio"