mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 04:43:33 +00:00
Merge branch 'master' of ssh://gitlab.espressif.cn:27227/idf/esp-idf into feature/throughput_optimization_phrase_1
This commit is contained in:
@@ -42,3 +42,15 @@ void IRAM_ATTR esp_cpu_unstall(int cpu_id)
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M);
|
||||
}
|
||||
}
|
||||
|
||||
bool IRAM_ATTR esp_cpu_in_ocd_debug_mode()
|
||||
{
|
||||
#if CONFIG_ESP32_DEBUG_OCDAWARE
|
||||
int dcr;
|
||||
int reg=0x10200C; //DSRSET register
|
||||
asm("rer %0,%1":"=r"(dcr):"r"(reg));
|
||||
return (dcr&0x1);
|
||||
#else
|
||||
return false; // Always return false if "OCD aware" is disabled
|
||||
#endif
|
||||
}
|
||||
|
@@ -104,4 +104,13 @@ void esp_cpu_stall(int cpu_id);
|
||||
*/
|
||||
void esp_cpu_unstall(int cpu_id);
|
||||
|
||||
/**
|
||||
* @brief Returns true if a JTAG debugger is attached to CPU
|
||||
* OCD (on chip debug) port.
|
||||
*
|
||||
* @note If "Make exception and panic handlers JTAG/OCD aware"
|
||||
* is disabled, this function always returns false.
|
||||
*/
|
||||
bool esp_cpu_in_ocd_debug_mode();
|
||||
|
||||
#endif
|
||||
|
@@ -261,6 +261,8 @@
|
||||
#define I2C_RXFIFO_FULL_THRHD_V 0x1F
|
||||
#define I2C_RXFIFO_FULL_THRHD_S 0
|
||||
|
||||
#define I2C_DATA_APB_REG(i) (0x60013000 + (i) * 0x14000 + 0x001c)
|
||||
|
||||
#define I2C_DATA_REG(i) (REG_I2C_BASE(i) + 0x001c)
|
||||
/* I2C_FIFO_RDATA : RO ;bitpos:[7:0] ;default: 8'b0 ; */
|
||||
/*description: The register represent the byte data read from rxfifo when use apb fifo access*/
|
||||
|
@@ -16,7 +16,7 @@
|
||||
typedef volatile struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t scl_low_period:14; /*This register is used to configure the low level width of SCL clock.*/
|
||||
uint32_t period:14; /*This register is used to configure the low level width of SCL clock.*/
|
||||
uint32_t reserved14: 18;
|
||||
};
|
||||
uint32_t val;
|
||||
@@ -58,7 +58,7 @@ typedef volatile struct {
|
||||
} status_reg;
|
||||
union {
|
||||
struct {
|
||||
uint32_t tout: 20; /*This register is used to configure the max clock number of receiving a data.*/
|
||||
uint32_t tout: 20; /*This register is used to configure the max clock number of receiving a data, unit: APB clock cycle.*/
|
||||
uint32_t reserved20:12;
|
||||
};
|
||||
uint32_t val;
|
||||
@@ -282,7 +282,7 @@ typedef volatile struct {
|
||||
uint32_t reserved_f4;
|
||||
uint32_t date; /**/
|
||||
uint32_t reserved_fc;
|
||||
uint32_t fifo_start_addr; /*This the start address for ram when use apb nonfifo access.*/
|
||||
uint32_t ram_data[32]; /*This the start address for ram when use apb nonfifo access.*/
|
||||
} i2c_dev_t;
|
||||
extern i2c_dev_t I2C0;
|
||||
extern i2c_dev_t I2C1;
|
||||
|
@@ -99,7 +99,7 @@ SECTIONS
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
*(.dynbss)
|
||||
KEEP(*(.bss))
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.share.mem)
|
||||
*(.gnu.linkonce.b.*)
|
||||
@@ -111,17 +111,17 @@ SECTIONS
|
||||
.dram0.data :
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
KEEP(*(.data))
|
||||
KEEP(*(.data.*))
|
||||
KEEP(*(.gnu.linkonce.d.*))
|
||||
KEEP(*(.data1))
|
||||
KEEP(*(.sdata))
|
||||
KEEP(*(.sdata.*))
|
||||
KEEP(*(.gnu.linkonce.s.*))
|
||||
KEEP(*(.sdata2))
|
||||
KEEP(*(.sdata2.*))
|
||||
KEEP(*(.gnu.linkonce.s2.*))
|
||||
KEEP(*(.jcr))
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
*(.jcr)
|
||||
*(.dram1 .dram1.*)
|
||||
*libesp32.a:panic.o(.rodata .rodata.*)
|
||||
_data_end = ABSOLUTE(.);
|
||||
|
@@ -36,7 +36,7 @@
|
||||
/*
|
||||
Panic handlers; these get called when an unhandled exception occurs or the assembly-level
|
||||
task switching / interrupt code runs into an unrecoverable error. The default task stack
|
||||
overflow handler also is in here.
|
||||
overflow handler and abort handler are also in here.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -95,15 +95,29 @@ inline static void panicPutHex(int a) { }
|
||||
inline static void panicPutDec(int a) { }
|
||||
#endif
|
||||
|
||||
|
||||
void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )
|
||||
{
|
||||
panicPutStr("***ERROR*** A stack overflow in task ");
|
||||
panicPutStr((char *)pcTaskName);
|
||||
panicPutStr(" has been detected.\r\n");
|
||||
configASSERT(0);
|
||||
abort();
|
||||
}
|
||||
|
||||
static bool abort_called;
|
||||
|
||||
void abort()
|
||||
{
|
||||
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||
ets_printf("abort() was called at PC 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3);
|
||||
#endif
|
||||
abort_called = true;
|
||||
while(1) {
|
||||
__asm__ ("break 0,0");
|
||||
*((int*) 0) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *edesc[] = {
|
||||
"IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError",
|
||||
"Level1Interrupt", "Alloca", "IntegerDivideByZero", "PCValue",
|
||||
@@ -118,7 +132,7 @@ static const char *edesc[] = {
|
||||
};
|
||||
|
||||
|
||||
void commonErrorHandler(XtExcFrame *frame);
|
||||
static void commonErrorHandler(XtExcFrame *frame);
|
||||
|
||||
//The fact that we've panic'ed probably means the other CPU is now running wild, possibly
|
||||
//messing up the serial output, so we stall it here.
|
||||
@@ -127,19 +141,6 @@ static void haltOtherCore()
|
||||
esp_cpu_stall( xPortGetCoreID() == 0 ? 1 : 0 );
|
||||
}
|
||||
|
||||
//Returns true when a debugger is attached using JTAG.
|
||||
static int inOCDMode()
|
||||
{
|
||||
#if CONFIG_ESP32_DEBUG_OCDAWARE
|
||||
int dcr;
|
||||
int reg = 0x10200C; //DSRSET register
|
||||
asm("rer %0,%1":"=r"(dcr):"r"(reg));
|
||||
return (dcr & 0x1);
|
||||
#else
|
||||
return 0; //Always return no debugger is attached.
|
||||
#endif
|
||||
}
|
||||
|
||||
void panicHandler(XtExcFrame *frame)
|
||||
{
|
||||
int *regs = (int *)frame;
|
||||
@@ -165,7 +166,7 @@ void panicHandler(XtExcFrame *frame)
|
||||
panicPutStr(reason);
|
||||
panicPutStr(")\r\n");
|
||||
|
||||
if (inOCDMode()) {
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
asm("break.n 1");
|
||||
}
|
||||
commonErrorHandler(frame);
|
||||
@@ -197,7 +198,7 @@ void xt_unhandled_exception(XtExcFrame *frame)
|
||||
}
|
||||
panicPutStr(" occurred on core ");
|
||||
panicPutDec(xPortGetCoreID());
|
||||
if (inOCDMode()) {
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
panicPutStr(" at pc=");
|
||||
panicPutHex(regs[1]);
|
||||
panicPutStr(". Setting bp and returning..\r\n");
|
||||
@@ -255,6 +256,7 @@ static inline bool stackPointerIsSane(uint32_t sp)
|
||||
{
|
||||
return !(sp < 0x3ffae010 || sp > 0x3ffffff0 || ((sp & 0xf) != 0));
|
||||
}
|
||||
|
||||
static void putEntry(uint32_t pc, uint32_t sp)
|
||||
{
|
||||
if (pc & 0x80000000) {
|
||||
@@ -265,7 +267,8 @@ static void putEntry(uint32_t pc, uint32_t sp)
|
||||
panicPutStr(":0x");
|
||||
panicPutHex(sp);
|
||||
}
|
||||
void doBacktrace(XtExcFrame *frame)
|
||||
|
||||
static void doBacktrace(XtExcFrame *frame)
|
||||
{
|
||||
uint32_t i = 0, pc = frame->pc, sp = frame->a1;
|
||||
panicPutStr("\nBacktrace:");
|
||||
@@ -291,7 +294,7 @@ void doBacktrace(XtExcFrame *frame)
|
||||
We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the
|
||||
serial port and either jump to the gdb stub, halt the CPU or reboot.
|
||||
*/
|
||||
void commonErrorHandler(XtExcFrame *frame)
|
||||
static void commonErrorHandler(XtExcFrame *frame)
|
||||
{
|
||||
int *regs = (int *)frame;
|
||||
int x, y;
|
||||
@@ -304,21 +307,28 @@ void commonErrorHandler(XtExcFrame *frame)
|
||||
//Feed the watchdogs, so they will give us time to print out debug info
|
||||
reconfigureAllWdts();
|
||||
|
||||
panicPutStr("Register dump:\r\n");
|
||||
/* only dump registers for 'real' crashes, if crashing via abort()
|
||||
the register window is no longer useful.
|
||||
*/
|
||||
if (!abort_called) {
|
||||
panicPutStr("Register dump:\r\n");
|
||||
|
||||
for (x = 0; x < 24; x += 4) {
|
||||
for (y = 0; y < 4; y++) {
|
||||
if (sdesc[x + y][0] != 0) {
|
||||
panicPutStr(sdesc[x + y]);
|
||||
panicPutStr(": 0x");
|
||||
panicPutHex(regs[x + y + 1]);
|
||||
panicPutStr(" ");
|
||||
for (x = 0; x < 24; x += 4) {
|
||||
for (y = 0; y < 4; y++) {
|
||||
if (sdesc[x + y][0] != 0) {
|
||||
panicPutStr(sdesc[x + y]);
|
||||
panicPutStr(": 0x");
|
||||
panicPutHex(regs[x + y + 1]);
|
||||
panicPutStr(" ");
|
||||
}
|
||||
}
|
||||
panicPutStr("\r\n");
|
||||
}
|
||||
panicPutStr("\r\n");
|
||||
}
|
||||
|
||||
/* With windowed ABI backtracing is easy, let's do it. */
|
||||
doBacktrace(frame);
|
||||
|
||||
#if CONFIG_ESP32_PANIC_GDBSTUB
|
||||
disableAllWdts();
|
||||
panicPutStr("Entering gdb stub now.\r\n");
|
||||
@@ -339,8 +349,7 @@ void commonErrorHandler(XtExcFrame *frame)
|
||||
|
||||
void esp_set_breakpoint_if_jtag(void *fn)
|
||||
{
|
||||
if (!inOCDMode()) {
|
||||
return;
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
setFirstBreakpoint((uint32_t)fn);
|
||||
}
|
||||
setFirstBreakpoint((uint32_t)fn);
|
||||
}
|
||||
|
Reference in New Issue
Block a user