cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
njozwiak
Adventurer
Adventurer
627 Views
Registered: ‎10-19-2017

Stall debugging FreeRTOS application on R5 with gdb

Jump to solution

Hi all,

I'm having a problem debugging a FreeRTOS application on my R5 using GDB. This is a test application that spawns one task whose only job is to print a counter once a second (source file is attached).

This application runs perfectly fine when I load it and run it from remoteproc:

INFO: [main] ARM Cortex-R5 0 is running
INFO: [task_main_func] [1] main loop
INFO: [task_main_func] [2] main loop
INFO: [task_main_func] [3] main loop
...

But if I am stepping through the code with GDB, it hangs on the first call to vTaskDelay() and never returns until I halt the core.

Here are my setup steps:

1. Boot the target board and run the RPU to validate everything is functioning. (NOTE: I have included `clk_ignore_unused cpuidle.off=1` in my kernel args per AR#69143)

Linux console:

root@xilinx:~# echo rpu0_app.elf > /sys/class/remoteproc/remoteproc0/firmware 
root@xilinx:~# echo start > /sys/class/remoteproc/remoteproc0/state
[ 93.698672] remoteproc remoteproc0: powering up r5@0
[ 93.726632] remoteproc remoteproc0: Booting fw image rpu0_app.elf, size 460204
[ 93.736996] r5@0: RPU boot from TCM.
[ 93.740011] remoteproc remoteproc0: remote processor r5@0 is now up
root@xilinx:~#

RPU0 console:

INFO: [main] ARM Cortex-R5 0 is running
INFO: [task_main_func] [1] main loop
INFO: [task_main_func] [2] main loop
INFO: [task_main_func] [3] main loop
INFO: [task_main_func] [4] main loop
INFO: [task_main_func] [5] main loop
INFO: [task_main_func] [6] main loop

2. Run hw_server

$ hw_server

****** Xilinx hw_server v2019.1
  **** Build date : May 24 2019 at 15:06:40
    ** Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.

INFO: hw_server application started
INFO: Use Ctrl-C to exit hw_server application

INFO: To connect to this hw_server instance use url: TCP:laptop:3121

3. Run xsct and connect to hw_server to view the status of the cores

xsct% connect -url TCP:localhost:3121                                                                                                       
tcfchan#1
xsct% Info: Cortex-A53 #1 (target 13) Stopped at 0xfffea110 (Reset Catch)                                                                   
xsct% Info: Cortex-A53 #2 (target 14) Stopped at 0xfffea110 (Reset Catch)
xsct% Info: Cortex-A53 #3 (target 15) Stopped at 0xfffea110 (Reset Catch)
xsct% targets                                                                                                                               
  1  PS TAP
     2  PMU
     3  PL
        4  Legacy Debug Hub
           5  JTAG2AXI
           6  JTAG2AXI
  7  PSU
     8  RPU
        9* Cortex-R5 #0 (Running)
       10  Cortex-R5 #1 (Halted)
    11  APU
       12  Cortex-A53 #0 (Running)
       13  Cortex-A53 #1 (Reset Catch, EL3(S)/A64)
       14  Cortex-A53 #2 (Reset Catch, EL3(S)/A64)
       15  Cortex-A53 #3 (Reset Catch, EL3(S)/A64)

4. Connect to the board with GDB and reload to get things back to initial state for debugging the FreeRTOS application

$ arm-none-eabi-gdb armr5/debug/rpu0_app.elf
...
(gdb) target remote :3000
Remote debugging using :3000
_prestart () at boot.S:124
124		mov	r0,#0
(gdb) load
Loading section .vectors, size 0x520 lma 0x0
Loading section .text, size 0xcc88 lma 0x3ed00000
Loading section .init, size 0xc lma 0x3ed0cc88
Loading section .fini, size 0xc lma 0x3ed0cc94
Loading section .rodata, size 0x8a0 lma 0x3ed0cca0
Loading section .data, size 0x10a4 lma 0x3ed0d540
Loading section .eh_frame, size 0x4 lma 0x3ed0e5e4
Loading section .ARM.exidx, size 0x8 lma 0x3ed0e5e8
Loading section .init_array, size 0x8 lma 0x3ed0e5f0
Loading section .fini_array, size 0x4 lma 0x3ed0e5f8
Start address 0x3c, load size 60188
Transfer rate: 184 KB/sec, 3761 bytes/write.
(gdb) b task_main_func
Breakpoint 1 at 0x3ed000d4: file /projects/rpu/rpu0_app/main.c, line 25.
(gdb) c
Continuing.

Breakpoint 1, task_main_func (pvParameters=0x0 <_vector_table>) at /projects/rpu/rpu0_app/main.c:25
25	    const TickType_t x1second = pdMS_TO_TICKS(1000);
(gdb) n
26	    int32_t counter = 0;
(gdb) n
31	        counter++;
(gdb) n
32	        loginfo("[%d] main loop", counter);
(gdb) n
34	        vTaskDelay(x1second);
(gdb) n

But that next instruction never returns. The RPU console only displays:

INFO: [main] ARM Cortex-R5 0 is running
INFO: [task_main_func] [1] main loop

If I take a look back at my xsct session, I see R5-0 is still listed as "Running":

xsct% targets                                                                                                                               
  1  PS TAP
     2  PMU
     3  PL
        4  Legacy Debug Hub
           5  JTAG2AXI
           6  JTAG2AXI
  7  PSU
     8  RPU
        9* Cortex-R5 #0 (Running)
       10  Cortex-R5 #1 (Halted)
    11  APU
       12  Cortex-A53 #0 (Running)
       13  Cortex-A53 #1 (Reset Catch, EL3(S)/A64)
       14  Cortex-A53 #2 (Reset Catch, EL3(S)/A64)
       15  Cortex-A53 #3 (Reset Catch, EL3(S)/A64)

And if I execute a stop from xsct, the next instruction in GDB finally returns with the following output:

Program received signal SIGTRAP, Trace/breakpoint trap.
0x3ed0139c in prvCheckTasksWaitingTermination () at tasks.c:3759
3759				vPortFree( pxTCB );
(gdb) 
prvIdleTask (pvParameters=) at tasks.c:3327
3327				if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
(gdb) 

I feel like I'm missing something simple here... I would expect to be able to fully step through this code without issue.

Is there a problem with my setup and maybe the clock that is driving the timer for the delay isn't running? If that was the case, I wouldn't expect it to work when I first boot up and kick off the R5 with remoteproc. How would I go about validating that was working?

Thanks

0 Kudos
1 Solution

Accepted Solutions
njozwiak
Adventurer
Adventurer
238 Views
Registered: ‎10-19-2017

I opened a SR with Xilinx and did find resolution to this. The problem was not really in how was debugging, but how I was initializing the RPU.

Debugging can not be fully achieved with the RPU when loading or initializing the core with remoteproc. In order to fully step through execution and debug, the RPU must be initialized from the FSBL. In other words: add an RPU ELF file to your BIF and build it into your BOOT.BIN file. You will then be able to JTAG another one in and step/run to bps without issue.

In my case, I created a skeleton ELF file that did nothing more than launch a loop to log a message at 1Hz. This is permanently added to my BOOT.BIN file during development. I can then either load my target ELF over JTAG for debugging or using remoteproc for normal launching.

View solution in original post

2 Replies
njozwiak
Adventurer
Adventurer
513 Views
Registered: ‎10-19-2017

I believe this problem to be the tick interrupt is not being executed: https://www.freertos.org/FreeRTOS_Support_Forum_Archive/December_2015/freertos_Freertos_stuck_in_vTaskDelay_2b62dcb6j.html

What I am not sure is why it runs fine when I am not debugging, but does not run when I am. My FreeRTOSConfig.h file defines the interrupt handler to be the one defined in ./rpu0_bsp/psu_cortexr5_0/libsrc/freertos10_xilinx_v1_3/src/portZynqUltrascale.c:

void FreeRTOS_SetupTickInterrupt( void );
#define configSETUP_TICK_INTERRUPT() FreeRTOS_SetupTickInterrupt()

void FreeRTOS_ClearTickInterrupt( void );
#define configCLEAR_TICK_INTERRUPT()	FreeRTOS_ClearTickInterrupt()

 

0 Kudos
njozwiak
Adventurer
Adventurer
239 Views
Registered: ‎10-19-2017

I opened a SR with Xilinx and did find resolution to this. The problem was not really in how was debugging, but how I was initializing the RPU.

Debugging can not be fully achieved with the RPU when loading or initializing the core with remoteproc. In order to fully step through execution and debug, the RPU must be initialized from the FSBL. In other words: add an RPU ELF file to your BIF and build it into your BOOT.BIN file. You will then be able to JTAG another one in and step/run to bps without issue.

In my case, I created a skeleton ELF file that did nothing more than launch a loop to log a message at 1Hz. This is permanently added to my BOOT.BIN file during development. I can then either load my target ELF over JTAG for debugging or using remoteproc for normal launching.

View solution in original post