Back to home page

LXR

 
 

    


Warning, /bsps/lm32/shared/gdbstub/README.md is written in an unsupported language. File is not indexed.

0001 GDB Stub lm32
0002 =============
0003 
0004 This is a thread-aware gdb stub for the lm32 architecture. It has to be
0005 linked with the application, which should be debugged. The application has
0006 to call 'lm32_gdb_stub_install' to setup the stub.
0007    The stub remaps _all_ h/w exceptions to an own code (lm32-debug.S), which
0008 saves all the registers, calls the gdb stub and restores the registers again.
0009    The interrupt exceptions gets handled in a special way. Because we remapped
0010 this exception, we need to do
0011  - the same as the original one (in cpu_asm.S),
0012  - and, as we might use an ISR for breaking into a running application with
0013    gdb, we need to save all registers as well. To be backward compatible
0014    the missing callee saved registers gets appended to CPU_Interrupt_frame.
0015    There is a mapping in 'gdb_handle_break' for that.
0016 
0017 To use this gdb stub, your bsp has to provide the following functions:
0018  - void gdb_put_debug_char(char c)
0019    Puts the given charater c to the debug console output. The function can
0020    block until the character can be written to the output buffer.
0021 
0022  - char gdb_get_debug_char(void)
0023    Returns the character in the input buffer of the debug console. If no one
0024    is availabe, the function must block.
0025 
0026  - void gdb_console_init()
0027    This function can be used to initialize the debug console. Additionally,
0028    it should set up the ISR for the debug console to call the function
0029    'gdb_handle_break', which is provided by the gdb stub and enable the
0030    interrupt for a break symbol on the debug serial port. If no ISR is
0031    provided, you won't be able to interrupt a running application.
0032 
0033  - void gdb_ack_irq()
0034    If an ISR is used, this function is used to acknowledge the interrupt.
0035 
0036 NOTE: the stub don't skip a hardcoded 'break' in the code. So you have to
0037    set the PC an instruction further in the debugger (set $pc += 4).
0038 
0039 NOTE2: make sure you have the following CFLAGS set:
0040      -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled 
0041      -msign-extend-enabled
0042    Without the hardware support, it is done in software. Unfortunately, the
0043    stub also uses some shifts and multiplies. If you step through your code,
0044    there will be a chance that a breakpoint is set to one of that functions,
0045    which then causes an endless loop.
0046 
0047 
0048 EXAMPLES
0049 
0050 ```shell
0051   char gdb_get_debug_char(void)
0052   {
0053     /* Wait until there is a byte in RXTX */
0054     while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR));
0055 
0056     return (char) uartread(LM32_UART_RBR);
0057   }
0058 
0059   void gdb_put_debug_char(char c)
0060   {
0061     /* Wait until RXTX is empty. */
0062     while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE));
0063     uartwrite(LM32_UART_RBR, c);
0064   }
0065 
0066   extern void gdb_handle_break(
0067     rtems_vector_number vector,
0068     CPU_Interrupt_frame *frame
0069   );
0070   void gdb_console_init()
0071   {
0072     rtems_isr_entry old;
0073 
0074     /* enable interrupts */
0075     uartwrite(LM32_UART_IER, 1);
0076 
0077     rtems_interrupt_catch((rtems_isr_entry) gdb_handle_break, DEBUG_UART_IRQ,
0078       &old);
0079     lm32_interrupt_unmask(1 << DEBUG_UART_IRQ);
0080   }
0081 
0082   void gdb_ack_irq()
0083   {
0084     lm32_interrupt_ack(1 << DEBUG_UART_IRQ);
0085   }
0086 ```