diff --git a/TeensyDebug.cpp b/TeensyDebug.cpp index 2953f38..6a5f853 100644 --- a/TeensyDebug.cpp +++ b/TeensyDebug.cpp @@ -733,9 +733,8 @@ void debug_monitor() { #pragma GCC optimize ("O0") void (*original_software_isr)() = NULL; -#if 0 void (*original_svc_isr)() = NULL; -#endif + /** * @brief Called by software interrupt. Perform chaining or * call handler. @@ -797,7 +796,7 @@ void debug_call_isr_setup() { NVIC_SET_PENDING(IRQ_SOFTWARE); } -#if 0 +#if 1 uint32_t lastpc; int testOurSVC() { @@ -815,7 +814,7 @@ int testOurSVC() { */ __attribute__((noinline, naked)) void svcall_isr() { -#if 0 +#if 1 // get the PC that triggered this // subtract width of svc instruction (which is 2) // is it one of our svcs? @@ -823,18 +822,19 @@ void svcall_isr() { "ldr r0, [sp, #24] \n" "sub r0, #2 \n" "ldr r1, =lastpc \n" - "str r0, [r1]" + "str r0, [r1] \n" + "push {lr}" ); if (testOurSVC()) { - asm volatile("push {lr}"); debug_call_isr_setup(); asm volatile("pop {pc}"); } else { if (original_svc_isr) { + asm volatile("pop {lr}"); asm volatile("mov pc, %0" : : "r" (original_svc_isr)); } - asm volatile("bx lr"); + asm volatile("pop {pc}"); } #else asm volatile("push {lr}"); @@ -1051,6 +1051,12 @@ void dumpmem(void *mem, int sz) { // table must be in ram above 0x20000000 and this ram is in the stack area. uint32_t save_stack; +#ifdef __IMXRT1062__ +extern "C" void unused_interrupt_vector(void); +#else +extern "C" void unused_isr(void); +#endif + /** * @brief Initialize debugging system. * @@ -1087,14 +1093,16 @@ void debug_init() { _VectorsRam[5] = call_bus_fault_isr; _VectorsRam[6] = call_usage_fault_isr; -#if 0 +#ifdef __IMXRT1062__ + if (_VectorsRam[11] == unused_interrupt_vector) { +#else if (_VectorsRam[11] == unused_isr) { +#endif original_svc_isr = 0; } else { original_svc_isr = _VectorsRam[11]; } -#endif _VectorsRam[11] = svcall_isr; // chain the software ISR handler diff --git a/gdbstub.cpp b/gdbstub.cpp index 6dac2a1..8313283 100644 --- a/gdbstub.cpp +++ b/gdbstub.cpp @@ -10,31 +10,33 @@ */ /* - * Notes: + * Notes on 'p': * - * Calling 'p' with a function as in `p func(1,2,3)` doesn't work. Use - * the 'monitor call' command instead. The reason it fails is that GDB 7 performs the + * Calling 'p' with a function as in `p func(1,2,3)` doesn't work without + * this hack. The reason it fails is that GDB 7 performs the * call by: * * 1. Setting a breakpoint at 0x60001000 (the ResetHandler) * 2. Setting LR to 0x60001000 * 3. Setting PC to the funtion we want to call - * 4. Continuing + * 4. Continuing, which causes function to execute * 5. Upon finishing, the function returns to LR * 6. The breakpoint is hit and GDB takes over * 7. GDB unrolls the stack, etc. and gets result * - * This doesn't work because 0x60001000 is in Flash. I tried to do a soft + * This doesn't work because 0x60001000 is in Flash. I first tried to do a soft * remap of 0x60001000 to a point in RAM, but that doesn't work. It fails * with a "Assertion `get_frame_type (frame) == DUMMY_FRAME' failed." - * I think the reason is because GDB changes SP by subtracting 4 before + * I think the reason is because GDB changes SP by subtracting 4 or 8 before * calling the function. Unfortunately, this library doesn't support - * GDB changing SP. + * GDB changing SP. So I keep track of a "fakesp" whenever SP is changed + * by GDB and just return that number instead of the real SP. See + * process_G and process_P. * * Newer versions of GDB choose a different breakpoint location. Instead * of setting the breakpoint on the ResetHandler, they will set it on - * the stack. So perhaps part of the fix is to update the GDB version - * distributed. + * the stack. If that's the case, then this hack will stop working + * sinces it relies on the address of 0x60001000. * */ @@ -392,36 +394,6 @@ char *append32(char *p, uint32_t n) { return p; } -/* - * Notes: - * - * Calling 'p' with a function as in `p func(1,2,3)` doesn't work without - * this hack. The reason it fails is that GDB 7 performs the - * call by: - * - * 1. Setting a breakpoint at 0x60001000 (the ResetHandler) - * 2. Setting LR to 0x60001000 - * 3. Setting PC to the funtion we want to call - * 4. Continuing, which causes function to execute - * 5. Upon finishing, the function returns to LR - * 6. The breakpoint is hit and GDB takes over - * 7. GDB unrolls the stack, etc. and gets result - * - * This doesn't work because 0x60001000 is in Flash. I tried to do a soft - * remap of 0x60001000 to a point in RAM, but that doesn't work. It fails - * with a "Assertion `get_frame_type (frame) == DUMMY_FRAME' failed." - * I think the reason is because GDB changes SP by subtracting 4 before - * calling the function. Unfortunately, this library doesn't support - * GDB changing SP. So I just hardcode subtracting 8 from SP and this - * seems to fool GDB. - * - * Newer versions of GDB choose a different breakpoint location. Instead - * of setting the breakpoint on the ResetHandler, they will set it on - * the stack. If that's the case, then this hack will stop working - * sinces it relies on the address of 0x60001000. - * - */ - // extern void print_registers(); /** @@ -779,6 +751,21 @@ char *getNextWord(char **text) { return orig; } +char *getNextToken(char **text, char token) { + char *orig = *text; + char *p = orig; + while(*p) { + if (*p == token) { + *p++ = 0; + *text = 0; + return orig; + } + p++; + } + *text = 0; + return orig; +} + int (*call0)(); int (*call1)(int p1); int (*call2)(int p1, int p2); @@ -959,6 +946,18 @@ int process_k(const char *cmd, char *result) { return 0; } +int process_v(char *cmd, char *result) { + char *work = getNextToken(&cmd, ';'); + // Serial.print("v:");Serial.println(work); + if (strcmp(work, "vKill") == 0) { + strcpy(result, "OK"); + } + else { + result[0] = 0; + } + return 0; +} + int gdb_active_flag = 0; /** @@ -968,7 +967,7 @@ int gdb_active_flag = 0; * @param result Result to send back * @return int 0 */ -int processCommand(const char *cmd, char *result) { +int processCommand(char *cmd, char *result) { gdb_active_flag = 1; switch(cmd[0]) { case 'g': return process_g(cmd, result); @@ -982,7 +981,7 @@ int processCommand(const char *cmd, char *result) { case 'R': return process_R(cmd, result); case 'r': return process_R(cmd, result); case 'k': return process_k(cmd, result); - + case 'v': return process_v(cmd, result); case '?': return process_question(cmd, result); // case 'B': return process_B(cmd, result); case 'z': return process_z(cmd, result); diff --git a/teensy_debug b/teensy_debug index c7667d2..78a4a38 100755 --- a/teensy_debug +++ b/teensy_debug @@ -118,8 +118,11 @@ def installGDB(): else: DIR = APPDIR + "Arduino.app/" else: - DIR = os.readlink("/usr/local/bin/arduino") - DIR = os.path.dirname(DIR) + "/" + try: + DIR = os.readlink("/usr/local/bin/arduinox") + DIR = os.path.dirname(DIR) + "/" + except: + DIR = '' while(True): if os.path.exists(DIR + "hardware/teensy"):