Select one of the symbols to view example projects that use it.
 
Outline
#include "sdkconfig.h"
#include <stdbool.h>
#include <stdint.h>
#include <assert.h>
#include "soc/soc_caps.h"
#include "xtensa_api.h"
#include "xt_utils.h"
#include "riscv/rv_utils.h"
#include "esp_intr_alloc.h"
#include "esp_err.h"
#include "esp_attr.h"
esp_cpu_cycle_count_t
esp_cpu_intr_type_t
esp_cpu_intr_desc_t
#define ESP_CPU_INTR_DESC_FLAG_SPECIAL
#define ESP_CPU_INTR_DESC_FLAG_RESVD
esp_cpu_watchpoint_trigger_t
esp_cpu_stall(int);
esp_cpu_unstall(int);
esp_cpu_reset(int);
esp_cpu_wait_for_intr();
esp_cpu_get_core_id()
esp_cpu_get_sp()
esp_cpu_get_cycle_count()
esp_cpu_set_cycle_count(esp_cpu_cycle_count_t)
esp_cpu_pc_to_addr(uint32_t)
Interrupt Descriptors
esp_cpu_intr_get_desc(int, int, esp_cpu_intr_desc_t *);
Interrupt Configuration
esp_cpu_intr_set_ivt_addr(const void *)
esp_cpu_intr_has_handler(int)
esp_cpu_intr_set_handler(int, esp_cpu_intr_handler_t, void *)
esp_cpu_intr_get_handler_arg(int)
Interrupt Control
esp_cpu_intr_enable(uint32_t)
esp_cpu_intr_disable(uint32_t)
esp_cpu_intr_get_enabled_mask()
esp_cpu_intr_edge_ack(int)
esp_cpu_configure_region_protection();
Breakpoints/Watchpoints
esp_cpu_set_breakpoint(int, const void *);
esp_cpu_clear_breakpoint(int);
esp_cpu_set_watchpoint(int, const void *, size_t, esp_cpu_watchpoint_trigger_t);
esp_cpu_clear_watchpoint(int);
Debugger
esp_cpu_dbgr_is_attached()
esp_cpu_dbgr_break()
Instructions
esp_cpu_get_call_addr(intptr_t)
esp_cpu_compare_and_set(volatile uint32_t *, uint32_t, uint32_t);
Files
loading...
SourceVuESP-IDF Framework and ExamplesESP-IDFcomponents/esp_hw_support/include/esp_cpu.h
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */ #pragma once #include "sdkconfig.h" #include <stdbool.h> #include <stdint.h> #include <assert.h> #include "soc/soc_caps.h"5 includes #ifdef __XTENSA__ #include "xtensa_api.h" #include "xt_utils.h"/* ... */ #elif __riscv #include "riscv/rv_utils.h" #endif #include "esp_intr_alloc.h" #include "esp_err.h" #include "esp_attr.h" #ifdef __cplusplus extern "C" { #endif /** * @brief CPU cycle count type * * This data type represents the CPU's clock cycle count *//* ... */ typedef uint32_t esp_cpu_cycle_count_t; /** * @brief CPU interrupt type *//* ... */ typedef enum { ESP_CPU_INTR_TYPE_LEVEL = 0, ESP_CPU_INTR_TYPE_EDGE, ESP_CPU_INTR_TYPE_NA, }{ ... } esp_cpu_intr_type_t; /** * @brief CPU interrupt descriptor * * Each particular CPU interrupt has an associated descriptor describing that * particular interrupt's characteristics. Call esp_cpu_intr_get_desc() to get * the descriptors of a particular interrupt. *//* ... */ typedef struct { int priority; /**< Priority of the interrupt if it has a fixed priority, (-1) if the priority is configurable. */ esp_cpu_intr_type_t type; /**< Whether the interrupt is an edge or level type interrupt, ESP_CPU_INTR_TYPE_NA if the type is configurable. */ uint32_t flags; /**< Flags indicating extra details. */ }{ ... } esp_cpu_intr_desc_t; /** * @brief Interrupt descriptor flags of esp_cpu_intr_desc_t *//* ... */ #define ESP_CPU_INTR_DESC_FLAG_SPECIAL 0x01 /**< The interrupt is a special interrupt (e.g., a CPU timer interrupt) */ #define ESP_CPU_INTR_DESC_FLAG_RESVD 0x02 /**< The interrupt is reserved for internal use */ /** * @brief CPU interrupt handler type *//* ... */ typedef void (*esp_cpu_intr_handler_t)(void *arg); /** * @brief CPU watchpoint trigger type *//* ... */ typedef enum { ESP_CPU_WATCHPOINT_LOAD, ESP_CPU_WATCHPOINT_STORE, ESP_CPU_WATCHPOINT_ACCESS, }{ ... } esp_cpu_watchpoint_trigger_t; /* --------------------------------------------------- CPU Control ----------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ *//* ... */ /** * @brief Stall a CPU core * * @param core_id The core's ID *//* ... */ void esp_cpu_stall(int core_id); /** * @brief Resume a previously stalled CPU core * * @param core_id The core's ID *//* ... */ void esp_cpu_unstall(int core_id); /** * @brief Reset a CPU core * * @param core_id The core's ID *//* ... */ void esp_cpu_reset(int core_id); /** * @brief Wait for Interrupt * * This function causes the current CPU core to execute its Wait For Interrupt * (WFI or equivalent) instruction. After executing this function, the CPU core * will stop execution until an interrupt occurs. *//* ... */ void esp_cpu_wait_for_intr(void); /* -------------------------------------------------- CPU Registers ---------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ *//* ... */ /** * @brief Get the current core's ID * * This function will return the ID of the current CPU (i.e., the CPU that calls * this function). * * @return The current core's ID [0..SOC_CPU_CORES_NUM - 1] *//* ... */ FORCE_INLINE_ATTR __attribute__((pure)) int esp_cpu_get_core_id(void) { //Note: Made "pure" to optimize for single core target #ifdef __XTENSA__ return (int)xt_utils_get_core_id(); #else return (int)rv_utils_get_core_id(); #endif }{ ... } /** * @brief Read the current stack pointer address * * @return Stack pointer address *//* ... */ FORCE_INLINE_ATTR void *esp_cpu_get_sp(void) { #ifdef __XTENSA__ return xt_utils_get_sp(); #else return rv_utils_get_sp(); #endif }{ ... } /** * @brief Get the current CPU core's cycle count * * Each CPU core maintains an internal counter (i.e., cycle count) that increments * every CPU clock cycle. * * @return Current CPU's cycle count, 0 if not supported. *//* ... */ FORCE_INLINE_ATTR esp_cpu_cycle_count_t esp_cpu_get_cycle_count(void) { #ifdef __XTENSA__ return (esp_cpu_cycle_count_t)xt_utils_get_cycle_count(); #else return (esp_cpu_cycle_count_t)rv_utils_get_cycle_count(); #endif }{ ... } /** * @brief Set the current CPU core's cycle count * * Set the given value into the internal counter that increments every * CPU clock cycle. * * @param cycle_count CPU cycle count *//* ... */ FORCE_INLINE_ATTR void esp_cpu_set_cycle_count(esp_cpu_cycle_count_t cycle_count) { #ifdef __XTENSA__ xt_utils_set_cycle_count((uint32_t)cycle_count); #else rv_utils_set_cycle_count((uint32_t)cycle_count); #endif }{ ... } /** * @brief Convert a program counter (PC) value to address * * If the architecture does not store the true virtual address in the CPU's PC * or return addresses, this function will convert the PC value to a virtual * address. Otherwise, the PC is just returned * * @param pc PC value * @return Virtual address *//* ... */ FORCE_INLINE_ATTR __attribute__((pure)) void *esp_cpu_pc_to_addr(uint32_t pc) { #ifdef __XTENSA__ // Xtensa stores window rotation in PC[31:30] return (void *)((pc & 0x3fffffffU) | 0x40000000U);/* ... */ #else return (void *)pc; #endif }{ ... } /* ------------------------------------------------- CPU Interrupts ---------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ *//* ... */ // ---------------- Interrupt Descriptors ------------------ /** * @brief Get a CPU interrupt's descriptor * * Each CPU interrupt has a descriptor describing the interrupt's capabilities * and restrictions. This function gets the descriptor of a particular interrupt * on a particular CPU. * * @param[in] core_id The core's ID * @param[in] intr_num Interrupt number * @param[out] intr_desc_ret The interrupt's descriptor *//* ... */ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret); Interrupt Descriptors // --------------- Interrupt Configuration ----------------- /** * @brief Set the base address of the current CPU's Interrupt Vector Table (IVT) * * @param ivt_addr Interrupt Vector Table's base address *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_set_ivt_addr(const void *ivt_addr) { #ifdef __XTENSA__ xt_utils_set_vecbase((uint32_t)ivt_addr); #else rv_utils_set_mtvec((uint32_t)ivt_addr); #endif }{ ... } #if SOC_INT_CLIC_SUPPORTED /** * @brief Set the base address of the current CPU's Interrupt Vector Table (MTVT) * * @param mtvt_addr Interrupt Vector Table's base address * * @note The MTVT table is only applicable when CLIC is supported *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_set_mtvt_addr(const void *mtvt_addr) { rv_utils_set_mtvt((uint32_t)mtvt_addr); }{...} /* ... */#endif //#if SOC_INT_CLIC_SUPPORTED #if SOC_CPU_HAS_FLEXIBLE_INTC /** * @brief Set the interrupt type of a particular interrupt * * Set the interrupt type (Level or Edge) of a particular interrupt on the * current CPU. * * @param intr_num Interrupt number (from 0 to 31) * @param intr_type The interrupt's type *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_set_type(int intr_num, esp_cpu_intr_type_t intr_type) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); enum intr_type type = (intr_type == ESP_CPU_INTR_TYPE_LEVEL) ? INTR_TYPE_LEVEL : INTR_TYPE_EDGE; esprv_int_set_type(intr_num, type); }{...} /** * @brief Get the current configured type of a particular interrupt * * Get the currently configured type (i.e., level or edge) of a particular * interrupt on the current CPU. * * @param intr_num Interrupt number (from 0 to 31) * @return Interrupt type *//* ... */ FORCE_INLINE_ATTR esp_cpu_intr_type_t esp_cpu_intr_get_type(int intr_num) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); enum intr_type type = esprv_int_get_type(intr_num); return (type == INTR_TYPE_LEVEL) ? ESP_CPU_INTR_TYPE_LEVEL : ESP_CPU_INTR_TYPE_EDGE; }{...} /** * @brief Set the priority of a particular interrupt * * Set the priority of a particular interrupt on the current CPU. * * @param intr_num Interrupt number (from 0 to 31) * @param intr_priority The interrupt's priority *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_set_priority(int intr_num, int intr_priority) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); esprv_int_set_priority(intr_num, intr_priority); }{...} /** * @brief Get the current configured priority of a particular interrupt * * Get the currently configured priority of a particular interrupt on the * current CPU. * * @param intr_num Interrupt number (from 0 to 31) * @return Interrupt's priority *//* ... */ FORCE_INLINE_ATTR int esp_cpu_intr_get_priority(int intr_num) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); return esprv_int_get_priority(intr_num); }{...} /* ... */#endif // SOC_CPU_HAS_FLEXIBLE_INTC /** * @brief Check if a particular interrupt already has a handler function * * Check if a particular interrupt on the current CPU already has a handler * function assigned. * * @note This function simply checks if the IVT of the current CPU already has * a handler assigned. * @param intr_num Interrupt number (from 0 to 31) * @return True if the interrupt has a handler function, false otherwise. *//* ... */ FORCE_INLINE_ATTR bool esp_cpu_intr_has_handler(int intr_num) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); bool has_handler; #ifdef __XTENSA__ has_handler = xt_int_has_handler(intr_num, esp_cpu_get_core_id()); #else has_handler = intr_handler_get(intr_num); #endif return has_handler; }{ ... } /** * @brief Set the handler function of a particular interrupt * * Assign a handler function (i.e., ISR) to a particular interrupt on the * current CPU. * * @note This function simply sets the handler function (in the IVT) and does * not actually enable the interrupt. * @param intr_num Interrupt number (from 0 to 31) * @param handler Handler function * @param handler_arg Argument passed to the handler function *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_set_handler(int intr_num, esp_cpu_intr_handler_t handler, void *handler_arg) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); #ifdef __XTENSA__ xt_set_interrupt_handler(intr_num, (xt_handler)handler, handler_arg); #else intr_handler_set(intr_num, (intr_handler_t)handler, handler_arg); #endif }{ ... } /** * @brief Get a handler function's argument of * * Get the argument of a previously assigned handler function on the current CPU. * * @param intr_num Interrupt number (from 0 to 31) * @return The the argument passed to the handler function *//* ... */ FORCE_INLINE_ATTR void *esp_cpu_intr_get_handler_arg(int intr_num) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); void *handler_arg; #ifdef __XTENSA__ handler_arg = xt_get_interrupt_handler_arg(intr_num); #else handler_arg = intr_handler_get_arg(intr_num); #endif return handler_arg; }{ ... } Interrupt Configuration// ------------------ Interrupt Control -------------------- /** * @brief Enable particular interrupts on the current CPU * * @param intr_mask Bit mask of the interrupts to enable *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_enable(uint32_t intr_mask) { #ifdef __XTENSA__ xt_ints_on(intr_mask); #else rv_utils_intr_enable(intr_mask); #endif }{ ... } /** * @brief Disable particular interrupts on the current CPU * * @param intr_mask Bit mask of the interrupts to disable *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_disable(uint32_t intr_mask) { #ifdef __XTENSA__ xt_ints_off(intr_mask); #else rv_utils_intr_disable(intr_mask); #endif }{ ... } /** * @brief Get the enabled interrupts on the current CPU * * @return Bit mask of the enabled interrupts *//* ... */ FORCE_INLINE_ATTR uint32_t esp_cpu_intr_get_enabled_mask(void) { #ifdef __XTENSA__ return xt_utils_intr_get_enabled_mask(); #else return rv_utils_intr_get_enabled_mask(); #endif }{ ... } /** * @brief Acknowledge an edge interrupt * * @param intr_num Interrupt number (from 0 to 31) *//* ... */ FORCE_INLINE_ATTR void esp_cpu_intr_edge_ack(int intr_num) { assert(intr_num >= 0 && intr_num < SOC_CPU_INTR_NUM); #ifdef __XTENSA__ xthal_set_intclear((unsigned) (1 << intr_num)); #else rv_utils_intr_edge_ack((unsigned) intr_num); #endif }{ ... } /* -------------------------------------------------- Memory Ports ----------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ *//* ... */ /** * @brief Configure the CPU to disable access to invalid memory regions *//* ... */ void esp_cpu_configure_region_protection(void); /* ---------------------------------------------------- Debugging ------------------------------------------------------ * * ------------------------------------------------------------------------------------------------------------------ *//* ... */ Interrupt Control // --------------- Breakpoints/Watchpoints ----------------- #if SOC_CPU_BREAKPOINTS_NUM > 0 /** * @brief Set and enable a hardware breakpoint on the current CPU * * @note This function is meant to be called by the panic handler to set a * breakpoint for an attached debugger during a panic. * @note Overwrites previously set breakpoint with same breakpoint number. * @param bp_num Hardware breakpoint number [0..SOC_CPU_BREAKPOINTS_NUM - 1] * @param bp_addr Address to set a breakpoint on * @return ESP_OK if breakpoint is set. Failure otherwise *//* ... */ esp_err_t esp_cpu_set_breakpoint(int bp_num, const void *bp_addr); /** * @brief Clear a hardware breakpoint on the current CPU * * @note Clears a breakpoint regardless of whether it was previously set * @param bp_num Hardware breakpoint number [0..SOC_CPU_BREAKPOINTS_NUM - 1] * @return ESP_OK if breakpoint is cleared. Failure otherwise *//* ... */ esp_err_t esp_cpu_clear_breakpoint(int bp_num); /* ... */ #endif // SOC_CPU_BREAKPOINTS_NUM > 0 /** * @brief Set and enable a hardware watchpoint on the current CPU * * Set and enable a hardware watchpoint on the current CPU, specifying the * memory range and trigger operation. Watchpoints will break/panic the CPU when * the CPU accesses (according to the trigger type) on a certain memory range. * * @note Overwrites previously set watchpoint with same watchpoint number. * On RISC-V chips, this API uses method0(Exact matching) and method1(NAPOT matching) according to the * riscv-debug-spec-0.13 specification for address matching. * If the watch region size is 1byte, it uses exact matching (method 0). * If the watch region size is larger than 1byte, it uses NAPOT matching (method 1). This mode requires * the watching region start address to be aligned to the watching region size. * * @param wp_num Hardware watchpoint number [0..SOC_CPU_WATCHPOINTS_NUM - 1] * @param wp_addr Watchpoint's base address, must be naturally aligned to the size of the region * @param size Size of the region to watch. Must be one of 2^n and in the range of [1 ... SOC_CPU_WATCHPOINT_MAX_REGION_SIZE] * @param trigger Trigger type * @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise *//* ... */ esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, esp_cpu_watchpoint_trigger_t trigger); /** * @brief Clear a hardware watchpoint on the current CPU * * @note Clears a watchpoint regardless of whether it was previously set * @param wp_num Hardware watchpoint number [0..SOC_CPU_WATCHPOINTS_NUM - 1] * @return ESP_OK if watchpoint was cleared. Failure otherwise. *//* ... */ esp_err_t esp_cpu_clear_watchpoint(int wp_num); Breakpoints/Watchpoints // ---------------------- Debugger ------------------------- /** * @brief Check if the current CPU has a debugger attached * * @return True if debugger is attached, false otherwise *//* ... */ FORCE_INLINE_ATTR bool esp_cpu_dbgr_is_attached(void) { #ifdef __XTENSA__ return xt_utils_dbgr_is_attached(); #else return rv_utils_dbgr_is_attached(); #endif }{ ... } /** * @brief Trigger a call to the current CPU's attached debugger *//* ... */ FORCE_INLINE_ATTR void esp_cpu_dbgr_break(void) { #ifdef __XTENSA__ xt_utils_dbgr_break(); #else rv_utils_dbgr_break(); #endif }{ ... } Debugger// ---------------------- Instructions ------------------------- /** * @brief Given the return address, calculate the address of the preceding call instruction * This is typically used to answer the question "where was the function called from?" * @param return_address The value of the return address register. * Typically set to the value of __builtin_return_address(0). * @return Address of the call instruction preceding the return address. *//* ... */ FORCE_INLINE_ATTR intptr_t esp_cpu_get_call_addr(intptr_t return_address) { /* Both Xtensa and RISC-V have 2-byte instructions, so to get this right we * should decode the preceding instruction as if it is 2-byte, check if it is a call, * else treat it as 3 or 4 byte one. However for the cases where this function is * used, being off by one instruction is usually okay, so this is kept simple for now. *//* ... */ #ifdef __XTENSA__ return return_address - 3; #else return return_address - 4; #endif }{ ... } /* ------------------------------------------------------ Misc --------------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ *//* ... */ /** * @brief Atomic compare-and-set operation * * @param addr Address of atomic variable * @param compare_value Value to compare the atomic variable to * @param new_value New value to set the atomic variable to * @return Whether the atomic variable was set or not *//* ... */ bool esp_cpu_compare_and_set(volatile uint32_t *addr, uint32_t compare_value, uint32_t new_value); #if SOC_BRANCH_PREDICTOR_SUPPORTED /** * @brief Enable branch prediction *//* ... */ FORCE_INLINE_ATTR void esp_cpu_branch_prediction_enable(void) { rv_utils_en_branch_predictor(); }{...} /** * @brief Disable branch prediction *//* ... */ FORCE_INLINE_ATTR void esp_cpu_branch_prediction_disable(void) { rv_utils_dis_branch_predictor(); }{...} /* ... */#endif //#if SOC_BRANCH_PREDICTOR_SUPPORTED #ifdef __cplusplus }Instructions {...}#endif
Details
Show:
from
Types: Columns:
This file uses the notable symbols shown below. Click anywhere in the file to view more details.