FreeRTOS is probably the most popular RTOS used and I love it: it is efficient, has a lot of features, simple and easy to use. But despite its popularity, debugging it with open source tools as with Eclipse and GDB is really not that user-friendly: debugging threads/tasks is a pain compared to commercial solutions. For my university classes this semester I was looking for something easy to use by my students. Finally I managed to use a GDB helper which makes things easier now: I can switch task threads in Eclipse with GDB now 🙂
The problem is: when I stop my running FreeRTOS application, it is very likely that it stops in the IDLE task, and only that idle task is shown in the Debug view:
What I need is an easy way to inspect the other tasks/stacks.
FreeRTOS Eclipse GDB Plugins
There are two plugins I’m aware of which ease the debugging with FreeRTOS in Eclipse:
- Wittenstein/High Integrity System Plugins (see DIY Free Toolchain for Kinetis: Part 5 – FreeRTOS Eclipse Kernel Awareness with GDB): free-of-charge, but not open source, need to register/download from Wittenstein. They show tasks/queues and timers. But do not allow to switch to a given task stack.
- Plugin from Code Confidence (http://www.codeconfidence.com/freertos-tools.shtml). This is not open source and not free-of-charge (100 GBP per developer seat, so out of reach for our classes). Additionally, it requires a special launch configuration, so the GNU ARM Eclipse launches are not supported. There is a demo mode which allows 2 threads, and debugging is terminated after 2 minutes.
FreeRTOS GDB Task Backtrace Switcher
I searched the internet for something what would help me to see the task stacks/threads, and have found a cool contribution in the FreeRTOS community under contributed ports (http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support-): it is an excellent example how GDB commands can be used to customize debugging :-).
The approach has two parts:
- A custom FreeRTOS vPortPendSVDHandler()
- A GDB script with custom commands to show and switch threads
The GDB script is using/setting variables which are then used by the GDB script to switch context. That’s actually a really cool idea, and I got that approach working quickly.
FreeRTOS Port Integration
To make it even easier to use, I have integrated that approach into the FreeRTOS Processor Expert component. So with a simple setting I can turn on that custom handler:
That setting turns on a custom FreeRTOS configuration I have added to FreeRTOSConfig.h:
/*----------------------------------------------------------- * GDB <span data-mce-bogus="1" class="mceItemHidden"><span class="hiddenSpellError" pre="GDB " data-mce-bogus="1">backtrace</span></span> handler support * See http://interactive.freertos.org/entries/23468301-Tasks-<span class="hiddenSpellError" pre="stack " data-mce-bogus="1">backtrace</span>-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support- *----------------------------------------------------------*/ #define configGDB_HELPER (1 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC)) /* 1: enable special GDB stack backtrace debug helper; 0: disabled */
With that define, I can turn it on/off easily without Processor Expert too. The component copies the GDB script as
Enable the GDB Helper option in the settings. It will create the GDB script plus a help text file (just in case you do not remember this blog article :-)):
💡 By default, the .* files are not visible in an Eclipse project. I need to customize the view to de-filter the .* resources:
I need to add the custom gdb commands from the .gdbinit-FreeRTOS-helpers script file.
💡 With GDB and the GNU ARM Eclipse plugins, the current directory of GDB is the project root folder. Otherwise you need to specify the full path to make sure GDB finds the file.
I can do this with the ‘source’ command in the in the debug/launch configuration so it executed every time I start the debugger in Eclipse:
When I stop the target, I switch to the GDB console (click on arm-none-eabi-gdb or select it in the Console view):
In the console, I use
to show all the tasks with their task handles:
I switch to the task with that handle:
Now I can inspect the call chain of that thread.
IMPORTANT: do not step, only inspect the stack. More about this later.
The same way I can inspect other task stacks or to set breakpoints in tasks.
Before resuming execution, make sure you switch back to the context where we have stopped execution. For this use
How it works
It is important to understand what happens with the
command in .gdbinit-FreeRTOS-helpers:
- It writes the task handle to a global variable
- Triggers a PendSV exception to call the custom PendSV handler
- The custom PendSV handler will stop on a brkt (breakpoint) instruction to stop the debugger
- The script will do to instruction steps and the stop to show the thread stack
So it is important to understand that the script actually executes code on the target. That’s why it is important not to continue stepping inside a switched context unless you know that you do! Basically switching context actually really switches the context through the GDB debugger.
That GDB helper works fine for me, and makes debugging a FreeRTOS application much easier. Best of all: it does not need a plugin, but works with normal GDB commands so can be adopted/changed easily too.
All the sources are available on GitHub. Consult the links at the end of the article. The FreeRTOS component will be available with the next release on SourceForge. If you want to get and try the current .PEupd file before the ‘official’ release, contact me by email (see About), and I make it available.
What could be next?
- Add support for Cortex-M0+ (I have it tested with Cortex-M4(F))
- Add a feature that I can specify the task name instead of the task handle address for context switching
I was hoping as well to find a nice GDB front end or something I can add buttons easily to Eclipse without writing a plugin? Anyone has an idea? Maybe we could together build an open source plugin? Looking for volunteers :-).
Happy Tasking 🙂
- FreeRTOS web site: http://www.freertos.org/
- Wittenstein Eclipse plugins: http://www.highintegritysystems.com/
- Code Confidence FreeRTOS Plugin: http://www.codeconfidence.com/freertos-tools.shtml
- FreeRTOS Community contribution of GDB Task Backtrace: http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support-
- GDB Task Backtrace Helper Files on GitHub: https://github.com/ErichStyger/McuOnEclipse_PEx/tree/master/Drivers/freeRTOS/gdbBacktraceDebug
- FreeRTOS port file with custom GDB Task Backtrace handler integrated: https://github.com/ErichStyger/McuOnEclipse_PEx/blob/master/Drivers/freeRTOS/port.c