[SOLVED] SEGGER FreeRTOS plugin with FreeRTOS v10.0.0 (no thread found)

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [SOLVED] SEGGER FreeRTOS plugin with FreeRTOS v10.0.0 (no thread found)

    I am trying to test SEGGER FreeRTOS plugin with Nordic SDK v15.0's example `blinky_freertos` on nRF52840 DevKit. Nordic says they use an unmodified version of FreeRTOS V10.0.0 in their SDK v15.0. The example is pretty simple 1 RTOS task, 1 RTOS periodical timer.

    I was excepted to see all FreeRTOS tasks with this plugin. I am using the latest SEGGER (V6.34b (DLL compiled Aug 13 2018 16:38:47))

    I started SEGGER GDBServer: /opt/SEGGER/JLink/JLinkGDBServer -Device nrf52840_XXAA -If SWD -Speed 4000 -rtos /opt/SEGGER/JLink/GDBServer/RTOSPlugin_FreeRTOS.so

    It seems to start correctly:

    Source Code

    1. -----GDB Server start settings-----
    2. GDBInit file: none
    3. GDB Server Listening port: 2331
    4. SWO raw output listening port: 2332
    5. Terminal I/O port: 2333
    6. Accept remote connection: yes
    7. Generate logfile: off
    8. Verify download: off
    9. Init regs on start: off
    10. Silent mode: off
    11. Single run mode: off
    12. Target connection timeout: 0 ms
    13. ------J-Link related settings------
    14. J-Link Host interface: USB
    15. J-Link script: none
    16. J-Link settings file: none
    17. ------Target related settings------
    18. Target device: nrf52840_XXAA
    19. Target interface: SWD
    20. Target interface speed: 4000kHz
    21. Target endian: little
    22. Connecting to J-Link...
    23. J-Link is connected.
    24. Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Jul 12 2018 11:44:41
    25. Hardware: V1.00
    26. S/N: 683670808
    27. Checking target voltage...
    28. Target voltage: 3.30 V
    29. Listening on TCP/IP port 2331
    30. Connecting to target...Connected to target
    31. Waiting for GDB connection...Connected to 127.0.0.1
    Display All





    And then I connected GDB to the GDB server with my ELF file: arm-none-eabi-gdb _build/nrf52840_xxaa.out --eval-command='target remote localhost:2331'

    I can see in GDB server:

    Source Code

    1. Reading all registers
    2. Read 4 bytes @ address 0x000006C0 (Data = 0x4100F8D2)
    3. Reading 64 bytes @ address 0x20000800
    4. Read 4 bytes @ address 0x000017F0 (Data = 0xBF00E7EC)
    5. Loading RTOS plugin: /opt/SEGGER/JLink/GDBServer/RTOSPlugin_FreeRTOS.so...
    6. RTOS plugin (API v1.0) loaded successfully
    7. RTOS plugin initialized successfully.
    8. Received symbol: pxCurrentTCB (0x20001094)
    9. Received symbol: pxReadyTasksLists (0x200010A0)
    10. Received symbol: xDelayedTaskList1 (0x200010F4)
    11. Received symbol: xDelayedTaskList2 (0x20001108)
    12. Received symbol: pxDelayedTaskList (0x20001098)
    13. Received symbol: pxOverflowDelayedTaskList (0x2000109C)
    14. Received symbol: xPendingReadyList (0x20001128)
    15. Received symbol: xTasksWaitingTermination (0x20001154)
    16. Received symbol: xSuspendedTaskList (0x20001140)
    17. Received symbol: uxCurrentNumberOfTasks (0x200010DC)
    18. Received symbol: uxTopUsedPriority (0x00000000)
    19. Received symbol: uxTopReadyPriority (0x200010F0)
    20. Received symbol: vPortEnableVFP (0x00000000)
    21. Received symbol: FreeRTOSDebugConfig (0x00000000)
    22. All mandatory symbols successfully loaded.
    23. Reading all registers
    Display All
    And in GDB it sees only one thread (the idle task):

    Source Code

    1. Remote debugging using localhost:2331
    2. vPortSuppressTicksAndSleep (xExpectedIdleTime=200) at ../../../../../../external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    3. 255 } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));
    4. (gdb) where
    5. #0 vPortSuppressTicksAndSleep (xExpectedIdleTime=200) at ../../../../../../external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    6. #1 0x000017f0 in prvIdleTask (pvParameters=<optimized out>) at ../../../../../../external/freertos/source/tasks.c:3321
    7. #2 0x0000050c in ?? ()
    8. Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    9. (gdb) info threads
    10. Id Target Id Frame
    11. * 1 Thread 57005 vPortSuppressTicksAndSleep (xExpectedIdleTime=200) at ../../../../../../external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    Display All



    As you might notice there are few mandatory symbols that are NULL:

    Source Code

    1. Received symbol: uxTopUsedPriority (0x00000000)
    2. Received symbol: vPortEnableVFP (0x00000000)
    3. Received symbol: FreeRTOSDebugConfig (0x00000000)

    For your information here is the source code of the example:

    C Source Code

    1. #include <stdbool.h>
    2. #include <stdint.h>
    3. #include "FreeRTOS.h"
    4. #include "task.h"
    5. #include "timers.h"
    6. #include "bsp.h"
    7. #include "nordic_common.h"
    8. #include "nrf_drv_clock.h"
    9. #include "sdk_errors.h"
    10. #include "app_error.h"
    11. #if LEDS_NUMBER <= 2
    12. #error "Board is not equipped with enough amount of LEDs"
    13. #endif
    14. #define TASK_DELAY 200 /**< Task delay. Delays a LED0 task for 200 ms */
    15. #define TIMER_PERIOD 1000 /**< Timer period. LED1 timer will expire after 1000 ms */
    16. TaskHandle_t led_toggle_task_handle; /**< Reference to LED0 toggling FreeRTOS task. */
    17. TimerHandle_t led_toggle_timer_handle; /**< Reference to LED1 toggling FreeRTOS timer. */
    18. /**@brief LED0 task entry function.
    19. *
    20. * @param[in] pvParameter Pointer that will be used as the parameter for the task.
    21. */
    22. static void led_toggle_task_function (void * pvParameter)
    23. {
    24. UNUSED_PARAMETER(pvParameter);
    25. while (true)
    26. {
    27. bsp_board_led_invert(BSP_BOARD_LED_0);
    28. /* Delay a task for a given number of ticks */
    29. vTaskDelay(TASK_DELAY);
    30. /* Tasks must be implemented to never return... */
    31. }
    32. }
    33. /**@brief The function to call when the LED1 FreeRTOS timer expires.
    34. *
    35. * @param[in] pvParameter Pointer that will be used as the parameter for the timer.
    36. */
    37. static void led_toggle_timer_callback (void * pvParameter)
    38. {
    39. UNUSED_PARAMETER(pvParameter);
    40. bsp_board_led_invert(BSP_BOARD_LED_1);
    41. }
    42. int main(void)
    43. {
    44. ret_code_t err_code;
    45. /* Initialize clock driver for better time accuracy in FREERTOS */
    46. err_code = nrf_drv_clock_init();
    47. APP_ERROR_CHECK(err_code);
    48. /* Configure LED-pins as outputs */
    49. bsp_board_init(BSP_INIT_LEDS);
    50. /* Create task for LED0 blinking with priority set to 2 */
    51. UNUSED_VARIABLE(xTaskCreate(led_toggle_task_function, "LED0", configMINIMAL_STACK_SIZE + 200, NULL, 2, &led_toggle_task_handle));
    52. /* Start timer for LED1 blinking */
    53. led_toggle_timer_handle = xTimerCreate( "LED1", TIMER_PERIOD, pdTRUE, NULL, led_toggle_timer_callback);
    54. UNUSED_VARIABLE(xTimerStart(led_toggle_timer_handle, 0));
    55. /* Activate deep sleep mode */
    56. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    57. /* Start FreeRTOS scheduler. */
    58. vTaskStartScheduler();
    59. while (true)
    60. {
    61. /* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
    62. * in vTaskStartScheduler function. */
    63. }
    64. }
    Display All
  • Hello Olivier,

    FreeRTOS makes it difficult for GDB server plugins to find out the length of some task lists.

    It will work with the default configuration, but it does not, if you turn on: #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1

    So you can either turn off port optimized task selection, or you can add a "helper structure" to your project.
    This is either "uxTopUsedPriority" (simply holding the value of the highest priority) or "FreeRTOSDebugConfig" (from freertos_tasks_c_additions.h)


    Best regards
    Arne
  • Thanks Arne for your response, I have just tried out.

    - I added freertos_tasks_c_additions.h to my project

    - Added:

    C Source Code

    1. #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1
    2. #define configUSE_TRACE_FACILITY 1




    - I confirm GDB can get the symbols:

    Source Code

    1. RTOS plugin initialized successfully.
    2. Received symbol: pxCurrentTCB (0x20002D2C)
    3. Received symbol: pxReadyTasksLists (0x20002D30)
    4. Received symbol: xDelayedTaskList1 (0x20002D94)
    5. Received symbol: xDelayedTaskList2 (0x20002DA8)
    6. Received symbol: pxDelayedTaskList (0x20002DBC)
    7. Received symbol: pxOverflowDelayedTaskList (0x20002DC0)
    8. Received symbol: xPendingReadyList (0x20002DC4)
    9. Received symbol: xTasksWaitingTermination (0x20002DD8)
    10. Received symbol: xSuspendedTaskList (0x20002DF0)
    11. Received symbol: uxCurrentNumberOfTasks (0x20002E04)
    12. Received symbol: uxTopUsedPriority (0x00000000)
    13. Received symbol: uxTopReadyPriority (0x20002E0C)
    14. Received symbol: vPortEnableVFP (0x00026650)
    15. Received symbol: FreeRTOSDebugConfig (0x0002BA68)
    16. All mandatory symbols successfully loaded.
    Display All

    But I can still only see 1 thread (the idle one):

    Source Code

    1. vPortSuppressTicksAndSleep (xExpectedIdleTime=16777213) at /home/olivier/labapart/biosency/boraconnect-firmware/nrf-sdk/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    2. 255 } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));
    3. (gdb) info threads
    4. [New Remote target]
    5. Id Target Id Frame
    6. 2 Remote target vPortSuppressTicksAndSleep (xExpectedIdleTime=16777213) at /home/olivier/labapart/biosency/boraconnect-firmware/nrf-sdk/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    7. The current thread <Thread ID 1> has terminated. See `help thread'.

    FreeRTOSDebugConfig seems to contain valid information:

    Source Code

    1. (gdb) x /16xb FreeRTOSDebugConfig
    2. 0x2ba68 0x01 0x01 0x09 0x00 0x00 0x05 0x00 0x04
    3. 0x2ba70 0x18 0x30 0x34 0x38 0x3c 0x04 0x05 0x00
  • Please find attached the GDB Server log. I am using gdb in command line and the only command I use after connecting to GDB server is 'info threads' that should list the threads.

    Here are the GDB client output:

    Source Code

    1. arm-none-eabi-gdb dk1/test/blinky_freertos/dk1-blinky-freertos.elf --eval-command='target remote localhost:2331'
    2. GNU gdb (GNU Tools for Arm Embedded Processors 7-2018-q3-update) 8.1.0.20180315-git
    3. Copyright (C) 2018 Free Software Foundation, Inc.
    4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    5. This is free software: you are free to change and redistribute it.
    6. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    7. and "show warranty" for details.
    8. This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
    9. Type "show configuration" for configuration details.
    10. For bug reporting instructions, please see:
    11. <http://www.gnu.org/software/gdb/bugs/>.
    12. Find the GDB manual and other documentation resources online at:
    13. <http://www.gnu.org/software/gdb/documentation/>.
    14. For help, type "help".
    15. Type "apropos word" to search for commands related to "word"...
    16. Reading symbols from dk1/test/blinky_freertos/dk1-blinky-freertos.elf...done.
    17. Remote debugging using localhost:2331
    18. vPortSuppressTicksAndSleep (xExpectedIdleTime=16777213) at /tmp/nrf-sdk/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    19. 255 } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));
    20. (gdb) info threads
    21. [New Remote target]
    22. Id Target Id Frame
    23. 2 Remote target vPortSuppressTicksAndSleep (xExpectedIdleTime=16777213) at /tmp/nrf-sdk/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    24. The current thread <Thread ID 1> has terminated. See `help thread'.
    Display All
    Files
    • gdbserver.log

      (45.08 kB, downloaded 125 times, last: )
  • Thanks a lot it works!

    Source Code

    1. (gdb) si
    2. [New Thread 536885784]
    3. [New Thread 536885448]
    4. [New Thread 536888528]
    5. Thread 2 received signal SIGTRAP, Trace/breakpoint trap.
    6. [Switching to Thread 536885784]
    7. 0x00026878 in vPortSuppressTicksAndSleep (xExpectedIdleTime=16777213) at /tmp/nrf-sdk/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    8. 255 } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));
    9. (gdb) info threads
    10. Id Target Id Frame
    11. * 2 Thread 536885784 (IDL : Running [P: 0]) 0x00026878 in vPortSuppressTicksAndSleep (xExpectedIdleTime=16777213)
    12. at /tmp/nrf-sdk/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c:255
    13. 3 Thread 536885448 (LED [P: 2]) __ISB () at /tmp/nrf-sdk/components/toolchain/cmsis/include/cmsis_gcc.h:418
    14. 4 Thread 536888528 (Tmr [P: 4]) __DSB () at /tmp/nrf-sdk/components/toolchain/cmsis/include/cmsis_gcc.h:429
    15. (gdb)
    Display All

    I will move this ticket to SOLVED but before doing that I do not undertsand what you mean by "the threads are only updated on reset or halt."
    When I do a single step, it does not do a reset or halt but the threads are updated.
  • The plugin cannot be initialized before the GDB client sends out the "qSymbol" command, because it needs the addresses of the symbols
    first. This is a drawback of the client/server architecture, the server cannot actively request anything from the client and relies on its
    offer.

    Most of our customers use the plug-in in combination with an eclipse based IDE and use the default behavior "reset and run to main", so
    they do not experience the situation you ran into.