Configuring VSCode for stm32 programming in Linux and not only Linux

Actually, the idea to write this article as a reminder to your beloved, well, maybe someone else came in handy a year ago, after he killed a lot of time for this simple activity. Recently it turned out that the problem is relevant to this day. For some reason, none of the options found by itself helps and this article is the result of processing all the information found. When deciding the question, it was most enraged – take my project and you will be happy, but the project is no longer there … I do not tolerate this approach, so I will not do it myself.

Everything described below is a consequence of my personal experience, and does not claim to be true. All tips are not intended for people who just decided to switch from AVR to STM32

Questions such as why Linux, VSCode and so on, I think, do not require coverage. I believe that all those interested in the question have long found their OWN answer to these little things. However, I note that in Windows all this also works, it is checked, and projects are calmly going through migration between machines.

Let’s start!

I will omit the VSCode installation stage, this stuff is so much in bulk that it’s even too much. I will only say that you need to install the modules at a minimum. C / C ++ from Microsoft (I believe that a plugin from a major author has a better chance of a long life), Cortex-Debug from marus25 (there are no alternatives yet) and Makefile Tools from Microsoft (it analyzes the Makefile and configures IntelliSense itself, I’ve been waiting for such a thing for a long time, at least write it yourself).

The easiest way to get a blueprint for a project is to build it in CubeMX. The process is intuitive, described hundreds of times on the net, so I will not be distracted by it. There are a couple of important points to note.

Do not forget to enable the debug bus in the port settings

A very pessimistic mistake. By default, all pins are transferred to the input and after the first firmware the programmer falls off. Since all beginners have a programmer – a Chinese minimum clone, there is no reset for STM32 and what to do next is not clear to everyone.

The solution is quite simple – you need to fix an annoying error and start the programming or erasing process while holding the reset button. Release the reset when the program will retry. It may not work the first time, but it will definitely work out. The other day, they suggested a way – to switch the download jumpers to a position other than Flash, so as not to allow our program to start and rewrite the stone from this position (I have not tried it myself).

Like me at one time, most beginners have the so-called Blue Pill at their disposal, so let’s turn on the output to which the LED is connected (PC13).

Since the LED is connected to the power supply through a resistor, we will set the output to the Open-Drain mode, although it will not be worse from Push-Pull.

I am too lazy to set up the timing, to poke a huge meaningless picture here, not to the point of meaning, but even less from the reduced meaning. In addition, CubeMX offers to set up all the coefficients by itself, and for the manual mode everything is more than intuitive.

Therefore, we finish working with CubeMX by specifying the name of the project and be sure to switch * Toolchain / IDE * on * Makefile *

After generating the project, we get the following set of files in the target directory.

Everything would be fine, but for debugging we need an SVD file, it contains information for the debugger, which is necessary for human display of peripheral registers, kernel, etc.

Where can I get this file? On the one hand, everything is quickly searched for, but it will not always be fresh versions. Best taken from ST website. We go to st.com, farther Products -> Microcontrollers & Microprocessors and we are looking for our percent there. In our case STM32 32-bit Arm Cortex MCUs -> STM32 Mainstream MCUs -> STM32F1 Series -> STM32F103

Here you can find all possible documentation on the processor, but now we are interested in the tab CAD Resources… On it we find HW Model, CAD Libraries & SVD -> System View Description… Download the found archive. For the lazy link to the page… There are several svd files in the archive. We are now interested in – STM32F103.svd… Without hesitation, we throw it into the folder with the project.

It’s time to start VSCode !!! Personally, I prefer to give the command in the right directory code., and there to each his own … The program will ask if you trust the authors of this directory, you will have to say that you trust. The Makefile Tool will parse the Makefile, which will display a lot of text in the panel, and set up IntelliSense. Not so long ago I had to configure it manually, not difficult, but not interesting.

Don’t forget to save the Workspace !!!

Now we add a little bit to the Makefile – adding one more target prog

prog: $(BUILD_DIR)/$(TARGET).elf
    openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c "program build/$(TARGET).elf verify exit reset"

A little explanation. Scripts interface / stlink-v2.cfg and target / stm32f1x.cfg allow openocd to know through which adapter and with whom it should work. The scripts themselves are located in the directory scripts with openocd installed (for Windows) or in the directory / usr / share / openocd on Linux. The above example works for the Chinese clone of ST-Link v2 and the Blue Pill. If you have another programmer or stone, you will find the necessary files in the same directories.

Actually, why is this baida needed? Sometimes you need to write a program to the processor without running debugging – just write it down and see what happens. This is what he is responsible for -c “program build / $ (TARGET) .elf verify exit reset

