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 ```