Adding FreeRTOS Thread Awareness to GDB and Eclipse

Segger has released a beta version of the J-Link software which includes their GDB thread awareness for embOS and FreeRTOS :-).

FreeRTOS Thread Aware Debugging

FreeRTOS Thread Aware Debugging

Outline

I had a first chance to try this plugin at NXP FTF 2016 in Austin (see “FreeRTOS Thread Debugging with Segger GDB in Eclipse“). Now that feature is included in the latest Segger beta download.

This article describes the steps how to use it with the NXP Kinetis Design Studio (V3.2.0) with the GNU ARM Eclipse plugins. Similar steps can apply for other Eclipse distributions with GDB. A similar feature is present in OpenOCD (see “FreeRTOS Thread Debugging with Eclipse and OpenOCD“).

Installation

Download the latest Segger J-Link software version from the Segger site: https://www.segger.com/jlink-software.html. Currently it is available on the beta site (V5.41h). Then run the setup. A dialog will ask to update existing IDE’s using Segger J-Link software on Windows:

Update J-Link DLL

Update J-Link DLL

For Mac OS X and Linux you have to copy the necessary files from the installation folder. The RTOS thread awareness is using DLLs/libraries from the ‘GDBServer’ subfolder.

Segger GDB Server Plugins

Segger GDB Server Plugins

In the beta installer, that GDBServer folder is not copied into Kinetis Design Studio (subfolder ‘segger’ inside KDS). I recommend to manually copy that folder into the ‘segger’ subfolder of KDS:

GDB Server Folder in KDS

GDB Server Folder in KDS

Using the FreeRTOS Plugin

To use the FreeRTOS plugin, specify which RTOS plugin to load with:

-rtos GDBServer/RTOSPlugin_FreeRTOS

💡 The path is relative to the Segger GDB server. If you have located the plugins elsewhere, you have to adopt the path.

Below shows the command in the debug launch configuration for GDB and Segger using the GNU ARM Eclipse plugin:

Setting in Segger J-Link Launch Configuration

Setting in Segger J-Link Launch Configuration

With this, it shows the RTOS threads in the GDB debug view under Eclipse while debugging:

FreeRTOS Thread Aware Debugging

FreeRTOS Thread Aware Debugging

Trouble Shooting

The implementation checks and accesses several symbols of FreeRTOS, for example:

Received symbol: pxCurrentTCB (20003A7C)
Received symbol: pxReadyTasksLists (20003A80)
Received symbol: xDelayedTaskList1 (20003AF8)
Received symbol: xDelayedTaskList2 (20003B0C)
Received symbol: pxDelayedTaskList (20003B20)
Received symbol: pxOverflowDelayedTaskList (20003B24)
Received symbol: xPendingReadyList (20003B28)
Received symbol: xTasksWaitingTermination (00000000)
Received symbol: xSuspendedTaskList (20003B3C)
Received symbol: uxCurrentNumberOfTasks (20003B50)
Received symbol: uxTopUsedPriority (2000002C)
Received symbol: vPortEnableVFP (0000FE24)

I had faced a problem where at high compiler optimization level the function vPortEnableVFP() was inlined. I have fixed that in my FreeRTOS port with a noinline attribute so it works with highest optimization too:

void __attribute__ ((noinline)) vPortEnableVFP(void) {

Summary

The Segger RTOS plugin provides a very convenient way to debug FreeRTOS (or Segger emBOS) threads with Eclipse and GDB using a Segger J-Link debug probe. A native J-Link or an embedded J-Link probe like OpenSDA on the NXP Freedom boards. It greatly simplifies the debug experience, and after using it I don’t know how I was able to debug RTOS applications before ;-).

Happy Threading 🙂

