1 /*
2 * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #pragma once
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13 #ifndef __ASSEMBLER__
14
15 #include <stdbool.h>
16 #include "esp_err.h"
17 #include "soc/soc.h" // [refactor-todo] IDF-2297
18 #include "esp_cpu.h"
19
20 /*
21 * @brief Structure used for backtracing
22 *
23 * This structure stores the backtrace information of a particular stack frame
24 * (i.e. the PC and SP). This structure is used iteratively with the
25 * esp_cpu_get_next_backtrace_frame() function to traverse each frame within a
26 * single stack. The next_pc represents the PC of the current frame's caller, thus
27 * a next_pc of 0 indicates that the current frame is the last frame on the stack.
28 *
29 * @note Call esp_backtrace_get_start() to obtain initialization values for
30 * this structure
31 */
32 typedef struct {
33 uint32_t pc; /* PC of the current frame */
34 uint32_t sp; /* SP of the current frame */
35 uint32_t next_pc; /* PC of the current frame's caller */
36 const void *exc_frame; /* Pointer to the full frame data structure, if applicable */
37 } esp_backtrace_frame_t;
38
39 /**
40 * @brief If an OCD is connected over JTAG. set breakpoint 0 to the given function
41 * address. Do nothing otherwise.
42 * @param fn Pointer to the target breakpoint position
43 */
44 void esp_set_breakpoint_if_jtag(void *fn);
45
46 /**
47 * Get the first frame of the current stack's backtrace
48 *
49 * Given the following function call flow (B -> A -> X -> esp_backtrace_get_start),
50 * this function will do the following.
51 * - Flush CPU registers and window frames onto the current stack
52 * - Return PC and SP of function A (i.e. start of the stack's backtrace)
53 * - Return PC of function B (i.e. next_pc)
54 *
55 * @note This function is implemented in assembly
56 *
57 * @param[out] pc PC of the first frame in the backtrace
58 * @param[out] sp SP of the first frame in the backtrace
59 * @param[out] next_pc PC of the first frame's caller
60 */
61 extern void esp_backtrace_get_start(uint32_t *pc, uint32_t *sp, uint32_t *next_pc);
62
63 /**
64 * Get the next frame on a stack for backtracing
65 *
66 * Given a stack frame(i), this function will obtain the next stack frame(i-1)
67 * on the same call stack (i.e. the caller of frame(i)). This function is meant to be
68 * called iteratively when doing a backtrace.
69 *
70 * Entry Conditions: Frame structure containing valid SP and next_pc
71 * Exit Conditions:
72 * - Frame structure updated with SP and PC of frame(i-1). next_pc now points to frame(i-2).
73 * - If a next_pc of 0 is returned, it indicates that frame(i-1) is last frame on the stack
74 *
75 * @param[inout] frame Pointer to frame structure
76 *
77 * @return
78 * - True if the SP and PC of the next frame(i-1) are sane
79 * - False otherwise
80 */
81 bool esp_backtrace_get_next_frame(esp_backtrace_frame_t *frame);
82
83 /**
84 * @brief Print the backtrace from specified frame.
85 *
86 * @param depth The maximum number of stack frames to print (should be > 0)
87 * @param frame Starting frame to print from
88 * @param panic Indicator if backtrace print is during a system panic
89 *
90 * @note On the ESP32, users must call esp_backtrace_get_start() first to flush the stack.
91 * @note If a esp_backtrace_frame_t* frame is obtained though a call to esp_backtrace_get_start()
92 * from some example function func_a(), then frame is only valid within the frame/scope of func_a().
93 * Users should not attempt to pass/use frame other frames within the same stack of different stacks.
94 *
95 * @return
96 * - ESP_OK Backtrace successfully printed to completion or to depth limit
97 * - ESP_FAIL Backtrace is corrupted
98 */
99 esp_err_t esp_backtrace_print_from_frame(int depth, const esp_backtrace_frame_t* frame, bool panic);
100
101 /**
102 * @brief Print the backtrace of the current stack
103 *
104 * @param depth The maximum number of stack frames to print (should be > 0)
105 *
106 * @return
107 * - ESP_OK Backtrace successfully printed to completion or to depth limit
108 * - ESP_FAIL Backtrace is corrupted
109 */
110 esp_err_t esp_backtrace_print(int depth);
111
112 /**
113 * @brief Set a watchpoint to break/panic when a certain memory range is accessed.
114 * Superseded by esp_cpu_set_watchpoint in esp_cpu.h.
115 */
esp_set_watchpoint(int no,void * adr,int size,int flags)116 static inline __attribute__((deprecated)) esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags)
117 {
118 return esp_cpu_set_watchpoint(no, adr, size, (esp_cpu_watchpoint_trigger_t)flags);
119 }
120
121 /**
122 * @brief Set a watchpoint to break/panic when a certain memory range is accessed.
123 * Superseded by esp_cpu_clear_watchpoint in esp_cpu.h.
124 */
esp_clear_watchpoint(int no)125 static inline __attribute__((deprecated)) void esp_clear_watchpoint(int no)
126 {
127 esp_cpu_clear_watchpoint(no);
128 }
129
130 #endif
131 #ifdef __cplusplus
132 }
133 #endif
134