@@ -38,6 +38,7 @@ extern cont_t g_cont;
38
38
static const char * s_panic_file = 0 ;
39
39
static int s_panic_line = 0 ;
40
40
static const char * s_panic_func = 0 ;
41
+ static const char * s_panic_what = 0 ;
41
42
42
43
static bool s_abort_called = false;
43
44
@@ -57,18 +58,33 @@ extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack,
57
58
58
59
extern void custom_crash_callback ( struct rst_info * rst_info , uint32_t stack , uint32_t stack_end ) __attribute__ ((weak , alias ("__custom_crash_callback" )));
59
60
60
- static void ets_puts_P (const char * romString ) {
61
- char c = pgm_read_byte (romString ++ );
62
- while (c ) {
63
- ets_putc (c );
64
- c = pgm_read_byte (romString ++ );
65
- }
61
+ // Single, non-inlined copy of pgm_read_byte to save IRAM space (as this is not timing critical)
62
+ static char ICACHE_RAM_ATTR iram_read_byte (const char * addr ) {
63
+ return pgm_read_byte (addr );
64
+ }
65
+
66
+ // Required to output the s_panic_file, it's stored in PMEM
67
+ #define ets_puts_P (pstr ) \
68
+ { \
69
+ char c; \
70
+ do { \
71
+ c = iram_read_byte(pstr++); \
72
+ if (c) ets_putc(c); \
73
+ } while (c); \
74
+ }
75
+
76
+ // Place these strings in .text because the SPI interface may be in bad shape during an exception.
77
+ #define ets_printf_P (str , ...) \
78
+ { \
79
+ static const char istr[] ICACHE_RAM_ATTR = (str); \
80
+ char mstr[sizeof(str)]; \
81
+ for (size_t i=0; i < sizeof(str); i++) mstr[i] = iram_read_byte(&istr[i]); \
82
+ ets_printf(mstr, ##__VA_ARGS__); \
66
83
}
67
84
68
85
void __wrap_system_restart_local () {
69
86
if (crash_for_gdb ) * ((int * )0 ) = 0 ;
70
87
register uint32_t sp asm("a1" );
71
-
72
88
struct rst_info rst_info = {0 };
73
89
system_rtc_mem_read (0 , & rst_info , sizeof (rst_info ));
74
90
if (rst_info .reason != REASON_SOFT_WDT_RST &&
@@ -81,21 +97,25 @@ void __wrap_system_restart_local() {
81
97
ets_install_putc1 (& uart_write_char_d );
82
98
83
99
if (s_panic_line ) {
84
- ets_puts_P (PSTR ("\nPanic " ));
85
- ets_puts_P (s_panic_file );
86
- ets_printf (":%d " , s_panic_line );
87
- ets_puts_P (s_panic_func );
88
- ets_puts_P (PSTR ("\n" ));
100
+ ets_printf_P ("\nPanic " );
101
+ ets_puts_P (s_panic_file ); // This is in PROGMEM, need special output because ets_printf can't handle ROM parameters
102
+ ets_printf_P (":%d %s" , s_panic_line , s_panic_func );
103
+ if (s_panic_what ) {
104
+ ets_printf_P (": Assertion '" );
105
+ ets_puts_P (s_panic_what ); // This is also in PMEM
106
+ ets_printf_P ("' failed." );
107
+ }
108
+ ets_putc ('\n' );
89
109
}
90
110
else if (s_abort_called ) {
91
- ets_puts_P ( PSTR ( "Abort called\n") );
111
+ ets_printf_P ( "\nAbort called\n" );
92
112
}
93
113
else if (rst_info .reason == REASON_EXCEPTION_RST ) {
94
- ets_printf ("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n" ,
114
+ ets_printf_P ("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n" ,
95
115
rst_info .exccause , rst_info .epc1 , rst_info .epc2 , rst_info .epc3 , rst_info .excvaddr , rst_info .depc );
96
116
}
97
117
else if (rst_info .reason == REASON_SOFT_WDT_RST ) {
98
- ets_puts_P ( PSTR ( "\nSoft WDT reset\n" ) );
118
+ ets_printf_P ( "\nSoft WDT reset\n" );
99
119
}
100
120
101
121
uint32_t cont_stack_start = (uint32_t ) & (g_cont .stack );
@@ -117,17 +137,17 @@ void __wrap_system_restart_local() {
117
137
}
118
138
119
139
if (sp > cont_stack_start && sp < cont_stack_end ) {
120
- ets_puts_P ( PSTR ( "\nctx: cont \n" ) );
140
+ ets_printf_P ( "\nctx: cont \n" );
121
141
stack_end = cont_stack_end ;
122
142
}
123
143
else {
124
- ets_puts_P (( "\nctx: sys \n" ) );
144
+ ets_printf_P ( "\nctx: sys \n" );
125
145
stack_end = 0x3fffffb0 ;
126
146
// it's actually 0x3ffffff0, but the stuff below ets_run
127
147
// is likely not really relevant to the crash
128
148
}
129
149
130
- ets_printf ("sp: %08x end: %08x offset: %04x\n" , sp , stack_end , offset );
150
+ ets_printf_P ("sp: %08x end: %08x offset: %04x\n" , sp , stack_end , offset );
131
151
132
152
// print_pcs(sp + offset, stack_end);
133
153
print_stack (sp + offset , stack_end );
@@ -139,34 +159,34 @@ void __wrap_system_restart_local() {
139
159
}
140
160
141
161
142
- static void print_stack (uint32_t start , uint32_t end ) {
143
- ets_puts_P ( PSTR ( "\n>>>stack>>>\n" ) );
162
+ static void ICACHE_RAM_ATTR print_stack (uint32_t start , uint32_t end ) {
163
+ ets_printf_P ( "\n>>>stack>>>\n" );
144
164
for (uint32_t pos = start ; pos < end ; pos += 0x10 ) {
145
165
uint32_t * values = (uint32_t * )(pos );
146
166
147
167
// rough indicator: stack frames usually have SP saved as the second word
148
168
bool looksLikeStackFrame = (values [2 ] == pos + 0x10 );
149
169
150
- ets_printf ("%08x: %08x %08x %08x %08x %c\n" ,
170
+ ets_printf_P ("%08x: %08x %08x %08x %08x %c\n" ,
151
171
pos , values [0 ], values [1 ], values [2 ], values [3 ], (looksLikeStackFrame )?'<' :' ' );
152
172
}
153
- ets_puts_P ( PSTR ( "<<<stack<<<\n" ) );
173
+ ets_printf_P ( "<<<stack<<<\n" );
154
174
}
155
175
156
176
/*
157
- static void print_pcs(uint32_t start, uint32_t end) {
177
+ static void ICACHE_RAM_ATTR print_pcs(uint32_t start, uint32_t end) {
158
178
uint32_t n = 0;
159
- ets_printf ("\n>>>pc>>>\n");
179
+ ets_printf_P ("\n>>>pc>>>\n");
160
180
for (uint32_t pos = start; pos < end; pos += 16, ++n) {
161
181
uint32_t* sf = (uint32_t*) pos;
162
182
163
183
uint32_t pc_ret = sf[3];
164
184
uint32_t sp_ret = sf[2];
165
185
if (pc_ret < 0x40000000 || pc_ret > 0x40f00000 || sp_ret != pos + 16)
166
186
continue;
167
- ets_printf ("%08x\n", pc_ret);
187
+ ets_printf_P ("%08x\n", pc_ret);
168
188
}
169
- ets_printf ("<<<pc<<<\n");
189
+ ets_printf_P ("<<<pc<<<\n");
170
190
}
171
191
*/
172
192
@@ -203,17 +223,18 @@ void abort(){
203
223
}
204
224
205
225
void __assert_func (const char * file , int line , const char * func , const char * what ) {
206
- (void ) what ;
207
226
s_panic_file = file ;
208
227
s_panic_line = line ;
209
228
s_panic_func = func ;
229
+ s_panic_what = what ;
210
230
gdb_do_break ();
211
231
}
212
232
213
233
void __panic_func (const char * file , int line , const char * func ) {
214
234
s_panic_file = file ;
215
235
s_panic_line = line ;
216
236
s_panic_func = func ;
237
+ s_panic_what = 0 ;
217
238
gdb_do_break ();
218
239
abort ();
219
240
}
0 commit comments