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 like Eclipse and GDB is really not that user-friendly: debugging threads and tasks is a pain compared to commercial solutions. For my university classes this semester I was looking for something easy to use for my students. Finally I managed to use a GDB helper which makes things easier: I can switch task threads in Eclipse with GDB now :-)
Switched to Shell Task
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:
Stopped FreeROTS Application
What I need is an easy way to inspect the other tasks or 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 and download from Wittenstein. They show tasks, queues, and timers, but they do not allow to switch to a given task stack.
Task Table in High Integrity System Plugin
- 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.
Multiple Threads with Code Confidence Plugin
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 and 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:
Processor Expert Component to turn on GDB Helper
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 and 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):
Genereated Files with GDB Script
By default, the .* files are not visible in an Eclipse project. I need to customize the view to de-filter the .* resources:
Eclipse Project Filter Settings
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:
Debugger Settings and Commands
When I stop the target, I switch to the GDB console (click on arm-none-eabi-gdb or select it in the Console view):
GDB console View
In the console, I use
to show all the tasks with their task handles:
I switch to the task with that handle:
Switched to Shell Task
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 the execution, make sure you switch back to the context where we have stopped execution. For this use:
Restored Context with freertos_restore_running_context
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 it can be adopted or changed easily.
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 can 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 to find a nice GDB front end or something I can add buttons easily to Eclipse without writing a plugin? Anyone have an idea? Maybe we could together build an open source plugin? Looking for volunteers :-).