Adding a new board to PlatformIO

I have defined/added a new board to PlatformIO but I can’t find any documentation whatsoever for the json board definition file, and specifically for the fields cited farther below.

It seems that different boards are defined in a fairly ad-hoc manner as if anything goes. Are there are some guidelines for how a well-formed board definition should look?

Also, once I have this working then I’d like to upload it to the project. Am I supposed to do a pull request, or do I email it out to the maintainer?

I’m puzzled that I’m not having to include register definitions and many other part-specific details about this board/CPU …or would I do that by creating a completely separate “bare metal” library? What happened to the “naked” framework thing? This seems really really sparse, especially considering that the CPU has specific methods of uploading code and debug features etc.

(1) “extra_flags”: What does this do? Does it actually affect anything or is it just for documentation purposes?

(2) “size_heap”: This is really weird because it would seem to be a compiler option and so why would it be defined here as part of CPU hardware? Wouldn’t it be safer to leave this out?

(3) “variant”: What does this do? It seems to be a documentation category thing rather than having actual effect during build-time.

(4) “f_cpu": "16000000L” Why is there an L at the end of the clock frequency? Some board definitions have an L while others do not.

Here is what I put together for the new Nuvoton N76E003 board:
“build”: {
“core”: “naked”,
“extra_flags”: “-DN76E003 -DNAKED_ARCH_MCS51 -DNAKED_MCS51_N76E003”,
“f_cpu”: “16000000L”,
“size_iram”: 256,
“size_xram”: 768,
“size_code”: 18432,
“size_heap”: 128,
“mcu”: “n76e003”,
“cpu”: “mcs51”,
“variant”: “n76e003”
“frameworks”: [],
“upload”: {
“maximum_ram_size”: 1024,
“maximum_size”: 18432
“name”: “Generic N76E003”,
“url”: “”,
“vendor”: “Nuvoton”

This acts like build_flags, adding global compiler flags to the build process when that board is used. Mostly used for propagating macros that are always needed / useful for that board. You can see it being processed here.

PlatformIO just takes this value and propagates this as a macro. It may or may not be used by the compiler. Feel free to PR into GitHub - platformio/platform-intel_mcs51: Intel MCS-51 (8051): development platform for PlatformIO if you don’t like this.

In most other platforms, this value determines which Arduino variant (folder) to use for a board. This value is unused in the platform logic as you seen. See here for counter-example.

The value of f_cpu is propagated as a macro as you read here, so the L is the suffix for a long integer constant in C/C++. Otherwise the value would internally overflow if the default int width is not big enough to hold that value. So, this may be bug in the other board definitions.

Hay thanks! That documents almost everything. Now there will be a flood of board submissions from world+dog. I figured out what’s up with the chip specific register definitions now: They go into the associated sample projects folder which I had to create for the new chip and an LED blinky needs to be included with that.

Once it’s all working, I’ll do a pull request and we’ll see what else they’ll make me do before they accept it.

I’ve created some new board definitions which I would like to upload to the PlatformIO project on GitHub. I’m including sample blinky code with these and it contains :#if defined" statements where I need to detect the currently selected board name of the currently active board “boards\boardname.json”. I see that platformio.ini also contains this under the board variable. Is there an environment variable accessible to my main.c which contains the current boardname?

This PlatformIO-internal information is not exposed in a macro by default and would need an extraScripts to work, see e.g. Inject Board Name into Code. That’s why the extraFlags in the board definition usually contains one macro unique to the board variant, say -DNUVOTON_N76E003.

I figured it out after inpecting the STM8 architecture examples, and I have implemented similar for mcs51 as shown below. It seems to take the value from the platformio.ini [env:BoardName] section headings but it capitalizes them before injecting them into the environment.

#if defined(N76E003)
   #include "n76e003.h"
   #define ledPin P14
   #define INIT_PIN P1M1 &= 0xFE; P1M2 &= 0xFE;
#elif defined(STC15F104W)
   #include "STC15xWES.h"
   #define ledPin P33
   #define INIT_PIN //No pin init needed
#elif defined(STC15W408AS)
   #include "STC15xA.h"
   #define ledPin P10
   #define INIT_PIN //No pin init needed
#else // GenericMCS51
   #include <mcs51/8051.h>
   #include <mcs51/8052.h>
   #define ledPin P1_0
   #define INIT_PIN //No pin init needed
1 Like

Ah thanks, that’s why it’s working for me. I’ll call it good enough!