Using Visual Studio Code for ARM Development – Defines

In the last post on Include Paths, I started with just a single error, and ended up with quite a large number of errors – it feels like going backwards! Keep in mind that the code actually builds and runs, so these are not actually problems with the code.

These errors are caused since the code I’m using, including the STM32 libraries standard ARM libraries, depend on macros that are not defined within the code itself. In this post, I will describe how to determine and pass the defines to Visual Studio Code so it will properly parse your code.

First, it is common to pass defines to the compiler using flags at compile time. In my case, I am using CMSIS and the new STM32 Low-Level library and that is included with the STM32Cube software, and I am targeting the 1bitsy development board, which uses an STM32F415 chip. In order for the library to use the right options, I need to pass these to the compiler, without them, many references to the library are not properly defined in the scope of my code.

-DUSE_FULL_LL_DRIVER
-DSTM32F415xx

Setting these for VSCode is simple: just add them to the “defines” section of c_cpp_properties.json, without the -D flag prefix:

"defines": [
"STM32F415xx",
"USE_FULL_LL_DRIVER"
],

Aha – This fixes all of the errors related to things defined in the libraries! But I still have one strange error remaining:

Isn’t uint32_t defined in stdint.h? I’ve included that, I don’t have any include errors… Grrr!

To be honest, this was quite maddening to figure out. The GNU ARM version of stdint.h actually drills down and leads to stdint-gcc.h, which is dependent upon a macro, but the macro isn’t defined! It’s also dependent on other macros to get there… This leaves uint32_t undefined, and the VSCode parser doesn’t know what to do with it. The same is true of all of the types defined in this file.

So why does this even compile? It turns out, that the GNU ARM compiler has many defines hard-coded into it, including __UINT32_TYPE__. The compiler will process the typedef properly, and then understand my code.

So, we need to figure out what these are, and set them for VSCode as well.

Since there are a very large number of defines (344!), I was able to dump them into a file by running

I’m not sure what all of these do, or when I might need them in the future, so I added all of them. (I used Excel to do some bulk editing tricks and sort them, but you can accomplish this however you are comfortable. I don’t want to reproduce the list as it may change with different builds of gcc; you should ensure it matches the compiler you are using!)

Again, follow the format of the -D compiler flag, just without the “-D” prefix. A few rules:

But now my error is gone, and hovering over the type shows it is defined!

If the include paths and defines are properly set up in Visual Studio Code, the C/C++ plugin should be able to properly parse your code, identify syntax errors, and will provide Intellisense code completion to improve the speed and accuracy of your writing!

In the next post, I will describe how build your code using Makefiles from within Visual Studio Code.

@schperplata … The DamogranLabs solution you posted is downright amazing. It took me a while to figure out (mostly because I’m new to VSCode), but I got it working on my Nucleo F446 and it is sooooo much better than working in Eclipse. A big THANK YOU!