16 thoughts on “Adding FreeRTOS Thread Awareness to GDB and Eclipse

    • Hi Peter,
      I have solved that problem in my FreeRTOS port with:
      void vPortStartFirstTask(void) {
      #if 1 /* only needed for openOCD thread awareness. It needs the symbol uxTopUsedPriority present after linking */
      {
      extern volatile const int uxTopUsedPriority;
      __attribute__((__unused__)) volatile uint8_t dummy_value_for_openocd;
      dummy_value_for_openocd = uxTopUsedPriority;
      }
      #endif
      __asm volatile (
      ” ldr r0, =0xE000ED08 \n” /* Use the NVIC offset register to locate the stack. */
      ” ldr r0, [r0] \n” /* load address of vector table */
      ” ldr r0, [r0] \n” /* load first entry of vector table which is the reset stack pointer */
      ” msr msp, r0 \n” /* Set the msp back to the start of the stack. */
      ” cpsie i \n” /* Globally enable interrupts. */
      ” svc 0 \n” /* System call to start first task. */
      ” nop \n”
      );
      }

      That way I don’t have to change the linker settings 🙂

      Erich

      Like

  1. Erich, I’m very excited to try this, but we’re using stock Eclipse and I didn’t see that pop up as an option with the prompt to “update existing IDE’s using Segger J-Link software”.
    Any suggestions here?

    Like

    • Hi Joe,
      I assume you are using the GNU ARM Eclipse plugins in your stock Eclipse? Then it is not necessary to update the IDE, as with this your launch configuration should use something like this
      ${jlink_path}/${jlink_gdbserver}
      to point to the Segger files. These variables are usually configured under Window > Preferences > Run/Debug > String Substitution.
      Just make sure they point to your J-Link software with the FreeRTOS plugins/version.

      Like

      • Erich,
        Thanks for the reply. We have it debugging now, but it is not showing the multiple threads. Note that our project currently uses 4 tasks. We analyzed the debugger Console and found the following error:

        Received symbol: uxTopUsedPriority (00000000)
        ERROR: Mandatory symbol uxTopUsedPriority not found.

        Researching online tells us that uxTopUsedPriority is a symbol is no longer used with the latest version of FreeRTOS. It appears to now use uxTopReadyPriority instead. But, we’re not sure how to get the debugger to use this new symbol. Any suggestions?

        Like

        • No, the symbol uxTopUsedPriority has to be present.
          You can add this to your sources:
          /* This is only really needed for debugging with openOCD:
          * Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer
          * present in the kernel, so it has to be supplied by other means for
          * OpenOCD’s threads awareness.
          *
          * Add this file to your project, and, if you’re using –gc-sections,
          * “–undefined=uxTopUsedPriority” (or
          * “-Wl,–undefined=uxTopUsedPriority” when using gcc for final
          * linking) to your LDFLAGS; same with all the other symbols you need.
          */
          volatile const int
          #ifdef __GNUC__
          __attribute__((used))
          #endif
          uxTopUsedPriority = configMAX_PRIORITIES;

          I hope this helps,
          Erich

          Like

      • Well, unfortunately that didn’t get us any farther. We’re currently unfamiliar with –gc-sections and LDFLAGS, but tried adding a few combinations to the makefile without success. We’re relatively new to the whole makefile concept. So, I’m guessing it’s something very basic that we’ve missed. If you have any further suggestions, we’d love to try them.

        As always, thanks for all your articles. I’ve found them very helpful.

        Like

        • Hi Joe,
          maybe this helps, I had added the thing in #if 1 … #endif below to make sure the symbol is referenced:
          void vPortStartFirstTask(void) {
          #if 1 /* only needed for openOCD thread awareness. It needs the symbol uxTopUsedPriority present after linking */
          {
          extern volatile const int uxTopUsedPriority;
          __attribute__((__unused__)) volatile uint8_t dummy_value_for_openocd;
          dummy_value_for_openocd = uxTopUsedPriority;
          }
          #endif
          __asm volatile (
          ” ldr r0, =0xE000ED08 \n” /* Use the NVIC offset register to locate the stack. */
          ” ldr r0, [r0] \n” /* load address of vector table */
          ” ldr r0, [r0] \n” /* load first entry of vector table which is the reset stack pointer */
          ” msr msp, r0 \n” /* Set the msp back to the start of the stack. */
          ” cpsie i \n” /* Globally enable interrupts. */
          ” svc 0 \n” /* System call to start first task. */
          ” nop \n”
          );
          }

          Like

  2. Hello,

    Could you tell me what the advantages are of this implementation compared to systemview? (No ram footprint, and more info on the execution state of a thread?)

    I’ve been reading your articles for a little while now, and they are great! Keep up the great work!

    Kind regards,

    Diederik

    Like

  3. Pingback: First steps: ARM Cortex-M7 and FreeRTOS on NXP TWR-KV58F220M | MCU on Eclipse

  4. Pingback: McuOnEclipse Components: 31-July-2016 Release | MCU on Eclipse

  5. Erich,

    Thank you for sharing this! We have successfully loaded all the symbols and can debug, pause and resume, but when we pause we do not see all the task threads. We only see the active thread. In addition in the console of Eclipse we see “ERROR: Null stack pointer in task.” and a number of “WARNING: Mis-aligned memory read: …”. Any ideas what could be wrong with our setup? We are running on Macbooks with macOS and using J-Link Plus debuggers with the latest software from Segger. We are compiling our target with GNU ARM GCC and debugging with a .elf file.

    Thanks,

    Kelly

    Like

    • Hi Kelly,
      are you using the McuOnEclipse port of FreeRTOS? I ask because I have added a few tweaks. One thing is to have the task stacks properly terminated. I recommend to set configTASK_RETURN_ADDRESS to zero:

      #define configTASK_RETURN_ADDRESS 0

      in FreeRTOSconfig.h
      What Cortex are you using? The M0+ would hardfault with a misagligned stack, but the M4 would do two fetches (not good for performance). Are you sure your task stacks are properly aligned? The usual ports ensure this, but I’m not sure what port you are using?

      I hope this helps,
      Erich

      Like

      • Hi Erich,

        We are using Nordic’s nRF52 which is an M4 and their port of FreeRTOS provided in their SDK. It is possible their port has some minor issues. I will try your suggestions and investigate more later today when I get a chance.

        Thanks,

        Kelly

        Like

  6. Pingback: Troubleshooting Tips for FreeRTOS Thread Aware Debugging in Eclipse | MCU on Eclipse

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.