In this post, I will step through an example setup that shows how to debug a FreeRTOS application in the Visual Studio Code (VSCode) editor using QEMU to emulate an Arm Cortex-M3 microcontroller. No actual hardware is required for this example, except a laptop or desktop as your development environment.
First off, what is QEMU and why would we want to debug with it? QEMU is a machine emulator that allows you to virtualize hardware types, even across different architectures. This can be very helpful for embedded development because you can run applications against hardware targets that you may not have immediate access to. This might be because (a) you are still in the process of selecting a chipset for an embedded product design, (b) your boards are somewhere else like a lab, (c) you want to run automated tests without physical hardware, or (d) the real hardware is simply in short supply. If you recognize any of these constraints, and the software development must go on, then QEMU can help.
QEMU supports many different hardware platforms, from x86 to ARM to RISC-V. FreeRTOS also supports many different hardware platforms. So, it is worth pointing out that the example I will cover below is not limited to just this hardware platform for FreeRTOS. You can adapt the same methods if you have a target other than the Arm Cortex-M3.
With those considerations, how do we begin? There are a number of prerequisites and dependencies in order to get up and running with the example. I have laid these out in 7 steps below, which you can follow. The order is not that important except the last step should stay the last step. You may have some or all of these tools installed on your development machine already, so just double-check that they are up-to-date and present in your path if that is the case.
Download and install VSCode from here.
Download and install QEMU from here.
Download and install the Arm GNU Toolchain from here.
Download and install CMake from here.
For Windows, download and install Git (includes Bash terminal) from here. Git should already be installed on MacOS and Linux.
-
Make sure 'make' is installed on your system. There are different ways to do this depending on your platform.
a. On Windows, you can install 'make' using Chocolatey at the Command Prompt with this command:
> choco install make
b. On MacOS, you can install 'make' using Homebrew in the Terminal app with this command
$ brew install make
c. On Linux, you can install 'make' using the package manager from a terminal with this command:
$ sudo apt install build-essential
Add the QEMU, Arm GNU Compiler, CMake, and 'make' installation paths to your PATH environment variable. OSes and environments have different ways to do this, so use the appropriate method for your system.
Once you have the prerequisite tools installed, proceed by cloning the source code we will be working with. From the command line, navigate to a folder where you would like to clone the FreeRTOS repository with the demo code, such as $ cd $HOME/Projects
as an example. Then, go ahead and clone the FreeRTOS repository from GitHub like this:
$ git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules
When cloning the repo has finished, launch VSCode. In VSCode, select 'File > Open Folder' in the menu. Navigate to the FreeRTOS repository you just cloned and select this subfolder: '.../FreeRTOS/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC'
After VScode loads the demo folder, open '.vscode/launch.json' in the editor. Find the miDebuggerPath
parameter and change the value to the path where 'arm-none-eabi-gdb' is located on your machine.
Now open 'main.c' and make sure that mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
is set to 1
. This will generate only the simple blinky demo.
Next, press the 'Run and Debug' button from the left side panel in VSCode. Select 'Launch QEMU RTOSDemo' from the dropdown at the top and press the 'play' button. This will build the code, run the program, and attach the debugger.
From there, you can 'Continue', 'Step Over', 'Step Into', 'Step Out', and 'Stop' from the button bar. You can also add breakpoints in the code by right clicking next to the line number.
Pressing the 'Continue' button will execute the code, which will produce output like this in the Terminal:
QEMU RTOSdemo started
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from task
Message received from software timer
...
And there you have it, debugging FreeRTOS with QEMU in VSCode. You can use this example to play around and explore what is possible. Happy debugging!
Top comments (4)
Hi, pressing "Launch QEMU RTOSDemo" button showed me some issues and the project didn't compile:
However, I got the job done when starting the projecf from the menu: "Menu -> Run -> Start debugging".
Specs:
$ sudo ln -s /usr/bin/gdb-multiarch /usr/bin/arm-none-eabi-gdb
(I followed this thread.)
So far, so good. Thank you for the tuto!
Hi, Using QEMU is an excelent way for trying my article "How to create interchangeable software components for embedded systems. Decouple the logic from hardware".
In it I code components in the PC, then, when they're ready, I write the component for the corresponding hardware. Although it's unbelievable practical to test the hardware components in the PC, it would be better to test them in something closer to the hardware, like the emulator for the Cortex-M3 core.
What are the memory model constraints? I mean, is there a limit, for practical purposes, in the use of RAM/FLASH, so that the emulator behaves in such sense as a real microcontroller? (Perhaps the emulator out of the box allows you to declare something like: int arr[1000000];.)
Greetings!
Great Article. How easy it is to get the AWS port of FreeRTOS run on QEMU?
Thanks much. All of the source code for the setup is available here: github.com/FreeRTOS/FreeRTOS/tree/...
The FreeRTOS/FreeRTOS repo is maintained by AWS, so there is no separate port.