kopia lustrzana https://github.com/espressif/esp-idf
Add option to automatically set a watchpoint at the end of the swapped-in task
rodzic
633cd49f88
commit
ca57a86f20
|
@ -14,8 +14,18 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
void esp_set_breakpoint_if_jtag(void *fn);
|
void esp_set_breakpoint_if_jtag(void *fn);
|
||||||
|
|
||||||
|
#define ESP_WATCHPOINT_LOAD 0x40000000
|
||||||
|
#define ESP_WATCHPOINT_STORE 0x80000000
|
||||||
|
#define ESP_WATCHPOINT_ACCESS 0xC0000000
|
||||||
|
|
||||||
|
esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags);
|
||||||
|
void esp_clear_watchpoint(int no);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -32,6 +32,7 @@
|
||||||
#include "esp_gdbstub.h"
|
#include "esp_gdbstub.h"
|
||||||
#include "esp_panic.h"
|
#include "esp_panic.h"
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Panic handlers; these get called when an unhandled exception occurs or the assembly-level
|
Panic handlers; these get called when an unhandled exception occurs or the assembly-level
|
||||||
|
@ -353,3 +354,50 @@ void esp_set_breakpoint_if_jtag(void *fn)
|
||||||
setFirstBreakpoint((uint32_t)fn);
|
setFirstBreakpoint((uint32_t)fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
if (no<0 || no>1) return ESP_ERR_INVALID_ARG;
|
||||||
|
if (flags&(~0xC0000000)) return ESP_ERR_INVALID_ARG;
|
||||||
|
int dbreakc=0x3F;
|
||||||
|
//We support watching 2^n byte values, from 1 to 64. Calculate the mask for that.
|
||||||
|
for (x=0; x<6; x++) {
|
||||||
|
if (size==(1<<x)) break;
|
||||||
|
dbreakc<<=1;
|
||||||
|
}
|
||||||
|
if (x==6) return ESP_ERR_INVALID_ARG;
|
||||||
|
//Mask mask and add in flags.
|
||||||
|
dbreakc=(dbreakc&0x3f)|flags;
|
||||||
|
|
||||||
|
if (no==0) {
|
||||||
|
asm volatile(
|
||||||
|
"wsr.dbreaka0 %0\n" \
|
||||||
|
"wsr.dbreakc0 %1\n" \
|
||||||
|
::"r"(adr),"r"(dbreakc));
|
||||||
|
} else {
|
||||||
|
asm volatile(
|
||||||
|
"wsr.dbreaka1 %0\n" \
|
||||||
|
"wsr.dbreakc1 %1\n" \
|
||||||
|
::"r"(adr),"r"(dbreakc));
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_clear_watchpoint(int no)
|
||||||
|
{
|
||||||
|
//Setting a dbreakc register to 0 makes it trigger on neither load nor store, effectively disabling it.
|
||||||
|
int dbreakc=0;
|
||||||
|
if (no==0) {
|
||||||
|
asm volatile(
|
||||||
|
"wsr.dbreakc0 %0\n" \
|
||||||
|
::"r"(dbreakc));
|
||||||
|
} else {
|
||||||
|
asm volatile(
|
||||||
|
"wsr.dbreakc1 %0\n" \
|
||||||
|
::"r"(dbreakc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,22 @@ config FREERTOS_PORTMUX_DEBUG_RECURSIVE
|
||||||
portMUX usage.
|
portMUX usage.
|
||||||
endif #FREERTOS_UNICORE
|
endif #FREERTOS_UNICORE
|
||||||
|
|
||||||
|
|
||||||
|
config FREERTOS_WATCHPOINT_END_OF_STACK
|
||||||
|
bool "Set a debug watchpoint at the end of each stack"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
FreeRTOS can check if a stack has overflown its bounds by checking either the value of
|
||||||
|
the stack pointer or by checking the integrity of canary bytes. (See FREERTOS_CHECK_STACKOVERFLOW
|
||||||
|
for more information.) These checks only happen on a context switch, and the situation that caused
|
||||||
|
the stack overflow may already be long gone by then. This option will use the debug memory
|
||||||
|
watchpoint 1 (the second one) to allow breaking into the debugger (or panic'ing) as soon as any
|
||||||
|
of the last 32 bytes on the stack of a task are overwritten. The side effect is that using gdb, you
|
||||||
|
effectively only have one watchpoint; the 2nd one is overwritten as soon as a task switch happens.
|
||||||
|
|
||||||
|
When this watchpoint is hit, gdb will stop with a SIGTRAP message. When no OCD is attached, esp-idf
|
||||||
|
will panic on an unhandled debug exception.
|
||||||
|
|
||||||
endif # FREERTOS_DEBUG_INTERNALS
|
endif # FREERTOS_DEBUG_INTERNALS
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -78,6 +78,7 @@ task.h is included from an application file. */
|
||||||
|
|
||||||
#include "rom/ets_sys.h"
|
#include "rom/ets_sys.h"
|
||||||
#include "esp_newlib.h"
|
#include "esp_newlib.h"
|
||||||
|
#include "esp_panic.h"
|
||||||
|
|
||||||
/* FreeRTOS includes. */
|
/* FreeRTOS includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
@ -2809,6 +2810,12 @@ void vTaskSwitchContext( void )
|
||||||
|
|
||||||
traceTASK_SWITCHED_IN();
|
traceTASK_SWITCHED_IN();
|
||||||
|
|
||||||
|
#if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK
|
||||||
|
//Set watchpoint 1 to watch the last 32 bytes of the stack.
|
||||||
|
esp_set_watchpoint(1, pxCurrentTCB[xPortGetCoreID()]->pxStack, 32, ESP_WATCHPOINT_STORE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL_NESTED(irqstate);
|
portEXIT_CRITICAL_NESTED(irqstate);
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue