Image of an arrow

Easy Debugging Zephyr with VSCode

Avatar

lbeaufils

Author : Luc Beaufils, Embedded Systems Engineer

 

Debugging MCUs has always been the key to producing high-quality code, but reliance on vendor-specific IDEs and complex debug server configurations can hinder a smooth development workflow.

While VSCode has revolutionized the way developers write and debug code, setting up a debug session for MCUs can sometimes turn into a challenging task.

Thanks to the Zephyr west tool and some VSCode extensions, setting a debugging session has never been easier.

In this post, we will make the VSCode configuration to run west debugserver, which is in charge of setting a debug runner, and connect it to the VSCode IDE with the Cortex-Debug extension.

Prerequisites

For debugging Zephyr application through VSCode you’ll need to install the powerful Cortex-Debug extension. Also, the Zephyr SDK should be installed. Please follow the Getting Started Guide if you haven’t installed it.

Easy setup with West debugserver

The west debugserver command is very helpful to set up a minimal debug environment, as it run runners with the appropriate configuration for your board and can be used generically with any Zephyr supported board. The runners may be openocd, jlink, pyocd or others, depending on your board support.

With these two following steps, you will be able to run a debug session with VSCode:

  1. Create a task in your tasks.json file to run west debugserver.
  2. Create a launch.json file to configure Cortex-Debug.

For this example, we will use the STM32L562E_DK board as it supports west debugserver out of the box.

West debugserver task

The default runner of this board is pyocd, but an external package needs to be installed to use it. Due to this, we will set openocd as the runner, which is already installed with the Zephyr SDK. First, you have to create a VSCode task to run west debugserver in the background. In your tasks.json file, add the following task:

json
{
"label": "West Debugserver",
"type": "shell",
"command": "west",
"args": [
"debugserver",
"-r",
"openocd"
],
"problemMatcher": {
"pattern": {
"regexp":
"^(Info |Warn |Error):(.*)$",
"severity": 1,
"message": 2
},
"background": {
"activeOnStart": true,
"beginsPattern": "^Open On-Chip Debugger.*",
"endsPattern": ".*watchpoints.*",
},
},
"isBackground": true,
"runOptions": {
"instanceLimit": 1,
"instancePolicy": "terminateOldest"
},
"presentation": {
"reveal": "silent",
"close": true,
},
},

Some explanations about the configuration:

  • args : The -r option specifies the runner to use, in this case, openocd.
  • problemMatcher : This is used to parse the output of the west debugserver command and display it in the Problems panel. In our case, it matches the openocd output. If another runner is used, you may need to adjust the regex patterns.
  •  runOptions: As west debugserver opens a server, we don’t want to have port conflicts, so only one instance of the task can run at a time.
  • presentation: This is used to control the output of the task in the terminal. In this case, we want to reveal the output silently and close it after the task is finished.

Now the task is ready to use. You can try to run it by pressing Ctrl+Shift+P, selecting the Tasks: Run Task command and selecting the West Debugserver or whatever label you have given to the task.

Another small task is needed to stop the west debugserver task when you are done debugging. Otherwise, it will keep running in the background. You can add the following task to your tasks.json file:

json
{
"label": "Stop Debugserver",
"type": "process",
"command": "${command:workbench.action.tasks.terminate}",
},

 

Here, the command will open an input box to select the task to terminate.

And that’s it for the tasks.json file!

Cortex-Debug configuration

The Cortex-Debug will now make the link between the debugserver and the VSCode debugging interface. To do this, you need to create a launch.json file in the .vscode directory of your project.

Add this configuration to your launch.json file:

json
{
"version": "0.2.0",
"configurations": [
{
"name": "Zephyr Debugging",
"executable": "${workspaceFolder}/build/zephyr/zephyr.elf",
"request": "launch",
"type": "cortex-debug",
"runToEntryPoint": "main",
"servertype": "external",
"gdbPath": "/opt/sdk-0.17.0/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb",
"gdbTarget": "localhost:3333",
"device": "STM32L562E_DK",
"preLaunchTask": "West Debugserver",
"postDebugTask": "Stop Debugserver"
}
]
}

 

Some explanations about the configuration:

  • executable: This is the path to the ELF file generated by the Zephyr build system. By default, the build directory is build/zephyr/zephyr.elf, but you can change it if you have a different build directory.
  •  runToEntryPoint: This option specifies the entry point to run to when starting the debug session. In this case, it is set to main.
  • gdbPath: The gdb path is set to the Zephyr SDK’s GDB executable.
  • preLaunchTask and postDebugTask: these options specify the tasks we created just before. The name should be the same as task’s label.

