Environment for Embedded programming
There are many IDE solutions on the web which require payment and which are free of charge; some are good and some are bad, but there is no universally perfect IDE. I personally tried a lot of them.
There are many IDE solutions on the web which require payment and which are free of charge; some are good and some are bad, but there is no universally perfect IDE. I personally tried a lot of them: Atmel Studio, Visual Studio, Arduino IDE, ARM Keil… and yes, they all get the job done but I didn’t like them, therefore PlatformIO IDE integration with VSCode text editor was the way to go. Is it for everyone? No. Is it good for programming every single chip in the world? No… But it works for me. In all of my tutorials in the future, for embedded development, I will use the solution explained in this text.
VSCode setup
- Go to Visual Studio Code website and download text editor in ZIP format. You can also download the executable and install it but I prefer portable version.
- For ZIP download, on the website click Other downloads and download .zip.
- Create folder Code somewhere in the filesystem and unpack ZIP into it.
- To start VSCode, run Code.exe
Adding PlatformIO extension
- In VSCode go to extensions, search for PlatformIO IDE and install it.
- The installation process should install all dependencies. If not, most common error is that Python and/or Clang is missing in the system.
System setup
- Install USB and FTDI drivers. Windows only
- Install USBasp drivers. Windows only
- Install STLink-v2 drivers. Linux/Windows
Blink example - ATmega328p - Arduino
- Go to PlatformIO Home and create a new project for Arduino Uno. You will need to have a connection to the internet when creating a new project. If this is your first project for this platform, initialization will take a few minutes (depending on the internet speed) since PlatformIO will download avrdude.

- In src directory of the project, enter blink code in main.cpp and build it by running PlatformIO Build command, default shortcut is Ctrl+Alt+B.
#include "Arduino.h"
#define led 13
void setup() {}
void loop() {
bool state = false;
pinMode(led, OUTPUT);
while(1) {
digitalWrite(led, state);
state = !state;
delay(1000);
}
}

- Tell PlatformIO to which port Arduino is connected by adding command to platformio.ini file in project directory (automatic detection is available but it is not reliable). For a Linux user it will look something like this
upload_port=/dev/ttyUSB0and for Windowsupload_port=COM0. Have in mind,the user that is running PlatformIO must have permission to access this port. - Upload code to Arduino using PlatformIO Upload, default shortcut is Ctrl+Alt+U. Since this is programming over USB using Arduino framework, you will need to have Arduino Bootloader pre-installed on the chip.

Blink example - ATmega328p-AU - USBasp
This will override bootloader on your chip!
- Create a new project for Arduino Uno.
- Write code that blinks onboard LED inside
/src/main.cpp.
#include "avr/io.h"
#include "util/delay.h"
#define t_bit(PORTx, PINx) PORTx ^= 1 << PINx
int main(void) {
DDRB |= 1 << PORTB5;
while(1) {
t_bit(PORTB, PIN5);
_delay_ms(100);
}
return 0;
}
- After building the code, we need to write a script that will upload HEX file to the MCU over USBasp.
- In the root directory of the project create file called upload. This file will contain the command for running avrdude for USBasp.
- Copy command to the file.
Linux
"/home/____USER____/.platformio/packages/tool-avrdude/avrdude" -C"/home/____USER____/.platformio/packages/tool-avrdude/avrdude.conf" -v -p____CHIP_____ -cusbasp -Pu sb -Uflash:w:.pioenvs/____BOARD____/firmware.hex:iWindows
"C:/Users/____USER____/.platformio/packages/tool-avrdude/avrdude" -C"C:/Users/____USER____/.platformio/packages/tool-avrdude/avrdude.conf" -v -p____CHIP_____ -cusbasp -Pu sb -Uflash:w:.pioenvs/____BOARD____/firmware.hex:i____USER____ is the Linux/Windows user. In my case it is banez.
____CHIP_____ is the name of MCU defined by PlatformIO. In my case it is atmega328p
____BOARD____ is the board defined in project. In my case it is uno.
- Run the file from terminal ./upload
- Upload should be successful if wires are connected correctly and all commands and paths in the script are good.
Blink example - STM32F103C8 - mbed
- Create new project for generic STM32F103C8 and select mbad for framework.
- Go to platformio.ini and set
upload_method=stlink. - Write a blink program.
#include "mbed.h"
int main(void) {
DigitalOut led(PC_13);
while(1) {
led.write(1);
wait(1);
led.write(0);
wait(1);
}
}
- Build and upload program using STlink.