-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathpanic.c
165 lines (134 loc) · 4.74 KB
/
panic.c
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
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "stdlib.h"
#include "esp_attr.h"
#include "esp_libc.h"
#include "esp_system.h"
#include "esp8266/rom_functions.h"
#include "esp8266/backtrace.h"
#include "rom/ets_sys.h"
#include "esp_err.h"
#include "FreeRTOS.h"
#define PANIC(_fmt, ...) ets_printf(_fmt, ##__VA_ARGS__)
#ifndef CONFIG_ESP_PANIC_SILENT_REBOOT
typedef struct panic_frame {
uint32_t exit;
uint32_t pc;
uint32_t ps;
uint32_t a0;
uint32_t a1;
uint32_t a2;
uint32_t a3;
uint32_t a4;
uint32_t a5;
uint32_t a6;
uint32_t a7;
uint32_t a8;
uint32_t a9;
uint32_t a10;
uint32_t a11;
uint32_t a12;
uint32_t a13;
uint32_t a14;
uint32_t a15;
uint32_t sar;
uint32_t exccause;
} panic_frame_t;
static inline void panic_frame(panic_frame_t *frame)
{
static const char *sdesc[] = {
"PC", "PS", "A0", "A1",
"A2", "A3", "A4", "A5",
"A6", "A7", "A8", "A9",
"A10", "A11", "A12", "A13",
"A14", "A15", "SAR", "EXCCAUSE"
};
static const char *edesc[] = {
"IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError",
"Level1Interrupt", "Alloca", "IntegerDivideByZero", "PCValue",
"Privileged", "LoadStoreAlignment", "res", "res",
"InstrPDAddrError", "LoadStorePIFDataError", "InstrPIFAddrError", "LoadStorePIFAddrError",
"InstTLBMiss", "InstTLBMultiHit", "InstFetchPrivilege", "res",
"InstrFetchProhibited", "res", "res", "res",
"LoadStoreTLBMiss", "LoadStoreTLBMultihit", "LoadStorePrivilege", "res",
"LoadProhibited", "StoreProhibited",
};
void *i_lr = (void *)frame->a0;
void *i_pc = (void *)frame->pc;
void *i_sp = (void *)frame->a1;
void *o_pc;
void *o_sp;
const char *reason = frame->exccause < 30 ? edesc[frame->exccause] : "unknown";
const uint32_t *regs = (const uint32_t *)frame;
PANIC("Guru Meditation Error: Core 0 panic'ed (%s). Exception was unhandled.\r\n", reason);
PANIC("Core 0 register dump:\n");
for (int i = 0; i < 20; i += 4) {
for (int j = 0; j < 4; j++) {
PANIC("%-8s: 0x%08x ", sdesc[i + j], regs[i + j + 1]);
}
PANIC("\r\n");
}
PANIC("\r\nBacktrace: %p:%p ", i_pc, i_sp);
while(xt_retaddr_callee(i_pc, i_sp, i_lr, &o_pc, &o_sp)) {
PANIC("%p:%p ", o_pc, o_sp);
i_pc = o_pc;
i_sp = o_sp;
}
PANIC("\r\n");
}
#endif /* !CONFIG_ESP_PANIC_SILENT_REBOOT */
void panicHandler(void *frame, int wdt)
{
#ifndef CONFIG_ESP_PANIC_SILENT_REBOOT
extern int _chip_nmi_cnt;
_chip_nmi_cnt = 0;
/* NMI can interrupt exception. */
vPortEnterCritical();
do {
REG_WRITE(INT_ENA_WDEV, 0);
} while (REG_READ(INT_ENA_WDEV) != 0);
if (wdt) {
PANIC("Task watchdog got triggered.\r\n\r\n");
}
panic_frame(frame);
#ifdef CONFIG_ESP_PANIC_PRINT_HALT
while (1);
#else
esp_restart();
#endif
#else /* CONFIG_ESP_PANIC_SILENT_REBOOT */
esp_restart();
#endif /* !CONFIG_ESP_PANIC_SILENT_REBOOT */
}
static void esp_error_check_failed_print(const char *msg, esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
PANIC("%s failed: esp_err_t 0x%x", msg, rc);
#ifdef CONFIG_ESP_ERR_TO_NAME_LOOKUP
PANIC(" (%s)", esp_err_to_name(rc));
#endif //CONFIG_ESP_ERR_TO_NAME_LOOKUP
PANIC(" at 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3);
// ESP8266 put main FreeRTOS code at flash
//if (spi_flash_cache_enabled()) { // strings may be in flash cache
PANIC("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression);
//}
}
void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
esp_error_check_failed_print("ESP_ERROR_CHECK_WITHOUT_ABORT", rc, file, line, function, expression);
}
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
esp_error_check_failed_print("ESP_ERROR_CHECK", rc, file, line, function, expression);
abort();
}