#ifndef __ASSEMBLER__
+#include "esp_err.h"
+
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
\ No newline at end of file
#include "esp_gdbstub.h"
#include "esp_panic.h"
#include "esp_attr.h"
+#include "esp_err.h"
/*
Panic handlers; these get called when an unhandled exception occurs or the assembly-level
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));
+ }
+}
+
+
portMUX usage.
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
endmenu
#include "rom/ets_sys.h"
#include "esp_newlib.h"
+#include "esp_panic.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
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);
}