The next step is to set up git, but that’s to my liking. Well, how I set it up, create a file * .gitignore * well and initialize the repository. Example .gitignore

    DSP/
    Templates/
    Examples/
    NN/
    /build/
    *.log
    *.d
    .mxproject
    *.ioc

I will explain only the catalog according to the list build – the project is assembled into it, so in order not to be distracted by it and accidentally shit into committing it and ignore it. Logi loves to create Makefile Tools, I don’t need them either.

If your hands itch very much, then at this stage you can already give the command `make prog` in the VSCode terminal, your empty project will be assembled and written to the processor. The build process will be displayed here in the terminal, and openocd will tell you about a successful write like this

...
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : clock speed 1000 kHz
Info : STLINK V2J37S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.169781
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000c74 msp: 0x20005000
** Programming Started **
Info : device id = 0x20036410
Info : flash size = 64kbytes
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked

Those who wish scratched their hands, we continue. In the catalog .vscode project you need to create a file tasks.json about the same content

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build",
            "type": "shell",
            "group": "build",
            "command": "make",
            "problemMatcher": []
        },
        {
            "label": "Clean",
            "type": "shell",
            "group": "build",
            "command": "make clean",
            "problemMatcher": []
        },
        {
            "label": "Write firmware",
            "type": "shell",
            "command": "make prog",
            "problemMatcher": []
        }
    ]
}

Actually, three tasks are declared here: building the project, cleaning the working directory and flashing the controller. You can, of course, write down all the commands with parameters here, I did it before, but then it became too lazy to duplicate the commands, to make sure that they were the same in the Makefile and here … Well, in general, I stopped at this option. It works …

Now we create launch.json c with this content

{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "openocd",
			"type": "cortex-debug",
			"request": "launch",
			"cwd": "${workspaceRoot}",
			"servertype": "openocd",
			"executable": "./build/Habr.elf",
			"svdFile": "STM32F103.svd",
			"configFiles": [
				"interface/stlink-v2.cfg",
				"target/stm32f1x.cfg"
			],
			"preLaunchTask": "Build"
		}
	]
}

A terrible thing. Actually “name” can have any value, it only affects the display. Field “executable” the file into which your program is going should be set, indicating the path from the project directory. You have it your own, so instead of Habr should be what you equal TARGET = v Makefile… V “svdFile” we register the svd file of our processor. If you put it not in the root of the project, then you need to specify the path from the project directory. V “configFiles” we indicate the very scripts that we added to Makefile for controller firmware. And the last moment “preLaunchTask”: “Build” – launching the program build task from tasks.json, so that there would be something to flash and debug.

And now the moment without which all this stuff does not work – you need to tell the program where the openocd and gdb binaries are located, and not the paths to the directories with them, but the programs themselves. You need to do this in the global file settings.json, while it works so stably. Since this file itself is slightly buried, moreover, in Linux and Windows it is located in different places, I found for myself an easy way to open it. Let’s go File -> Settings -> Options, a tab with settings will open. Further Text editor -> Font and looking for an inscription Edit in settings.json… In the file that opens, add the following lines

"cortex-debug.armToolchainPath": "usr/bin",
"cortex-debug.openocdPath": "/usr/bin/openocd",
"cortex-debug.gdbPath": "/usr/bin/gdb-multiarch",

“cortex-debug.armToolchainPath” – just the path to the directory where your * arm-none-eabi-gcc *, here is just a directory

“cortex-debug.openocdPath” – full path to the openocd binary, for Windows it will end with .exe

“cortex-debug.gdbPath” – full path to the gdb binary you will be using

Well, the home stretch.

In file * main.c * slightly change the function * main () * on this

int main(void)
{
  uint32_t tempTick;
 
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();

  __ASM("NOP");
  while (1)
  {
    tempTick = HAL_GetTick();
    while (HAL_GetTick() - tempTick < 500);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1);
    tempTick = HAL_GetTick();
    while (HAL_GetTick() - tempTick < 500);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0);
  }
}

To be honest, I couldn’t come up with more terrible code on the fly. I just want to show that THIS ALL can live.

Now on __ASM (“NOP”); set a breakpoint, go to “Start and Debug” and start all this stuff by clicking on the green triangle.

In the Terminal, the inscriptions of the compilation process ran and after a couple of seconds everything stopped at this picture

** CONGRATULATIONS, YOU ARE IN DEBUGGING !!! **

You can just click F5 or play icon and enjoy the blinking LED!

That’s all for me! I could also tell you about the IntelliSense setup, but firstly it is so good and so in bulk, and secondly, the problem is already partially solved by the plugin Makefile Tools, although not ideal yet, but enough for a start.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *