Skip to content

Commit 1d9af16

Browse files
authored
Merge branch 'master' into dynamic_sd_cache
2 parents bfc025b + 6d3f0b4 commit 1d9af16

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1596
-243
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ boards.local.txt
1919
*.gcno
2020
*.gcda
2121
*.o
22+
*.a

boards.txt

Lines changed: 232 additions & 72 deletions
Large diffs are not rendered by default.

cores/esp8266/Print.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,13 @@
3434
/* default implementation: may be overridden */
3535
size_t Print::write(const uint8_t *buffer, size_t size) {
3636
size_t n = 0;
37-
while(size--) {
38-
n += write(*buffer++);
37+
while (size--) {
38+
size_t ret = write(*buffer++);
39+
if (ret == 0) {
40+
// Write of last byte didn't complete, abort additional processing
41+
break;
42+
}
43+
n += ret;
3944
}
4045
return n;
4146
}

cores/esp8266/abi.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,28 @@
2424

2525
using __cxxabiv1::__guard;
2626

27+
// Debugging helper, last allocation which returned NULL
28+
extern void *umm_last_fail_alloc_addr;
29+
extern int umm_last_fail_alloc_size;
30+
2731
void *operator new(size_t size)
2832
{
29-
return malloc(size);
33+
void *ret = malloc(size);
34+
if (0 != size && 0 == ret) {
35+
umm_last_fail_alloc_addr = __builtin_return_address(0);
36+
umm_last_fail_alloc_size = size;
37+
}
38+
return ret;
3039
}
3140

3241
void *operator new[](size_t size)
3342
{
34-
return malloc(size);
43+
void *ret = malloc(size);
44+
if (0 != size && 0 == ret) {
45+
umm_last_fail_alloc_addr = __builtin_return_address(0);
46+
umm_last_fail_alloc_size = size;
47+
}
48+
return ret;
3549
}
3650

3751
void operator delete(void * ptr)

cores/esp8266/core_esp8266_i2s.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static uint32_t *i2s_slc_buf_pntr[SLC_BUF_CNT]; //Pointer to the I2S DMA buffer
5656
static struct slc_queue_item i2s_slc_items[SLC_BUF_CNT]; //I2S DMA buffer descriptors
5757
static uint32_t *i2s_curr_slc_buf=NULL;//current buffer for writing
5858
static int i2s_curr_slc_buf_pos=0; //position in the current buffer
59+
static void (*i2s_callback) (void)=0; //Callback function should be defined as 'void ICACHE_FLASH_ATTR function_name()', placing the function in IRAM for faster execution. Avoid long computational tasks in this function, use it to set flags and process later.
5960

6061
bool ICACHE_FLASH_ATTR i2s_is_full(){
6162
return (i2s_curr_slc_buf_pos==SLC_BUF_LEN || i2s_curr_slc_buf==NULL) && (i2s_slc_queue_len == 0);
@@ -92,10 +93,15 @@ void ICACHE_FLASH_ATTR i2s_slc_isr(void) {
9293
i2s_slc_queue_next_item(); //free space for finished_item
9394
}
9495
i2s_slc_queue[i2s_slc_queue_len++] = finished_item->buf_ptr;
96+
if (i2s_callback) i2s_callback();
9597
ETS_SLC_INTR_ENABLE();
9698
}
9799
}
98100

101+
void i2s_set_callback(void (*callback) (void)){
102+
i2s_callback = callback;
103+
}
104+
99105
void ICACHE_FLASH_ATTR i2s_slc_begin(){
100106
i2s_slc_queue_len = 0;
101107
int x, y;
@@ -248,7 +254,6 @@ float ICACHE_FLASH_ATTR i2s_get_real_rate(){
248254
return (float)I2SBASEFREQ/32/((I2SC>>I2SBD) & I2SBDM)/((I2SC >> I2SCD) & I2SCDM);
249255
}
250256

251-
252257
void ICACHE_FLASH_ATTR i2s_begin(){
253258
_i2s_sample_rate = 0;
254259
i2s_slc_begin();

cores/esp8266/core_esp8266_main.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern "C" {
3333
#include "cont.h"
3434
}
3535
#include <core_version.h>
36+
#include "gdb_hooks.h"
3637

3738
#define LOOP_TASK_PRIORITY 1
3839
#define LOOP_QUEUE_SIZE 1
@@ -137,12 +138,6 @@ static void do_global_ctors(void) {
137138
(*--p)();
138139
}
139140

140-
extern "C" void __gdb_init() {}
141-
extern "C" void gdb_init(void) __attribute__ ((weak, alias("__gdb_init")));
142-
143-
extern "C" void __gdb_do_break(){}
144-
extern "C" void gdb_do_break(void) __attribute__ ((weak, alias("__gdb_do_break")));
145-
146141
void init_done() {
147142
system_set_os_print(1);
148143
gdb_init();

cores/esp8266/core_esp8266_postmortem.c

Lines changed: 78 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,31 @@
2828
#include "esp8266_peri.h"
2929
#include "cont.h"
3030
#include "pgmspace.h"
31+
#include "gdb_hooks.h"
3132

3233
extern void __real_system_restart_local();
33-
extern void gdb_do_break();
3434

3535
extern cont_t g_cont;
3636

3737
// These will be pointers to PROGMEM const strings
3838
static const char* s_panic_file = 0;
3939
static int s_panic_line = 0;
4040
static const char* s_panic_func = 0;
41+
static const char* s_panic_what = 0;
4142

4243
static bool s_abort_called = false;
4344

44-
void uart_write_char_d(char c);
45+
void abort() __attribute__((noreturn));
46+
static void uart_write_char_d(char c);
4547
static void uart0_write_char_d(char c);
4648
static void uart1_write_char_d(char c);
4749
static void print_stack(uint32_t start, uint32_t end);
48-
//static void print_pcs(uint32_t start, uint32_t end);
4950

50-
bool __attribute((weak)) crash_for_gdb = 0;
51+
// From UMM, the last caller of a malloc/realloc/calloc which failed:
52+
extern void *umm_last_fail_alloc_addr;
53+
extern int umm_last_fail_alloc_size;
54+
55+
static void raise_exception() __attribute__((noreturn));
5156

5257
extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) {
5358
(void) rst_info;
@@ -57,18 +62,42 @@ extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack,
5762

5863
extern void custom_crash_callback( struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) __attribute__ ((weak, alias("__custom_crash_callback")));
5964

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-
}
65+
// Single, non-inlined copy of pgm_read_byte to save IRAM space (as this is not timing critical)
66+
static char ICACHE_RAM_ATTR iram_read_byte (const char *addr) {
67+
return pgm_read_byte(addr);
68+
}
69+
70+
// Required to output the s_panic_file, it's stored in PMEM
71+
#define ets_puts_P(pstr) \
72+
{ \
73+
char c; \
74+
do { \
75+
c = iram_read_byte(pstr++); \
76+
if (c) ets_putc(c); \
77+
} while (c); \
78+
}
79+
80+
// Place these strings in .text because the SPI interface may be in bad shape during an exception.
81+
#define ets_printf_P(str, ...) \
82+
{ \
83+
static const char istr[] ICACHE_RAM_ATTR = (str); \
84+
char mstr[sizeof(str)]; \
85+
for (size_t i=0; i < sizeof(str); i++) mstr[i] = iram_read_byte(&istr[i]); \
86+
ets_printf(mstr, ##__VA_ARGS__); \
6687
}
6788

6889
void __wrap_system_restart_local() {
69-
if (crash_for_gdb) *((int*)0) = 0;
7090
register uint32_t sp asm("a1");
7191

92+
if (gdb_present()) {
93+
/* When GDBStub is present, exceptions are handled by GDBStub,
94+
but Soft WDT will still call this function.
95+
Trigger an exception to break into GDB.
96+
TODO: check why gdb_do_break() or asm("break.n 0") do not
97+
break into GDB here. */
98+
raise_exception();
99+
}
100+
72101
struct rst_info rst_info = {0};
73102
system_rtc_mem_read(0, &rst_info, sizeof(rst_info));
74103
if (rst_info.reason != REASON_SOFT_WDT_RST &&
@@ -81,21 +110,25 @@ void __wrap_system_restart_local() {
81110
ets_install_putc1(&uart_write_char_d);
82111

83112
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"));
113+
ets_printf_P("\nPanic ");
114+
ets_puts_P(s_panic_file); // This is in PROGMEM, need special output because ets_printf can't handle ROM parameters
115+
ets_printf_P(":%d %s", s_panic_line, s_panic_func);
116+
if (s_panic_what) {
117+
ets_printf_P(": Assertion '");
118+
ets_puts_P(s_panic_what); // This is also in PMEM
119+
ets_printf_P("' failed.");
120+
}
121+
ets_putc('\n');
89122
}
90123
else if (s_abort_called) {
91-
ets_puts_P(PSTR("Abort called\n"));
124+
ets_printf_P("\nAbort called\n");
92125
}
93126
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",
127+
ets_printf_P("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n",
95128
rst_info.exccause, rst_info.epc1, rst_info.epc2, rst_info.epc3, rst_info.excvaddr, rst_info.depc);
96129
}
97130
else if (rst_info.reason == REASON_SOFT_WDT_RST) {
98-
ets_puts_P(PSTR("\nSoft WDT reset\n"));
131+
ets_printf_P("\nSoft WDT reset\n");
99132
}
100133

101134
uint32_t cont_stack_start = (uint32_t) &(g_cont.stack);
@@ -117,60 +150,47 @@ void __wrap_system_restart_local() {
117150
}
118151

119152
if (sp > cont_stack_start && sp < cont_stack_end) {
120-
ets_puts_P(PSTR("\nctx: cont \n"));
153+
ets_printf_P("\nctx: cont \n");
121154
stack_end = cont_stack_end;
122155
}
123156
else {
124-
ets_puts_P(("\nctx: sys \n"));
157+
ets_printf_P("\nctx: sys \n");
125158
stack_end = 0x3fffffb0;
126159
// it's actually 0x3ffffff0, but the stuff below ets_run
127160
// is likely not really relevant to the crash
128161
}
129162

130-
ets_printf("sp: %08x end: %08x offset: %04x\n", sp, stack_end, offset);
163+
ets_printf_P("sp: %08x end: %08x offset: %04x\n", sp, stack_end, offset);
131164

132-
// print_pcs(sp + offset, stack_end);
133165
print_stack(sp + offset, stack_end);
134166

167+
// Use cap-X formatting to ensure the standard EspExceptionDecoder doesn't match the address
168+
if (umm_last_fail_alloc_addr) {
169+
ets_printf("\nlast failed alloc call: %08X(%d)\n", (uint32_t)umm_last_fail_alloc_addr, umm_last_fail_alloc_size);
170+
}
171+
135172
custom_crash_callback( &rst_info, sp + offset, stack_end );
136173

137174
delayMicroseconds(10000);
138175
__real_system_restart_local();
139176
}
140177

141178

142-
static void print_stack(uint32_t start, uint32_t end) {
143-
ets_puts_P(PSTR("\n>>>stack>>>\n"));
179+
static void ICACHE_RAM_ATTR print_stack(uint32_t start, uint32_t end) {
180+
ets_printf_P("\n>>>stack>>>\n");
144181
for (uint32_t pos = start; pos < end; pos += 0x10) {
145182
uint32_t* values = (uint32_t*)(pos);
146183

147184
// rough indicator: stack frames usually have SP saved as the second word
148185
bool looksLikeStackFrame = (values[2] == pos + 0x10);
149186

150-
ets_printf("%08x: %08x %08x %08x %08x %c\n",
187+
ets_printf_P("%08x: %08x %08x %08x %08x %c\n",
151188
pos, values[0], values[1], values[2], values[3], (looksLikeStackFrame)?'<':' ');
152189
}
153-
ets_puts_P(PSTR("<<<stack<<<\n"));
190+
ets_printf_P("<<<stack<<<\n");
154191
}
155192

156-
/*
157-
static void print_pcs(uint32_t start, uint32_t end) {
158-
uint32_t n = 0;
159-
ets_printf("\n>>>pc>>>\n");
160-
for (uint32_t pos = start; pos < end; pos += 16, ++n) {
161-
uint32_t* sf = (uint32_t*) pos;
162-
163-
uint32_t pc_ret = sf[3];
164-
uint32_t sp_ret = sf[2];
165-
if (pc_ret < 0x40000000 || pc_ret > 0x40f00000 || sp_ret != pos + 16)
166-
continue;
167-
ets_printf("%08x\n", pc_ret);
168-
}
169-
ets_printf("<<<pc<<<\n");
170-
}
171-
*/
172-
173-
void uart_write_char_d(char c) {
193+
static void uart_write_char_d(char c) {
174194
uart0_write_char_d(c);
175195
uart1_write_char_d(c);
176196
}
@@ -192,29 +212,32 @@ static void uart1_write_char_d(char c) {
192212
}
193213
USF(1) = c;
194214
}
195-
void abort() __attribute__((noreturn));
196215

197-
void abort(){
198-
// cause exception
216+
static void raise_exception() {
217+
__asm__ __volatile__ ("syscall");
218+
while (1); // never reached, needed to satisfy "noreturn" attribute
219+
}
220+
221+
void abort() {
199222
s_abort_called = true;
200-
do {
201-
*((int*)0) = 0;
202-
} while(true);
223+
raise_exception();
203224
}
204225

205226
void __assert_func(const char *file, int line, const char *func, const char *what) {
206-
(void) what;
207227
s_panic_file = file;
208228
s_panic_line = line;
209229
s_panic_func = func;
210-
gdb_do_break();
230+
s_panic_what = what;
231+
gdb_do_break(); /* if GDB is not present, this is a no-op */
232+
raise_exception();
211233
}
212234

213235
void __panic_func(const char* file, int line, const char* func) {
214236
s_panic_file = file;
215237
s_panic_line = line;
216238
s_panic_func = func;
217-
gdb_do_break();
218-
abort();
239+
s_panic_what = 0;
240+
gdb_do_break(); /* if GDB is not present, this is a no-op */
241+
raise_exception();
219242
}
220243

0 commit comments

Comments
 (0)