eCos Product
RedBoot Product
Supported Hardware |
![]() eCos GDB stubs [TBD/in progress]The eCos common HAL contains target stubs which know the protocol used by GDB. This means that GDB can debug an application on the target, using the stubs features to control execution and examine memory/registers. See [FIXME:ref] here for details on the protocol used by GDB. Implementing stubs for a new HAL consists of two parts. The first is the architecture or variant part which is used by the common stub code to control the CPU, access register contents, and translate exception codes into UNIX signal numbers. The second part is required for each new platform, and is the implementation of a simple device driver used by the common stub to communicate with GDB via the platform's IO hardware. Architecture Stub Support [TBD]The various features required by the architecture HAL are described below. Take a look an existing implementation to put it all in context. Startup InitializationThe common stubs need to be initialized before the application proper is started. This is done with a call to initialize_stub after the target has been fully initialized. After this, the function hal_ctrlc_isr_init should be called to initialize the device driver for asynchronous breakpoints. Both calls should be made conditional on the configuration. In the SH HAL this looks like this: #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS mov.l $_initialize_stub,r1 jsr @r1 nop #endif #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) mov.l $_hal_ctrlc_isr_init,r1 jsr @r1 nop #endif mov.l $_cyg_start,r1 jsr @r1 nop Register DefinitionsThe architecture stub header file must contain an enumeration of register names and macros defining number of registers and the register sizes. This is the definitions from the PPC HAL: #define NUMREGS 71 #define REGSIZE( _x_ ) (((_x_) >= F0 && (_x_) <= F31) ? 8 : 4) enum regnames { R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31, PC, PS, CND, LR, CNT, XER, MQ }; Global Data AccessIf the architecture uses a "Global Pointer" register for accessing data, CYGARC_HAL_SAVE_GP and CYGARC_HAL_RESTORE_GP macros must be implemented. These allow switching between the GP data area used by the RAM startup application, and that used by the stub code in ROM. Single-steppingIt is possible to implement single-stepping in one of two ways. The first (and simplest and most effective) is to use a CPU builtin single-stepping control. The SH and PPC HALs use this method. The other method requires code to examine the instruction at the PC to determine which instruction will be executed next - a breakpoint is then placed on that instruction. ARM and MIPS HALs use this method. Signal TranslationThe function __computeSignal() must provide a translation from the HAL exception number to the standard UNIX signal number. On some architectures it may be necessary to read some of the saved registers to determine what signal an exception should be translated to - in this case, use the get_register() function to acquire register values. Platform Stub SupportThere are two parts to the platform stub support. The first part is the simple communication features. The second part is the asynchronous breakpoints, which should be implemented last (since they are more useful for application development than for stub/eCos debugging). GDB Communication [TBD]FIXME:See calling interfaceAsynchronous GDB breakpointsFIXME: What happens is that the stubs enable serial receive interrupts, but do not change the vector. When a serial interrupt happens, it causes the cyg_hal_default_isr of the application to be run. This calls into the stub (via the virtual vectors) which determines if the received character was a 0x03. If so, a breakpoint is put at the PC where the interrupt happened. GDB allows to asynchronously break execution of a running application. This is done by sending a 0x03 character to the target. If the serial device has interrupts enabled the interrupt execution path will eventually pass through hal_default_isr (see the Note below) which will check for the 0x03 character and issue a breakpoint. This will cause the ROM monitor to be entered, and GDB resumes control of the target. Note: if a serial device driver is enabled and is using the serial receive character interrupt vector, the character will never reach the asynchronous breakpoint handling code, and thus GDB will not be able to break the application execution. If possible (not available on all platforms), use different serial devices for debugging and serial communication. Implementation detailsThe implementation consists of two parts:
Thread debugging [TBD]Application will set DBG_SYSCALL in virtual vector table, allowing ROM monitor to call into the application kernel context and retrieve debugging information. This is all set up in hal_if_init(). |