If you are working with STMicroelectronics’ F0 and L0 family of microcontrollers, you are propably using Keil uVision as your IDE. However, if you try to use fancy stuff like mbed OS, and uTensor (this was actually the reason behind this article) on a relativley higher end microcontrollers, you are most likely going to get hit with the IDE dilemma. There are no modern, kinda proffesional, easy to install and use IDEs that are free! I mean, not really, otherwise, I would not have written this article 😁

In this post, I will detail a step-by-step guide to set up a functional VS Code IDE to work with projects exported from mbed-cli tool, on a Windows 10 environment. In this tutorial I am using STM32L4 Discovery kit IoT node (in mbed, this is known as DISCO_L475VG_IOT01A).


  1. Install Visual Studio Code (link).
  2. Download and install GNU Tools ARM Embedded (link).
  3. This will be installed in C:\Program Files (x86)\GNU Tools Arm Embedded.
  4. Add the \bin folder to your PATH environment variable (e.g., C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin).
  5. Download GNU Make Windows Build Tools (link).
  6. Extract the GNU Make files to a path (e.g., C:\Program Files\).
  7. Add the \bin folder to the PATH environment variable (e.g., C:\Program Files\GNU MCU Eclipse\Build Tools\2.10-20180103-1919\bin).
  8. Download and install Python 2.7 (link).
  9. Make sure you also install pip with the Python package.
  10. From command line, install mbed CLI:
    pip install mbed-cli
  11. Now you can export mbed projects to VS Code or any other IDE. To export to VS Code, from the project parent folder run:
    mbed export --ide vscode_gcc_arm --target DISCO_L475VG_IOT01A
  12. Change target to match yours. Run the following command to get a list of supported targets and toolchains:
    mbed target -S
  13. For a complete matrix of supported targets and IDEs, run:
    mbed export -S
  14. Export Makefile from mbed CLI:
    mbed export --ide make_gcc_arm --target DISCO_L475VG_IOT01A
  15. This will create a Makefile required by GNU Make to compile your project.
  16. Open the project folder with VS Code after exporting from mbed CLI.
  17. Open folder .vscode and edit file launch.json. Change field MIDebuggerPath under windows to be:
    "MIDebuggerPath": "arm-none-eabi-gdb.exe",
  18. Clear the field serverStarted, as this looks for a specific pattern in the output to start the GDB server. It’s causing problems in launching the GDB.
        "serverStarted": "",
  19. If you get Make error 87, this is because the makefile is passing a long command more than Windows API can process. Change the linking command in the makefile to be:
    $(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS) $(PROJECT).link_script.ld 
        $(file > $, $(filter %.o, $^))
        +@echo "link: $(notdir $@)"
        $(LD)   $(LD_FLAGS) -T $(filter-out %.o, $^) $(LIBRARY_PATHS) --output $@ @$ $(LIBRARIES) $(LD_SYS_LIBS)

    Instead of:

    $(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS) $(PROJECT).link_script.ld 
        +@echo "link: $(notdir $@)"
        @$(LD) $(LD_FLAGS) -T $(filter-out %.o, $^) $(LIBRARY_PATHS) --output $@ $(filter %.o, $^) $(LIBRARIES) $(LD_SYS_LIBS)

    What this does is that it breaks the command into two sections. (Note: there is a tab at the beginning of the second, third, and fourth lines).

  20. If your source is C++ and you get errors about C++11 standard, make sure that -std=c++11 is defined in CPP and CXX_FLAGS objects in the makefile. For example:
     CPP     = 'arm-none-eabi-g++' '-std=c++11' '-fno-rtti' '-Wvla' '-c' '-Wall' '-Wextra' '-Wno-unused-parameter' '-Wno-missing-field-initializers' '-fmessage-length=0' '-fno-exceptions' '-fno-builtin' '-ffunction-sections' '-fdata-sections' '-funsigned-char' '-MMD' '-fno-delete-null-pointer-checks' '-fomit-frame-pointer' '-O0' '-g3' '-DMBED_DEBUG' '-DMBED_TRAP_ERRORS_ENABLED=1' '-mcpu=cortex-m4' '-mthumb' '-mfpu=fpv4-sp-d16' '-mfloat-abi=softfp'
    CXX_FLAGS += -std=c++11
    CXX_FLAGS += -fno-rtti
    CXX_FLAGS += -Wvla
  21. So far, we haven’t setup the debugger yet. If you are using ST-LINK, you probably want to use OpenOCD. Other options available are SEGGER’s J-Link but this requires upgrading the ST-LINK to a J-Link firmware.
  22. Download and extract OpenOCD binaries for Windows somewhere (link). e.g., C:\openocd-0.10.0\.
  23. Add the \bin folder to your PATH environment variable (e.g., C:\openocd-0.10.0\bin).
  24. In launch.json, edit the field debugServerPath to be:
    "debugServerPath": "openocd.exe",

    Note: if you don’t add the \bin folder to your PATH, you should provide the full path to your openocd.exe. Make sure you can call openocd.exe directly from any command line prompt.

  25. Edit the filed debugServerArgs to add parameters to be passed to your openocd.exe call. This Tells OpenOCD what board/MCU you are trying to connect to.
    "debugServerArgs": "-f C:\\openocd-0.10.0\\scripts\\board\\stm32l4discovery.cfg -f C:\\openocd-0.10.0\\scripts\\interface\\stlink-v2-1.cfg -c init -c \"reset init\"",

    Note that you have to provide the full path to your configuration files. You can check supported boards by browsing the \board folders.

  26. In the Debug tab, hit the play button to start debugging.