neulab/tldr huggingface dataset:
extra_scripts = extra_script.py upload_protocol = custom ; each flag in a new line upload_flags = -f scripts/interface/stlink.cfg -f scripts/target/stm32f4x.cfg
platform = env.PioPlatform()
env.Prepend( UPLOADERFLAGS=["-s", platform.get_package_dir("tool-openocd") or ""] ) env.Append( UPLOADERFLAGS=["-c", "program {{$SOURCE}} verify reset; shutdown"] ) env.Replace( UPLOADER="openocd", UPLOADCMD="$UPLOADER $UPLOADERFLAGS" )
Upload to Cloud (OTA) See project example https://github.com/platformio/bintray-secure-ota
Custom firmware/program name Sometimes is useful to have a different firmware/program name in projectconf_pio_build_dir.
[env:env_custom_prog_name] platform = espressif8266 board = nodemcuv2 framework = arduino build_flags = -D VERSION=13 extra_scripts = pre:extra_script.py
my_flags = env.ParseFlags(env['BUILD_FLAGS']) defines = {k: v for (k, v) in my_flags.get("CPPDEFINES")} # print(defines)
env.Replace(PROGNAME="firmware_%s" % defines.get("VERSION"))
Override package files PlatformIO Package Manager automatically installs pre-built packages (frameworks, toolchains, libraries) required by development platforms and build process. Sometimes you need to override original files with own versions: configure custom GPIO, do changes to built-in LD scripts, or some patching to installed library dependency.
The simplest way is using Diff and Patch technique. How does it work?
1. Modify original source files
2. Generate patches
3. Apply patches via PlatformIO extra script before build process.
We need to patch the original standard/pins_arduino.h variant from framework_arduino framework and add extra macro #define PIN_A8   (99). Let's duplicate standard/pins_arduino.h and apply changes. Generate a patch file and place it into patches folder located in the root of a project:
diff ~/.platformio/packages/framework-arduinoavr/variants/standard/pins_arduino.h /tmp/pins_arduino_modified.h > /path/to/platformio/project/patches/1-framework-arduinoavr-add-pin-a8.patch
The result of 1-framework-arduinoavr-add-pin-a8.patch:
63a64 > #define PIN_A8   (99) 112c113 < // 14-21 PA0-PA7 works --- > // 14-21 PA0-PA7 works
Using extra scripting we can apply patching before a build process. The final result of projectconf and "PRE" extra script named apply_patches.py:
[env:uno] platform = atmelavr board = uno framework = arduino extra_scripts = pre:apply_patches.py
apply_patches.py:
from os.path import join, isfile
FRAMEWORK_DIR = env.PioPlatform().get_package_dir("framework-arduinoavr") patchflag_path = join(FRAMEWORK_DIR, ".patching-done")
# patch file only if we didn't do it before if not isfile(join(FRAMEWORK_DIR, ".patching-done")): original_file = join(FRAMEWORK_DIR, "variants", "standard", "pins_arduino.h") patched_file = join("patches", "1-framework-arduinoavr-add-pin-a8.patch")
assert isfile(original_file) and isfile(patched_file)
env.Execute("patch %s %s" % (original_file, patched_file)) # env.Execute("touch " + patchflag_path)
def _touch(path): with open(path, "w") as fp: fp.write("")
env.Execute(lambda *args, **kwargs: _touch(patchflag_path))
Please note that this example will work on a system where a patch tool is available. For Windows OS, you can use patch and diff tools provided by Git client utility (located inside installation directory).
If you need to make it more independent to the operating system, please replace the patch with a multi-platform python-patch script.
Override Board Configuration PlatformIO allows one to override some basic options (integer or string values) using projectconf_board_more_options in projectconf.  Sometimes you need to do complex changes to default board manifest and extra PRE scripting work well here. See example below how to override default hardware VID/PIDs.
WARNING: Due to a technical limitation these board changes will not work for cmd_device_monitor command.
[env:uno] platform = atmelavr board = uno framework = arduino extra_scripts = pre:custon_hwids.py
custon_hwids.py:
board_config = env.BoardConfig() # should be array of VID:PID pairs board_config.update("build.hwids", [ ["0x2341", "0x0243"],  # 1st pair ["0x2A03", "0x0043"].  # 2nd pair, etc. ])
Custom debug flags PlatformIO removes all debug/optimization flags before a debug session or when build_configurations is set to debug and overrides them with -0g -g2 -ggdb2 for ASFLAGS, CCFLAGS, and LINKFLAGS build scopes.
An extra script allows us to override PlatformIO's default behavior and declare custom flags. See example below where we override -Og with -O0:
[env:teensy31] platform = teensy board = teensy31 framework = arduino extra_scripts = custom_debug_flags.py
custom_debug_flags.py:
if env.GetBuildType() == "debug": for scope in ("ASFLAGS", "CCFLAGS", "LINKFLAGS"): for i, flag in enumerate(env[scope]): if flag == "-Og": env[scope][i] = "-O0"
Library Manager PlatformIO Library Manager is a tool for managing libraries of PlatformIO Registry and VCS repositories (Git, Hg, SVN). It makes it exceedingly simple to find, install and keep libraries up-to-date. PlatformIO Library Manager supports Semantic Versioning and its rules.
pioide has built-in piohome with a modern GUI which allows:
• Search for new libraries in PlatformIO Registry
• "1-click" library installation, per-project libraries, extra storages
• List installed libraries in multiple storages
• List built-in libraries (by frameworks)
• Updates for installed libraries
• Multiple examples, trending libraries, and more. [image]
Quick Start PlatformIO Library Manager is a tool for managing libraries of PlatformIO Registry and VCS repositories (Git, Hg, SVN). It makes it exceedingly simple to find, install and keep libraries up-to-date. PlatformIO Library Manager supports Semantic Versioning and its rules.
There are 3 options how to find/manage libraries:
• piohome
• Web Library Search
• PIO Core Command Line Interface
You can manage different library storages using platformio lib --global or  platformio lib --storage-dir options. If you change current working directory in terminal to project folder, then platformio lib command will manage automatically dependency storage in projectconf_pio_libdeps_dir.
Project dependencies PlatformIO Library Manager allows one to specify project dependencies (projectconf_lib_deps) that will be installed automatically per project before environment processing. You do not need to install libraries manually.  The only one simple step is to define dependencies in projectconf.  You can use library ID, Name or even repository URL. For example,
[env:myenv] platform = ... framework = ... board = ... lib_deps = 13 PubSubClient ArduinoJson@~5.6,!=5.4 https://github.com/gioblu/PJON.git#v2.0 https://github.com/me-no-dev/ESPAsyncTCP.git https://github.com/adafruit/DHT-sensor-library/archive/master.zip
Please follow to cmd_lib_install for detailed documentation about possible values.
PlatformIO IDE pioide has built-in piohome with a modern GUI which allows:
PlatformIO Core [image]
CLI Guide Library Dependency Finder (LDF) Library Dependency Finder is a core part of PlatformIO Build System that operates with the C/C++ source files and looks for #include ... directives to know what header directories to include for the compiler.
In spite of the fact that Library Dependency Finder is written in pure Python, it evaluates C/C++ Preprocessor conditional syntax (#ifdef, if, defined, else, and elif) without calling gcc -E. This approach allows to significantly reduce the total compilation time. See Dependency Finder Mode for more details.
Contents • Library Dependency Finder (LDF)
• Configuration
• Storage
• Dependency Finder Mode
• Compatibility Mode
• C/C++ Preprocessor conditional syntax
Configuration Library Dependency Finder can be configured from projectconf:
Storage There are different storages where Library Dependency Finder looks for libraries. These storages (folders) have priority and LDF operates in the next order:
1. projectconf_lib_extra_dirs - extra storages per build environment
2. projectconf_pio_lib_dir - own/private library storage per project
3. projectconf_pio_libdeps_dir - project dependency storage used by librarymanager
4. "projectconf_pio_core_dir/lib" - global storage per all projects.
5. Library storages built into frameworks, SDKs.
Dependency Finder Mode Library Dependency Finder starts work from analyzing source files of the project (projectconf_pio_src_dir) and can work in the next modes:
off    "Manual mode", does not process source files of a project and dependencies.  Builds only the libraries that are specified in manifests (library_config, module.json) or using projectconf_lib_deps option.
chain  [DEFAULT] Parses ALL C/C++ source files of the project and follows only by nested includes (#include ..., chain...) from the libraries.  It also parses C, CC, CPP files from libraries which have the same name as included header file. Does not evaluate C/C++ Preprocessor conditional syntax.
deep   Parses ALL C/C++ source files of the project and parses ALL C/C++ source files of the each found dependency (recursively).  Does not evaluate C/C++ Preprocessor conditional syntax.
chain+ The same behavior as for the chain but evaluates C/C++ Preprocessor conditional syntax.
deep+  The same behavior as for the deep but evaluates C/C++ Preprocessor conditional syntax.
The mode can be changed using projectconf_lib_ldf_mode option in projectconf. Default value is set to chain.
NOTE: Usually, when the LDF appears to fail to identify a dependency of a library, it is because the dependency is only referenced from a library source file, and not a library header file (see example below). In this case, it is necessary to either explicitly reference the dependency from the project source or projectconf (projectconf_lib_deps option), or change the LDF mode to "deep" (not generally recommended).
A difference between chain/chain+ and deep/deep+ modes. For example, there are 2 libraries:
• Library Foo with files:
• Foo/foo.h
• Foo/foo.cpp
• Foo/extra.cpp
• Library Bar with files:
• Bar/bar.h
• Bar/bar.cpp
• lib_ldf_mode = chain
• Foo/foo.h depends on the Bar library (contains #include <bar.h>)
• #include <foo.h> is located in one of the project source files
Here the nested includes (project file > foo.h > bar.h) and LDF will find both libraries "Foo`` and Bar.
• Foo/extra.cpp depends on the Bar library (contains #include <bar.h>)
In this case, LDF will not find the Bar library because it doesn't know about the CPP file (Foo/extra.cpp).
• lib_ldf_mode = deep
• Foo/extra.cpp depends on Bar library (contains #include <bar.h>)
Firstly, LDF finds the Foo library, then it parses all sources from the Foo library and finds Foo/extra.cpp that depends on #include <bar.h>.  Secondly, it will parse all sources from the Bar library. This operation continues until all dependencies will not be parsed.
Compatibility Mode Compatibility mode allows one to control strictness of Library Dependency Finder.  If library contains one of manifest file (library_config, library.properties, module.json), then LDF check compatibility of this library with real build environment. Available compatibility modes:
off    Does not check for compatibility (is not recommended)
soft   [DEFAULT] Checks for the compatibility with projectconf_env_framework from build environment
strict Checks for the compatibility with projectconf_env_framework and projectconf_env_platform from build environment.
This mode can be changed using projectconf_lib_compat_mode option in projectconf. Default value is set to soft.
C/C++ Preprocessor conditional syntax In spite of the fact that Library Dependency Finder is written in pure Python, it evaluates C/C++ Preprocessor conditional syntax (#ifdef, if, defined, else, and elif) without calling gcc -E. For example,
[env:myenv] lib_ldf_mode = chain+ build_flags = -D MY_PROJECT_VERSION=13
mylib.h
#ifdef MY_PROJECT_VERSION // include common file for the project #include "my_common.h" #endif
#if MY_PROJECT_VERSION < 10 // this include will be ignored because does not satisfy condition above #include "my_old.h" #endif
library.json library.json is a manifest file of development library. It allows developers to keep project in own structure and define:
• location of source code
• examples list
• compatible frameworks and platforms
• library dependencies
• advanced build settings
PlatformIO Library Crawler uses library.json manifest to extract source code from developer's location and keeps a cleaned library in own Library Registry.
A data in library.json should be represented in JSON-style via associative array (name/value pairs). An order doesn't matter. The allowable fields (names from pairs) are described below.
Fields • name
• version
• keywords
• authors
• repository
• license
• downloadUrl
• homepage
• export
• include
• exclude
• dependencies
• examples
• build
• flags
• unflags
• includeDir
• srcDir
• srcFilter
• extraScript
• libArchive
• libLDFMode
• libCompatMode
name Required | Type: String | Max. Length: 50
A name of the library.
• Must be unique.
• Should be slug style for simplicity, consistency and compatibility. Example: Arduino-SPI
• Title Case, Aa-z, can contain digits and dashes (but not start/end with them).
• Consecutive dashes are not allowed.
version Required | Type: String | Max. Length: 20
A version of the current library source code. Can contain a-z, digits, dots or dash and should be Semantic Versioning <http://semver.org> compatible.
"name": "Bar", "version": "1.0.0", "repository": { "type": "git", "url": "https://github.com/foo/bar.git" }
description Required | Type: String | Max. Length: 255
The field helps users to identify and search for your library with a brief description. Describe the hardware devices (sensors, boards and etc.) which are suitable with it.
keywords Required | Type: String | Max. Length: 255
Used for search by keyword. Helps to make your library easier to discover without people needing to know its name.
The keyword should be lowercased, can contain a-z, digits and dash (but not start/end with them). A list from the keywords can be specified with separator ,
authors Required if repository field is not defined | Type: Object or Array
An author contact information
• name Full name (Required)
• email
• url An author's contact page
• maintainer Specify "maintainer" status
"authors": { "name": "John Smith", "email": "me@john-smith.com", "url": "http://www.john-smith/contact" }
"authors": [ { "name": "John Smith", "email": "me@john-smith.com", "url": "http://www.john-smith/contact" }, { "name": "Andrew Smith", "email": "me@andrew-smith.com", "url": "http://www.andrew-smith/contact", "maintainer": true } ]
NOTE: You can omit authors field and define repository field. Only GitHub-based repository is supported now. In this case PlatformIO Library Registry Crawler will use information from GitHub API Users.
repository Required if downloadUrl field is not defined | Type: Object
The repository in which the source code can be found. The field consists of the next items:
• type the only "git", "hg" or "svn" are supported
• url
• branch if is not specified, default branch will be used. This field will be ignored if tag/release exists with the value of version.
"repository": { "type": "git", "url": "https://github.com/foo/bar.git" }
license Optional | Type: String
A license of the library. You can check the full list of SPDX license IDs. Ideally you should pick one that is OSI approved.
"license": "Apache-2.0"
downloadUrl Required if repository field is not defined | Type: String
It is the HTTP URL to the archived source code of library. It should end with the type of archive (.zip or .tar.gz).
NOTE: downloadUrl has higher priority than repository.
Example with detached release/tag on GitHub:
"version": "1.0.0", "downloadUrl": "https://github.com/foo/bar/archive/v1.0.0.tar.gz", "include": "bar-1.0.0"
See more library.json library_creating_examples.
homepage Optional | Type: String | Max. Length: 255
Home page of library (if is different from repository url).
export Optional | Type: Object
Explain PlatformIO Library Crawler which content from the repository/archive should be exported as "source code" of the library. This option is useful if need to exclude extra data (test code, docs, images, PDFs, etc). It allows one to reduce size of the final archive.
Possible options:
include Optional | Type: String or Array | Glob Pattern
If include field is a type of String, then PlatformIO Library Registry Crawler will recognize it like a "relative path inside repository/archive to library source code".  See example below where the only source code from the relative directory LibrarySourceCodeHere will be included.
"include": "some/child/dir/LibrarySourceCodeHere"
If include field is a type of Array, then PlatformIO Library Registry Crawler  will include only directories/files which match with include patterns.
"export": { "include": [ "dir/*.[ch]pp", "dir/examples/*", "*/*/*.h" ] }
Pattern Meaning
exclude Optional | Type: String or Array | Glob Pattern
Exclude the directories and files which match with exclude patterns.
frameworks Optional | Type: String or Array
A list with compatible frameworks. The available framework types are defined in the frameworks section.
If the library is compatible with the all frameworks, then you can use * symbol:
"frameworks": "*"
platforms Optional | Type: String or Array
A list with compatible platforms. The available platform types are defined in platforms section.
If the library is compatible with the all platforms, then you can use * symbol:
"platforms": "*"
dependencies Optional | Type: Array or Object
A list of dependent libraries. They will be installed automatically with cmd_lib_install command.
Allowed requirements for dependent library:
• name | Type: String
• version | Type: String
• authors | Type: String or Array
• frameworks | Type: String or Array
• platforms | Type: String or Array
• ^1.2.3 - any compatible version (exact version for 1.x.x versions
The rest possible values including VCS repository URLs are documented in cmd_lib_install command.
"dependencies": [ { "name": "Library-Foo", "authors": [ "Jhon Smith", "Andrew Smith" ] }, { "name": "Library-Bar", "version": "~1.2.3" }, { "name": "lib-from-repo", "version": "https://github.com/user/package.git#1.2.3" } ]
A short definition of dependencies is allowed:
"dependencies": { "mylib": "1.2.3", "lib-from-repo": "githubuser/package" }
examples Optional | Type: String or Array | Glob Pattern
A list of example patterns. This field is predefined with default value:
"examples": [ "[Ee]xamples/*.c", "[Ee]xamples/*.cpp", "[Ee]xamples/*.ino", "[Ee]xamples/*.pde", "[Ee]xamples/*/*.c", "[Ee]xamples/*/*.cpp", "[Ee]xamples/*/*.ino", "[Ee]xamples/*/*.pde", "[Ee]xamples/*/*/*.c", "[Ee]xamples/*/*/*.cpp", "[Ee]xamples/*/*/*.ino", "[Ee]xamples/*/*/*.pde" ]
build Optional | Type: Object
Specify advanced settings, options and flags for the build system. Possible options:
flags Optional | Type: String or Array
Extra flags to control preprocessing, compilation, assembly and linking processes. More details projectconf_build_flags.
unflags Optional | Type: String or Array
Remove base/initial flags which were set by development platform. More details projectconf_build_unflags.
includeDir Optional | Type: String
Custom location of library header files. A default value is include and means that folder is located in the root of a library.
srcDir Optional | Type: String
Custom location of library source code. A default value is src and means that folder is located in the root of a library.
srcFilter Optional | Type: String or Array
Specify which source files should be included/excluded from build process.  The path in filter should be relative from a root of library.
See syntax in projectconf_src_filter.
Please note that you can generate source filter "on-the-fly" using extraScript (see below)
extraScript Optional | Type: String
Launch extra script before build process.  More details projectconf_extra_scripts.
Example (HAL-based library)
This example demonstrates how to build HAL-dependent source files and exclude other source files from a build process.
├── lib │   ├── README │   └── SomeLib │       ├── extra_script.py │       ├── hal │       │   ├── bar │       │   │   ├── hal.c │       │   │   └── hal.h │       │   ├── foo │       │       ├── hal.c │       │       └── hal.h │       ├── library.json │       ├── SomeLib.c │       └── SomeLib.h ├── platformio.ini └── src └── test.c
[env:foo] platform = native build_flags = -DHAL=foo
[env:bar] platform = native build_flags = -DHAL=bar
library.json
{ "name": "SomeLib", "version": "0.0.0", "build": { "extraScript": "extra_script.py" } }
extra_script.py
Import('env') from os.path import join, realpath
# private library flags for item in env.get("CPPDEFINES", []): if isinstance(item, tuple) and item[0] == "HAL": env.Append(CPPPATH=[realpath(join("hal", item[1]))]) env.Replace(SRC_FILTER=["+<*>", "-<hal>", "+<%s>" % join("hal", item[1])]) break
# pass flags to a global build environment (for all libraries, etc) global_env = DefaultEnvironment() global_env.Append( CPPDEFINES=[ ("MQTT_MAX_PACKET_SIZE", 512), "ARDUINOJSON_ENABLE_STD_STRING", ("BUFFER_LENGTH", 32) ] )
libArchive Optional | Type: Boolean
Create an archive (*.a, static library) from the object files and link it into a firmware (program). This is default behavior of PlatformIO Build System ("libArchive": true).
Setting "libArchive": false will instruct PIO Build System to link object files directly (in-line). This could be useful if you need to override weak symbols defined in framework or other libraries.
You can disable library archiving globally using projectconf_lib_archive option in projectconf.
libLDFMode Optional | Type: String
Specify Library Dependency Finder Mode. See ldf_mode for details.
libCompatMode Optional | Type: String
Specify Library Compatibility Mode. See ldf_compat_mode for details.
Examples 1. Custom macros/defines
"build": { "flags": "-D MYLIB_REV=1.2.3 -DRELEASE" }
2. Extra includes for C preprocessor
"build": { "flags": [ "-I inc", "-I inc/target_x13" ] }
3. Force to use C99 standard instead of C11
"build": { "unflags": "-std=gnu++11", "flags": "-std=c99" }
4. Build source files (c, cpp, h) at the top level of the library
"build": { "srcFilter": [ "+<*.c>", "+<*.cpp>", "+<*.h>" ] }
5. Extend PlatformIO Build System with own extra script
"build": { "extraScript": "generate_headers.py" }
generate_headers.py
Import('env') # print(env.Dump()) env.Append( CPPDEFINES=["HELLO=WORLD", "TAG=1.2.3", "DEBUG"], CPPPATH=["inc", "inc/devices"] )
# some python code that generates header files "on-the-fly"
Creating Library PlatformIO librarymanager doesn't have any requirements to a library source code structure. The only one requirement is library's manifest file - library_config, library.properties or module.json. It can be located inside your library or in the another location where PlatformIO Library Registry Crawler will have HTTP access.
Updates to existing libraries are done every 24 hours. In case a more urgent update is required, you can post a request on PlatformIO community.
Contents • Source Code Location
• At GitHub
• Under VCS (SVN/GIT)
• Self-hosted
• Register
Source Code Location There are a several ways how to share your library with the whole world (see examples).
You can hold a lot of libraries (split into separated folders) inside one of the repository/archive. In this case, you need to specify include option of libjson_export field to relative path to your library's source code.
At GitHub Recommended
If a library source code is located at GitHub, then you need to specify only these fields in the library_config:
• libjson_name
• libjson_version (is not required, but highly recommended for new librarymanager)
• libjson_keywords
• libjson_description
• libjson_repository
PlatformIO Library Registry Crawler will populate the rest fields, like libjson_authors with an actual information from GitHub.
Example, DallasTemperature:
{ "name": "DallasTemperature", "keywords": "onewire, 1-wire, bus, sensor, temperature", "description": "Arduino Library for Dallas Temperature ICs (DS18B20, DS18S20, DS1822, DS1820)", "repository": { "type": "git", "url": "https://github.com/milesburton/Arduino-Temperature-Control-Library.git" }, "authors": [ { "name": "Miles Burton", "email": "miles@mnetcs.com", "url": "http://www.milesburton.com", "maintainer": true }, { "name": "Tim Newsome", "email": "nuisance@casualhacker.net" }, { "name": "Guil Barros", "email": "gfbarros@bappos.com" }, { "name": "Rob Tillaart", "email": "rob.tillaart@gmail.com" } ], "dependencies": [ { "name": "OneWire", "authors": "Paul Stoffregen", "frameworks": "arduino" } ], "version": "3.7.7", "frameworks": "arduino", "platforms": "*" }
Under VCS (SVN/GIT) PlatformIO Library Registry Crawler can operate with a library source code that is under VCS control.  The list of required fields in the library_config will look like:
• libjson_authors
{ "name": "XBee", "keywords": "xbee, protocol, radio", "description": "Arduino library for communicating with XBees in API mode", "authors": { "name": "Andrew Rapp", "email": "andrew.rapp@gmail.com", "url": "https://code.google.com/u/andrew.rapp@gmail.com/" }, "repository": { "type": "git", "url": "https://code.google.com/p/xbee-arduino/" }, "frameworks": "arduino", "platforms": "atmelavr" }
Self-hosted You can manually archive (Zip, Tar.Gz) your library source code and host it in the Internet. Then you should specify the additional fields, like libjson_version and libjson_downloadurl. The final list of required fields in the library_config will look like:
• libjson_version
• libjson_downloadurl
{ "name": "OneWire", "keywords": "onewire, 1-wire, bus, sensor, temperature, ibutton", "description": "Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)", "authors": { "name": "Paul Stoffregen", "url": "http://www.pjrc.com/teensy/td_libs_OneWire.html" }, "version": "2.2", "downloadUrl": "http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip", "export": { "include": "OneWire" }, "frameworks": "arduino", "platforms": "atmelavr" }
Register The registration requirements:
• A library must adhere to the library manifest specification - library_config, library.properties or module.json.
• There must be public HTTP access to the library manifest file.
Now, you can register your library and allow others to install it.
Examples Command:
$ platformio lib register http://my.example.com/library.json $ platformio lib register http://my.example.com/library.properties $ platformio lib register http://my.example.com/module.json
• GitHub + detached release
• Dependencies by author and framework
• Multiple libraries in the one repository
Development Platforms The PlatformIO ecosystem has a decentralized architecture, allowing development for a range of development platforms. A development platform (or just "platform" for short) is usually a particular microcontroller or processor architecture that PlatformIO projects can be compiled to run on. (A few platforms, for example Teensy, use different target architectures for different boards.)
Each of the three supported host systems Mac OS X, Linux and Windows support compiling for all platforms listed below. Some platforms are also supported under ARM Linux hosts such as Raspberry Pi. For each development platform, PlatformIO defines:
• The PlatformIO Build System build scripts for the supported frameworks and SDKs
• Pre-configured presets for embedded circuit boards
• Pre-compiled toolchains and related tools for the architechture(s)
Each project must specify the platform name using the projectconf_env_platform option in projectconf. A specific platform version can optionally be specified as well. As embedded boards are equipped with a particular microcontroller, each embedded board specifies what development platform it uses and this can not be changed.
If a new board uses an architecture not in this list, a custom development platform can be created; see platform_creating.
Embedded Aceinna IMU Configuration projectconf_env_platform = aceinna_imu
Open-source, embedded development platform for Aceinna IMU hardware. Run custom algorithms and navigation code on Aceinna IMU/INS hardware.
For more detailed information please visit vendor site.
Contents • Examples
• Debugging
• Stable and upstream versions
• Packages
• Boards
Examples Examples are listed from Aceinna IMU development platform repository:
• OpenIMU300RI
• OpenIMU330BI
• OpenRTK330LI
• OpenIMU300ZI
Debugging piodebug - "1-click" solution for debugging with a zero configuration.
• Tools & Debug Probes
• On-Board Debug Tools
• External Debug Tools
Tools & Debug Probes Supported debugging tools are listed in "Debug" column. For more detailed information, please scroll table by horizontal.  You can switch between debugging debugging_tools using projectconf_debug_tool option in projectconf.
WARNING: You will need to install debug tool drivers depending on your system. Please click on compatible debug tool below for the further instructions.
On-Board Debug Tools Boards listed below have on-board debug probe and ARE READY for debugging!  You do not need to use/buy external debug probe.
┌─────────────────────────────┬───────────────┬───────────┬───────┬───────┐ │Name                         │ MCU           │ Frequency │ Flash │ RAM   │ ├─────────────────────────────┼───────────────┼───────────┼───────┼───────┤ │board_aceinna_imu_LowCostRTK │ STM32F469NIH6 │ 180MHz    │ 1MB   │ 384KB │ └─────────────────────────────┴───────────────┴───────────┴───────┴───────┘
External Debug Tools Boards listed below are compatible with piodebug but DEPEND ON external debug probe. They ARE NOT READY for debugging.  Please click on board name for the further details.
┌───────────────────────────────┬─────────────┬───────────┬───────┬───────┐ │Name                           │ MCU         │ Frequency │ Flash │ RAM   │ ├───────────────────────────────┼─────────────┼───────────┼───────┼───────┤ │board_aceinna_imu_OpenIMU300   │ STM32F405RG │ 120MHz    │ 1MB   │ 128KB │ ├───────────────────────────────┼─────────────┼───────────┼───────┼───────┤ │board_aceinna_imu_OpenIMU300ZA │ STM32F405RG │ 120MHz    │ 1MB   │ 128KB │ ├───────────────────────────────┼─────────────┼───────────┼───────┼───────┤ │board_aceinna_imu_OpenIMU330   │ STM32L431CB │ 80MHz     │ 128KB │ 64KB  │ ├───────────────────────────────┼─────────────┼───────────┼───────┼───────┤ │board_aceinna_imu_OpenRTK      │ STM32F469IG │ 180MHz    │ 1MB   │ 384KB │ ├───────────────────────────────┼─────────────┼───────────┼───────┼───────┤ │board_aceinna_imu_OpenRTK330L  │ STM32F469IG │ 180MHz    │ 1MB   │ 384KB │ └───────────────────────────────┴─────────────┴───────────┴───────┴───────┘
Stable and upstream versions You can switch between stable releases of Aceinna IMU development platform and the latest upstream version using projectconf_env_platform option in projectconf as described below.
Stable ; Latest stable version [env:latest_stable] platform = aceinna_imu board = ...
; Custom stable version [env:custom_stable] platform = aceinna_imu@x.y.z board = ...
Upstream [env:upstream_develop] platform = https://github.com/aceinna/platform-aceinna_imu.git board = ...
Packages ┌─────────────────────────┬────────────────────────────┐ │Name                     │ Description                │ ├─────────────────────────┼────────────────────────────┤ │tool-jlink               │ SEGGER J-Link Software and │ │                         │ Documentation Pack         │ ├─────────────────────────┼────────────────────────────┤ │tool-openocd             │ OpenOCD                    │ ├─────────────────────────┼────────────────────────────┤ │toolchain-gccarmnoneeabi │ gcc-arm-embedded           │ └─────────────────────────┴────────────────────────────┘
WARNING: Linux Users:
• Install "udev" rules faq_udev_rules
Windows Users: Please check that you have a correctly installed USB driver from board manufacturer
Boards NOTE:
• You can list pre-configured boards by cmd_boards command or PlatformIO Boards Explorer
• For more detailed board information please scroll the tables below by horizontally.
Aceinna
┌───────────────────────────────┬──────────┬───────────────┬───────────┬───────┬───────┐
│Name                           │ Debug    │ MCU           │ Frequency │ Flash │ RAM   │
├───────────────────────────────┼──────────┼───────────────┼───────────┼───────┼───────┤
│board_aceinna_imu_LowCostRTK   │ On-board │ STM32F469NIH6 │ 180MHz    │ 1MB   │ 384KB │
├───────────────────────────────┼──────────┼───────────────┼───────────┼───────┼───────┤
│board_aceinna_imu_OpenIMU300   │ External │ STM32F405RG   │ 120MHz    │ 1MB   │ 128KB │
├───────────────────────────────┼──────────┼───────────────┼───────────┼───────┼───────┤
│board_aceinna_imu_OpenIMU300ZA │ External │ STM32F405RG   │ 120MHz    │ 1MB   │ 128KB │
├───────────────────────────────┼──────────┼───────────────┼───────────┼───────┼───────┤
│board_aceinna_imu_OpenIMU330   │ External │ STM32L431CB   │ 80MHz     │ 128KB │ 64KB  │
├───────────────────────────────┼──────────┼───────────────┼───────────┼───────┼───────┤
│board_aceinna_imu_OpenRTK      │ External │ STM32F469IG   │ 180MHz    │ 1MB   │ 384KB │
├───────────────────────────────┼──────────┼───────────────┼───────────┼───────┼───────┤
│board_aceinna_imu_OpenRTK330L  │ External │ STM32F469IG   │ 180MHz    │ 1MB   │ 384KB │
└───────────────────────────────┴──────────┴───────────────┴───────────┴───────┴───────┘
Atmel AVR Configuration projectconf_env_platform = atmelavr
Atmel AVR 8-bit MCUs deliver a unique combination of performance, power efficiency and design flexibility. Optimized to speed time to market-and easily adapt to new ones-they are based on the industry's most code-efficient architecture for C and assembly programming
Contents • Configuration
• Frameworks
Configuration • Upload using Programmer
• Upload EEPROM data
• Fuses programming
• Custom fuses
• MiniCore, MegaCore and MightyCore
• Bootloader programming
• Custom bootloader
Upload using Programmer To upload firmware using programmer you need to use program target instead of upload for platformio run --target command. For example, platformio run -t program.
WARNING: Upload options like upload_port don't work as expected with platformio run -t program. You need to use upload_flags if you want to specify custom port or speed (see examples below).
NOTE: List of avrdude supported programmers are accessible with avrdude -c ?
Configuration for the programmers:
• AVR ISP
[env:myenv] platform = atmelavr framework = arduino upload_protocol = stk500v1 ; each flag in a new line upload_flags = -P$UPLOAD_PORT
; edit this line with valid upload port upload_port = SERIAL_PORT_HERE
• AVRISP mkII
[env:myenv] platform = atmelavr framework = arduino upload_protocol = stk500v2 ; each flag in a new line upload_flags = -Pusb
• USBtinyISP
[env:myenv] platform = atmelavr framework = arduino upload_protocol = usbtiny
• ArduinoISP
[env:myenv] platform = atmelavr framework = arduino upload_protocol = arduinoisp
• USBasp
[env:myenv] platform = atmelavr framework = arduino upload_protocol = usbasp ; each flag in a new line upload_flags = -Pusb
• Parallel Programmer
[env:myenv] platform = atmelavr framework = arduino upload_protocol = dapa ; each flag in a new line upload_flags = -F
• Arduino as ISP
[env:myenv] platform = atmelavr framework = arduino upload_protocol = stk500v1 ; each flag in a new line upload_flags = -P$UPLOAD_PORT -b$UPLOAD_SPEED
; edit these lines upload_port = SERIAL_PORT_HERE upload_speed = 19200
• Bus Pirate as ISP
[env:myenv] platform = atmelavr framework = arduino upload_protocol = buspirate ; each flag in a new line upload_flags = -P$UPLOAD_PORT -b$UPLOAD_SPEED
; edit these lines upload_port = SERIAL_PORT_HERE upload_speed = 115200
Upload EEPROM data To upload EEPROM data (from EEMEM directive) you need to use uploadeep target instead upload for platformio run --target command.  For example, platformio run -t uploadeep.
Fuses programming PlatformIO has a built-in target named fuses for setting fuse bits. The default fuse bits are predefined in board manifest file in fuses section. For example, fuses section for Arduino Uno board. To set fuse bits you need to use target fuses with platformio run --target command.
Custom fuses Custom fuse values and upload flags (based on upload protocol) should be specified in projectconf. lfuse and hfuse bits are mandatory, efuse is optional and not supported by all targets. An example of setting custom fuses for uno board:
[env:custom_fuses] platform = atmelavr framework = arduino board = uno upload_protocol = stk500v1 upload_speed = 19200 board_fuses.lfuse = 0xAA board_fuses.hfuse = 0xBB board_fuses.efuse = 0xCC upload_flags = -PCOM15 -b$UPLOAD_SPEED -e
MiniCore, MegaCore and MightyCore MiniCore, MegaCore and MightyCore support dynamic fuses generation. Generated values are based on the next parameters:
┌───────────┬──────────────────────┬───────────────┐ │Parameter  │ Description          │ Default value │ ├───────────┼──────────────────────┼───────────────┤ │f_cpu      │ Specifies the clock  │ 16000000L     │ │           │ frequencies in Hz.   │               │ │           │ Used to determine    │               │ │           │ what oscillator      │               │ │           │ option to choose. A  │               │ │           │ capital L has to be  │               │ │           │ added to the end of  │               │ │           │ the frequency        │               │ │           │ number.              │               │ ├───────────┼──────────────────────┼───────────────┤ │oscillator │ Specifies which      │ external      │ │           │ oscillator is used   │               │ │           │ internal or          │               │ │           │ external. Internal   │               │ │           │ oscillator only      │               │ │           │ works with f_cpu     │               │ │           │ values 8000000L and  │               │ │           │ 1000000L             │               │ └───────────┴──────────────────────┴───────────────┘
│uart       │ Specifies the        │ uart0         │ │           │ hardware UART port   │               │ │           │ used for serial      │               │ │           │ upload. can be       │               │ │           │ uart0, uart1, uart2  │               │ │           │ or uart3 depending   │               │ │           │ on the target. Use   │               │ │           │ no_bootloader if     │               │ │           │ you're not using a   │               │ │           │ bootloader for       │               │ │           │ serial upload.       │               │ ├───────────┼──────────────────────┼───────────────┤ │bod        │ Specifies the        │ 2.7v          │ │           │ hardware brown-out   │               │ │           │ detection. Use       │               │ │           │ disabled to disable  │               │ │           │ brown-out detection. │               │ ├───────────┼──────────────────────┼───────────────┤ │eesave     │ Specifies if the     │ yes           │ │           │ EEPROM memory should │               │ │           │ be retained when     │               │ │           │ uploading using a    │               │ │           │ programmer. Use no   │               │ │           │ to disable           │               │ └───────────┴──────────────────────┴───────────────┘
Valid BOD values:
┌──────────────────┬──────────────────┬───────────────┐ │ATmega8,          │ AT90CAN32/64/128 │ Other targets │ │ATmega8535/16/32, │                  │               │ │ATmega64/128      │                  │               │ ├──────────────────┼──────────────────┼───────────────┤ │4.0v              │ 4.1v             │ 4.3v          │ ├──────────────────┼──────────────────┼───────────────┤ │2.7v              │ 4.0v             │ 2.7v          │ ├──────────────────┼──────────────────┼───────────────┤ │disabled          │ 3.9v             │ 1.8v          │ ├──────────────────┼──────────────────┼───────────────┤ │                  │ 3.8v             │ disabled      │ ├──────────────────┼──────────────────┼───────────────┤ │                  │ 2.7v             │               │ ├──────────────────┼──────────────────┼───────────────┤ │                  │ 2.6v             │               │ ├──────────────────┼──────────────────┼───────────────┤ │                  │ 2.5v             │               │ ├──────────────────┼──────────────────┼───────────────┤ │                  │ disabled         │               │ └──────────────────┴──────────────────┴───────────────┘
Hardware configuration example:
[env:custom_fuses] platform = atmelavr framework = arduino board = ATmega32
board_build.f_cpu = 1000000L board_hardware.uart = uart0 board_hardware.oscillator = internal board_hardware.bod = 2.7v board_hardware.eesave = no
upload_protocol = usbasp upload_flags = -Pusb
Bootloader programming PlatformIO has a built-in target named bootloader for flashing bootloaders. The default bootloader image and corresponding fuse bits are predefined in board manifest file in bootloader section, for example, Arduino Uno. To upload bootloader image you need to use target bootloader with platformio run --target command.
Custom bootloader Custom bootloader and corresponding fuses should be specified in projectconf. If lock_bits and unlock_bits are not set then the default values 0x0F and 0x3F are used accordingly. An example of setting custom bootloader for uno board:
board_bootloader.file = /path/to/custom/bootloader.hex board_bootloader.lfuse = 0xFF board_bootloader.hfuse = 0xDE board_bootloader.efuse = 0xFD board_bootloader.lock_bits = 0x0F board_bootloader.unlock_bits = 0x3F
MiniCore, MegaCore and MightyCore have a wide variety of precompiled bootloaders. Bootloader binary is dynamically selected according to the hardware parameters: f_cpu, oscillator, upload_speed:
┌──────────┬───────────────────┬──────────────┐ │Frequency │ Oscillator        │ Upload Speed │ ├──────────┼───────────────────┼──────────────┤ │20000000L │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │18432000L │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │16000000L │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │14745600L │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │12000000L │ external          │ 57600        │ └──────────┴───────────────────┴──────────────┘
│11059200L │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │8000000L  │ external/internal │ 57600/38400  │ ├──────────┼───────────────────┼──────────────┤ │7372800L  │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │3686400L  │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │1843200L  │ external          │ 115200       │ ├──────────┼───────────────────┼──────────────┤ │1000000L  │ external/internal │ 9600         │ └──────────┴───────────────────┴──────────────┘
Examples Examples are listed from Atmel AVR development platform repository:
• arduino-blink
• simba-blink
• native-blink
• arduino-own-src_dir
• engduino-magnetometer
• digitstump-mouse
• arduino-internal-libs
• arduino-external-libs
Stable and upstream versions You can switch between stable releases of Atmel AVR development platform and the latest upstream version using projectconf_env_platform option in projectconf as described below.
Stable ; Latest stable version [env:latest_stable] platform = atmelavr board = ...
; Custom stable version [env:custom_stable] platform = atmelavr@x.y.z board = ...
Upstream [env:upstream_develop] platform = https://github.com/platformio/platform-atmelavr.git board = ...
Packages ┌──────────────────────────────────┬────────────────────────────┐ │Name                              │ Description                │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr             │ Arduino Wiring-based       │ │                                  │ Framework (AVR Core)       │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-attiny      │ Arduino Wiring-based       │ │                                  │ Framework (ATTiny Core)    │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-bean        │ Arduino Wiring-based       │ │                                  │ Framework (Bean Core)      │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-core13      │ Arduino Wiring-based       │ │                                  │ Framework (Core13)         │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-digistump   │ Arduino Wiring-based       │ │                                  │ Framework (Digistump Core) │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-dwenguino   │ Arduino Wiring-based       │ │                                  │ Framework (Dwenguino Core) │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-majorcore   │ Arduino Wiring-based       │ │                                  │ Framework (Major Core)     │ └──────────────────────────────────┴────────────────────────────┘
│framework-arduino-avr-megacore    │ Arduino Wiring-based       │ │                                  │ Framework (MegaCore)       │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-mightycore  │ Arduino Wiring-based       │ │                                  │ Framework (MightyCore)     │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-minicore    │ Arduino Wiring-based       │ │                                  │ Framework (MiniCore)       │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-nicai       │ Arduino Wiring-based       │ │                                  │ Framework (Nicai Core)     │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-panstamp    │ Arduino Wiring-based       │ │                                  │ Framework (Panstamp Core)  │ ├──────────────────────────────────┼────────────────────────────┤ │framework-arduino-avr-prusa_rambo │ Arduino Wiring-based       │ │                                  │ Framework (Prusa Rambo     │ │                                  │ Core)                      │ ├──────────────────────────────────┼────────────────────────────┤ │framework-simba                   │ Simba Framework            │ ├──────────────────────────────────┼────────────────────────────┤ │tool-avrdude                      │ AVRDUDE                    │ ├──────────────────────────────────┼────────────────────────────┤ │tool-micronucleus                 │ Micronucleus               │ ├──────────────────────────────────┼────────────────────────────┤ │tool-simavr                       │ simavr is a lean, mean and │ │                                  │ hackable AVR simulator     │ ├──────────────────────────────────┼────────────────────────────┤ │toolchain-atmelavr                │ avr-gcc                    │ └──────────────────────────────────┴────────────────────────────┘
Frameworks ┌──────────────────┬─────────────────────────────┐ │Name              │ Description                 │ ├──────────────────┼─────────────────────────────┤ │framework_arduino │ Arduino Wiring-based        │ │                  │ Framework allows writing    │ │                  │ cross-platform software to  │ │                  │ control devices attached to │ │                  │ a wide range of Arduino     │ │                  │ boards to create all kinds  │ │                  │ of creative coding,         │ │                  │ interactive objects, spaces │ │                  │ or physical experiences.    │ ├──────────────────┼─────────────────────────────┤ │framework_simba   │ Simba is an RTOS and build  │ │                  │ framework. It aims to make  │ │                  │ embedded programming easy   │ │                  │ and portable.               │ └──────────────────┴─────────────────────────────┘