Migrating from 5.x to 6.0

Guidance on how to upgrade from PlatformIO Core (CLI) v5.x to v6.x with emphasis on major changes, what is new, and what has been removed.

Note

PlatformIO Core 6.0 is FULLY BACKWARD COMPATIBLE* with PlatformIO 5.0 projects. It means, there are no breaking changes or required migration steps. Project compatibility between major PlatformIO Core releases is our main task and part of PlatformIO’s decentralized architecture.

We highly recommend using the latest PlatformIO Core. See pio upgrade command.

* see a note regarding Unit Testing and the grouped test suites in the migration steps below.

Please read PlatformIO 6.0 Release Notes before.

Migration Steps

PlatformIO Core 6.0 received a lot of new features and updates to improve the lives of everyday engineers. To benefit from its improvements, we recommend taking into account the following steps:

  1. Replace deprecated pio lib, pio platform, and pio update commands with the unified Package Management CLI

  2. Avoid using global libraries previously installed using the pio lib --global command. Ensure that the globallib_dir folder is empty. Please use a declarative approach for the safety-critical embedded development and declare project dependencies using the lib_deps option

  3. Ensure that project dependencies are declared using the platform, platform_packages, and lib_deps options in “platformio.ini” (Project Configuration File):

    1. meet the updated Package Specifications

    2. use recommended Semantic Version Requirements (check PlatformIO Registry for the available package versions)

    Bad practice (not recommended)

    [env:myenv]
    ; Depend on ANY/Latest version of the development platform
    ; allowing breaking changes
    platform = espressif32
    
    lib_deps =
      ; Omit library package owner (<owner>/<name>) and depend on the library by name.
      ; Lead to the conflicts when there are multiple libraries with the same name
      OneWire
    
      ; Depend on ANY/Latest version of the development platform
      ; allowing breaking changes
      me-no-dev/AsyncTCP
    
      ; Depend on the development branch of the Git repository,
      ; allow breaking changes, and untested commits
      https://github.com/username/HelloWorld.git
    

    Good practice (highly recommended)

    [env:myenv]
    ; Depend on the latest compatible version of development platform
    ; allowing new functionality (backward-compatible), and bug fixes.
    ; No breaking changes
    ; FYI: ^4 == ^4.0.0 == (>=4.0.0, <5.0.0)
    platform = espressif32 @ ^4
    
    lib_deps =
      ; Depend on the latest 6.x stable version of ArduinoJson.
      ; The minimum required version is 6.19.4.
      ; New functionality (backward-compatible) and bug-fixed are allowed
      bblanchon/ArduinoJson @ ^6.19.4
    
      ; Depend on the exact 1.1.1 version
      ; No new functionality (backward-compatible) or bug fixes.
      ; Recommended for safety-critical projects
      me-no-dev/AsyncTCP @ 1.1.1
    
      ; Depend on the particular tag (v2.13) of a Git repository
      https://github.com/username/HelloWorld.git#v2.13
    
  4. If you use a custom testing transport via the “test_transport” option in “platformio.ini” (Project Configuration File), please align your codebase with Custom unity_config.h. The “test_transport” option has been removed.

  5. There is a known bug in PlatformIO Core 5.0 when Unit Testing didn’t handle correctly grouped test suites. Please ensure that a test suite folder that contains test source files is prefixed with test_. See Test Hierarchy for details.

What is new

In this section, we are going to highlight the most important changes and features introduced in PlatformIO Core 6.0. Please visit PlatformIO 6.0 Release Notes for more detailed information.

Package Management

PlatformIO Core 6.0 brings a powerful solution to manage different Package Types using the unified Package Management CLI:

There are no more global packages that could lead to potential issues. The new package management solution allows you to use a modern declarative approach for safety-critical embedded development. Using the Semantic Version Requirements guarantees the full project reproducibility on any supported host machine for decades.

The new Package Management CLI operates in accordance with the active (working) project. The pio pkg install command will install all required project dependencies. The pio pkg list commmand allows listing not only dependent libraries but also development platforms and their packages.

The notable addition is the pio pkg outdated command. It allows you to check for outdated project packages and list version information for all dependencies. There are three color legends to help you easily identify which updates are backward-incompatible.

Run package command

PlatformIO Registry contains a rich set of popular toolchains and other useful tools. The pio pkg exec command allows you to run an arbitrary command from the specified package. If you specify package requirements using the pio pkg exec --package option, PlatformIO will ensure that the package is installed before running any command.

Practical use cases include running debugging servers, uploaders or special tools from a toolchain. A few examples of how to leverage the new pio pkg exec command:

# Ensure JLink tool is installed and start GDB server
> pio pkg exec --package=tool-jlink -- JLinkGDBServer -singlerun -if JTAG -select USB -jtagconf -1,-1 -device EFR32BG22CxxxF512 -port 2331

# Run Espressif SoC serial bootloader utility and erase a flash from the target device
> pio pkg exec -- esptool.py erase_flash

# Disassembly AVR ELF file
> pio pkg exec -- avr-objdump -d -m avr2 .pio/build/uno/firmware.elf

Unit Testing

It’s been six years since we added support for unit testing, and Unity was the only available testing framework. We didn’t expect that the PlatformIO Unit Testing solution will gain broad popularity, especially when it comes to using it on native (host) machines.

So, the time has come to refresh our view on PlatformIO Unit Testing with taking into account your feedback and feature requests.

Test-driven development

The PlatformIO Core 6.0 introduces an absolutely a new workflow for test-driven development in the embedded systems industry. Thanks to the rich set of supported Testing Frameworks and the ability to organize tests in groups using the Test Hierarchy, you can create hybrid projects and benefit from multiple testing frameworks depending on the project requirements simultaneously. See a simple example of the hybrid configuration:

[env:native]
platform = native
test_framework = googletest
test_filter =
  common/*
  native/*

[env:embedded]
platform = ...
framework = ...
test_framework = unity
test_filter =
  common/*
  embedded/*

Use more advanced C++ testing frameworks with Mocking support such as GoogleTest in pair with the Native development platform to run desktop tests on the host machine and a lightweight framework, such as Unity, for running tests on the target embedded device with constrained resources.

Hardware-less development

It’s hard to imagine today a next-gen project development workflow that does not benefit from Continuous Integration systems. PlatformIO already provides multiple solutions to improve code quality including Static Code Analysis. In addition to the testing frameworks that allow you to mock objects and simulate the behavior of real objects, the PlatformIO Core 6.0 adds support for the Simulators.

The combination of simulation tools and testing frameworks allow you to simulate hardware systems and run unit tests in virtual environments. Simulators can significantly accelerate project development, especially when used in pair with Continuous Integration.

Integration of any simulator tool to the PlatformIO Unit Testing is very simple and does not require any extra software or code writing. Please take a look at the example below how easy it is to integrate the Renode simulation framework:

[env:hifive1-revb]
platform = sifive
framework = zephyr
board = hifive1-revb

platform_packages =
    platformio/tool-renode
test_testing_command =
    ${platformio.packages_dir}/tool-renode/renode
    --disable-xwt
    -e include @scripts/single-node/sifive_fe310.resc
    -e showAnalyzer uart1
    -e sysbus LoadELF @${platformio.build_dir}/${this.__env__}/firmware.elf
    -e start

What is changed or removed

Dropped automatic updates

Thanks to your feedback, we finally removed automatic updates of global libraries and development platforms. Please use pio pkg outdated to check for outdated project packages and list version information for all dependencies.

The pio pkg update is intended to update the project dependencies, custom packages from the PlatformIO Registry, or external sources.

Command Line Interface

The following commands have been changed in v6.0.

Command

Description

pio pkg

NEW Unified package management solution

pio project init

NEW pio project init --no-install-dependencies option

pio project metadata

NEW pio project metadata --json-output-path option

pio run

NEW pio run --program-arg option

pio test

NEW pio test --program-arg, pio test --json-output-path, pio test --junit-output-path, and pio test --list-tests options

pio project data

RENAMED to the pio project metadata

pio lib

DEPRECATED in favor of Package Management CLI

pio platform

DEPRECATED in favor of Package Management CLI

pio update

DEPRECATED in favor of Package Management CLI