The VSCode debugging session is now ready to be launched. You can add some breakpoints to your code and try running the debug session by pressing F5 or selecting the session by pressing Ctrl+Shift+D and clicking on the green play button.

Special case: Attach debugger to running target

Sometimes, target cannot support a reset when starting a debugging session.

We have dealt with this behavior when supporting the Cortex-M33 of the STM32MP2 board.

Thus, the VSCode configuration has been slightly changed to attach the debugger to the running target instead of reset and run the code. In the tasks.json file, the West Debugserver task is updated as follows:

json
{
"label": "West Debugserver",
"type": "shell",
"command": "west",
"args": [
"debugserver",
"-r",
"openocd",
"--no-init",
"--cmd-reset-halt",
"''",
],
"problemMatcher": {
"pattern": {
"regexp": "^(Info |Warn |Error):(.*)$",
"severity": 1,
"message": 2
},
"background": {
"activeOnStart": true,
"beginsPattern": "^Open On-Chip Debugger.*",
"endsPattern": ".*watchpoints.*",
},
},
"isBackground": true,"runOptions": {
"instanceLimit": 1,
"instancePolicy": "terminateOldest"
},
"presentation": {
"reveal": "silent",
"close": true,
}
},

Only the args parameter is updated to ask the west debugserver to not reset the target when launching the task. Accordingly, the launch.json file is also modified to permit VSCode to attach the debugger:

json
{
"name": "Attach Zephyr Debugging",
"executable": "${workspaceFolder}/build/zephyr/zephyr.elf",
"request": "attach",
"type": "cortex-debug",
"runToEntryPoint": "main",
"servertype": "external",
"gdbPath": "/opt/sdk-0.17.0/arm-zephyr-eabi/bin/arm-zephyr-eabi-gdb",
"gdbTarget": "localhost:3334",
"device": "STM32MP2",
"preLaunchTask": "West Debugserver",
"postDebugTask": "Stop Debugserver",
},

 

The request parameter is updated to attach the debugger.

Also the gdb port is set to 3334, because the stm32mp2 SoC has multiple architecture, so the debugserver set by default the Cortex-M33 to the 3334.

Conclusion

As you can see, setting up a debug environment for Zephyr development is trivial, thanks to the tools provided by the RTOS and the full-featured VSCode extension Cortex-Debug.

Feel free to use the configuration for running or attaching a debug session!

Find the config on GitHub : Main branch 

 

 

Laisser un commentaire

Votre adresse courriel ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire le pourriel. En savoir plus sur comment les données de vos commentaires sont utilisées.


Articles similaires

Image of an arrow

L’année 2024 a été particulièrement riche pour Savoir-faire Linux. Nous avons eu l’opportunité de participer à des événements clés dans les secteurs de l’énergie et de l’embarqué. Nous avons construit de nouveaux partenariats et renforcé notre position dans la communauté Open Source. Nous avons également eu le plaisir de sponsoriser deux événements cette année : le […]

En continuant nos rétrospectives de 2023, nous souhaitons mettre en lumière les contributions que nous avons apportées tout au long de l’année aux divers projets open source que nous utilisons quotidiennement pour nos besoins et ceux de nos clients, ou auxquels nous sommes stratégiquement impliqués par leur développement ou leur maintenance. En tant que membre […]

Bonjour ! Je m’appelle Emma Falkiewitz et j’ai 21 ans.‌‌ Je suis en 4ᵉ année d’école d’informatique à l’université de technologie de Compiègne (l’UTC) en France. Je viens de terminer mon stage à Savoir-faire Linux où j’ai travaillé sur Jami. Comment t’est venu ce choix de carrière ? Au lycée, j’étais déjà intéressée par l’informatique, […]

[L’introduction est en français, le reste du texte en anglais] 2023 fut une année très prolifique pour Savoir-faire Linux, et à l’occasion de notre participation et de notre sponsorisation du LF Energy Summit 2024, nous souhaitions partager une rétrospective des conférences auxquelles nous avons participé en 2023. Grâce à nos investissements en R&D ainsi que […]

Salle Shuli Goodman

Notre vie personnelle et professionnelle est souvent jalonnée de rencontres avec des femmes et des hommes qui nous ont marqués et inspirés, que ce soit par leurs compétences, leur engagement social ou politique, leur vision, leur leadership… Nous avons cette tradition chez Savoir-faire Linux qui est de rendre hommage à certaines de ces personnalités remarquables […]