mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-31 15:41:02 +08:00
feat(gdbstub): modify GDB stub for ESP8266
This commit is contained in:
@ -178,6 +178,15 @@ config ESP_PANIC_SILENT_REBOOT
|
||||
bool "Silent reboot"
|
||||
help
|
||||
Just resets the processor without outputting anything
|
||||
|
||||
config ESP_PANIC_GDBSTUB
|
||||
bool "Invoke GDBStub"
|
||||
select ESP_GDBSTUB_ENABLED
|
||||
help
|
||||
Invoke gdbstub on the serial port, allowing for gdb to attach to it to do a postmortem
|
||||
of the crash.
|
||||
|
||||
The UART's baudrate should be 115200 or others which can be recognized by xtensa GDB.
|
||||
endchoice
|
||||
|
||||
config MAIN_TASK_STACK_SIZE
|
||||
|
@ -8,6 +8,5 @@ set(esp_gdbstub_srcs "src/gdbstub.c"
|
||||
idf_component_register(SRCS "${esp_gdbstub_srcs}"
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_INCLUDE_DIRS "private_include" "${target}" "xtensa"
|
||||
LDFRAGMENTS "linker.lf"
|
||||
REQUIRES "freertos"
|
||||
PRIV_REQUIRES "soc" "xtensa" "esp_rom")
|
||||
PRIV_REQUIRES "esp8266")
|
||||
|
@ -1,4 +1,3 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := private_include esp32 xtensa
|
||||
COMPONENT_SRCDIRS := src esp32 xtensa
|
||||
COMPONENT_ADD_LDFRAGMENTS += linker.lf
|
||||
COMPONENT_PRIV_INCLUDEDIRS := private_include esp8266 xtensa
|
||||
COMPONENT_SRCDIRS := src esp8266 xtensa
|
||||
|
@ -12,10 +12,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "soc/uart_periph.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "esp_gdbstub_common.h"
|
||||
#include "esp8266/uart_register.h"
|
||||
#include "esp8266/eagle_soc.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_task_wdt.h"
|
||||
|
||||
#define UART_NUM CONFIG_CONSOLE_UART_NUM
|
||||
|
||||
@ -25,23 +25,24 @@ void esp_gdbstub_target_init(void)
|
||||
|
||||
int esp_gdbstub_getchar(void)
|
||||
{
|
||||
while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_RXFIFO_CNT) == 0) {
|
||||
;
|
||||
while (((READ_PERI_REG(UART_STATUS(UART_NUM)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT) == 0) {
|
||||
esp_task_wdt_reset();
|
||||
}
|
||||
return REG_READ(UART_FIFO_REG(UART_NUM));
|
||||
return READ_PERI_REG(UART_FIFO(UART_NUM));
|
||||
}
|
||||
|
||||
void esp_gdbstub_putchar(int c)
|
||||
{
|
||||
while (REG_GET_FIELD(UART_STATUS_REG(UART_NUM), UART_TXFIFO_CNT) >= 126) {
|
||||
while (((READ_PERI_REG(UART_STATUS(UART_NUM)) >> UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT) >= 126) {
|
||||
;
|
||||
}
|
||||
REG_WRITE(UART_FIFO_REG(UART_NUM), c);
|
||||
|
||||
WRITE_PERI_REG(UART_FIFO(UART_NUM) , c);
|
||||
}
|
||||
|
||||
int esp_gdbstub_readmem(intptr_t addr)
|
||||
{
|
||||
if (addr < 0x20000000 || addr >= 0x80000000) {
|
||||
if (addr < 0x3ff00000 || addr >= 0x60010000) {
|
||||
/* see cpu_configure_region_protection */
|
||||
return -1;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
[mapping:esp_gdbstub]
|
||||
archive: libesp_gdbstub.a
|
||||
entries:
|
||||
if ESP32_PANIC_HANDLER_IRAM = y:
|
||||
* (noflash_text)
|
||||
else:
|
||||
* (default)
|
@ -25,8 +25,8 @@ typedef XtExcFrame esp_gdbstub_frame_t;
|
||||
|
||||
/* GDB regfile structure, configuration dependent */
|
||||
typedef struct {
|
||||
uint32_t pc;
|
||||
uint32_t a[XCHAL_NUM_AREGS];
|
||||
uint32_t pc;
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
uint32_t lbeg;
|
||||
@ -36,6 +36,8 @@ typedef struct {
|
||||
|
||||
uint32_t sar;
|
||||
|
||||
uint32_t litbase;
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
uint32_t windowbase;
|
||||
uint32_t windowstart;
|
||||
|
@ -15,13 +15,14 @@
|
||||
#include <string.h>
|
||||
#include "esp_gdbstub.h"
|
||||
#include "esp_gdbstub_common.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
#include "esp8266/eagle_soc.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if !XCHAL_HAVE_WINDOWED
|
||||
#warning "gdbstub_xtensa: revisit the implementation for Call0 ABI"
|
||||
#endif
|
||||
inline static bool esp_stack_ptr_is_sane(uint32_t sp)
|
||||
{
|
||||
//Check if stack ptr is in between SOC_DRAM_LOW and SOC_DRAM_HIGH, and 16 byte aligned.
|
||||
return !(!IS_DRAM(sp) || ((sp & 0xF) != 0));
|
||||
}
|
||||
|
||||
static void init_regfile(esp_gdbstub_gdb_regfile_t *dst)
|
||||
{
|
||||
@ -36,10 +37,12 @@ static void update_regfile_common(esp_gdbstub_gdb_regfile_t *dst)
|
||||
if (!esp_stack_ptr_is_sane(dst->a[1])) {
|
||||
dst->a[1] = 0xDEADBEEF;
|
||||
}
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
dst->windowbase = 0;
|
||||
dst->windowstart = 0x1;
|
||||
RSR(CONFIGID0, dst->configid0);
|
||||
RSR(CONFIGID1, dst->configid1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_gdbstub_frame_to_regfile(const esp_gdbstub_frame_t *frame, esp_gdbstub_gdb_regfile_t *dst)
|
||||
@ -51,9 +54,11 @@ void esp_gdbstub_frame_to_regfile(const esp_gdbstub_frame_t *frame, esp_gdbstub_
|
||||
for (int i = 0; i < 16; i++) {
|
||||
dst->a[i] = a_regs[i];
|
||||
}
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
for (int i = 16; i < 64; i++) {
|
||||
dst->a[i] = 0xDEADBEEF;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
dst->lbeg = frame->lbeg;
|
||||
@ -78,9 +83,11 @@ static void solicited_frame_to_regfile(const XtSolFrame *frame, esp_gdbstub_gdb_
|
||||
for (int i = 0; i < 4; i++) {
|
||||
dst->a[i] = a_regs[i];
|
||||
}
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
for (int i = 4; i < 64; i++) {
|
||||
dst->a[i] = 0xDEADBEEF;
|
||||
}
|
||||
#endif
|
||||
|
||||
dst->ps = (frame->ps & PS_UM) ? (frame->ps & ~PS_EXCM) : frame->ps;
|
||||
update_regfile_common(dst);
|
||||
|
@ -5098,6 +5098,89 @@ const TickType_t xConstTickCount = xTickCount;
|
||||
#endif /* INCLUDE_vTaskSuspend */
|
||||
}
|
||||
|
||||
#if ( configENABLE_TASK_SNAPSHOT == 1 )
|
||||
static void prvTaskGetSnapshot( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, TCB_t *pxTCB )
|
||||
{
|
||||
if (pxTCB == NULL) {
|
||||
return;
|
||||
}
|
||||
pxTaskSnapshotArray[ *uxTask ].pxTCB = pxTCB;
|
||||
pxTaskSnapshotArray[ *uxTask ].pxTopOfStack = (StackType_t *)pxTCB->pxTopOfStack;
|
||||
#if( portSTACK_GROWTH < 0 )
|
||||
{
|
||||
pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxEndOfStack;
|
||||
}
|
||||
#else
|
||||
{
|
||||
pxTaskSnapshotArray[ *uxTask ].pxEndOfStack = pxTCB->pxStack;
|
||||
}
|
||||
#endif
|
||||
(*uxTask)++;
|
||||
}
|
||||
|
||||
static void prvTaskGetSnapshotsFromList( TaskSnapshot_t *pxTaskSnapshotArray, UBaseType_t *uxTask, const UBaseType_t uxArraySize, List_t *pxList )
|
||||
{
|
||||
TCB_t *pxNextTCB, *pxFirstTCB;
|
||||
|
||||
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
|
||||
do
|
||||
{
|
||||
if( *uxTask >= uxArraySize )
|
||||
break;
|
||||
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
|
||||
prvTaskGetSnapshot( pxTaskSnapshotArray, uxTask, pxNextTCB );
|
||||
} while( pxNextTCB != pxFirstTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
|
||||
UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz )
|
||||
{
|
||||
UBaseType_t uxTask = 0, i = 0;
|
||||
|
||||
|
||||
*pxTcbSz = sizeof(TCB_t);
|
||||
/* Fill in an TaskStatus_t structure with information on each
|
||||
task in the Ready state. */
|
||||
i = configMAX_PRIORITIES;
|
||||
do
|
||||
{
|
||||
i--;
|
||||
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &( pxReadyTasksLists[ i ] ) );
|
||||
} while( i > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||
|
||||
/* Fill in an TaskStatus_t structure with information on each
|
||||
task in the Blocked state. */
|
||||
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, ( List_t * ) pxDelayedTaskList );
|
||||
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, ( List_t * ) pxOverflowDelayedTaskList );
|
||||
for (i = 0; i < portNUM_PROCESSORS; i++) {
|
||||
if( uxTask >= uxArraySize )
|
||||
break;
|
||||
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &xPendingReadyList );
|
||||
}
|
||||
|
||||
#if( INCLUDE_vTaskDelete == 1 )
|
||||
{
|
||||
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &xTasksWaitingTermination );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||
{
|
||||
prvTaskGetSnapshotsFromList( pxTaskSnapshotArray, &uxTask, uxArraySize, &xSuspendedTaskList );
|
||||
}
|
||||
#endif
|
||||
return uxTask;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Code below here allows additional code to be inserted into this source file,
|
||||
especially where access to file scope functions and data is needed (for example
|
||||
when performing module tests). */
|
||||
|
@ -2359,6 +2359,28 @@ void *pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
|
||||
*/
|
||||
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* Used with the uxTaskGetSnapshotAll() function to save memory snapshot of each task in the system.
|
||||
* We need this struct because TCB_t is defined (hidden) in tasks.c.
|
||||
*/
|
||||
typedef struct xTASK_SNAPSHOT
|
||||
{
|
||||
void *pxTCB; /*!< Address of task control block. */
|
||||
StackType_t *pxTopOfStack; /*!< Points to the location of the last item placed on the tasks stack. */
|
||||
StackType_t *pxEndOfStack; /*!< Points to the end of the stack. pxTopOfStack < pxEndOfStack, stack grows hi2lo
|
||||
pxTopOfStack > pxEndOfStack, stack grows lo2hi*/
|
||||
} TaskSnapshot_t;
|
||||
|
||||
/*
|
||||
* This function fills array with TaskSnapshot_t structures for every task in the system.
|
||||
* Used by core dump facility to get snapshots of all tasks in the system.
|
||||
* Only available when configENABLE_TASK_SNAPSHOT is set to 1.
|
||||
* @param pxTaskSnapshotArray Pointer to array of TaskSnapshot_t structures to store tasks snapshot data.
|
||||
* @param uxArraySize Size of tasks snapshots array.
|
||||
* @param pxTcbSz Pointer to store size of TCB.
|
||||
* @return Number of elements stored in array.
|
||||
*/
|
||||
UBaseType_t uxTaskGetSnapshotAll( TaskSnapshot_t * const pxTaskSnapshotArray, const UBaseType_t uxArraySize, UBaseType_t * const pxTcbSz );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -182,5 +182,9 @@ uint32_t esp_get_time(void);
|
||||
#define configIDLE_TASK_STACK_SIZE CONFIG_FREERTOS_IDLE_TASK_STACKSIZE
|
||||
#endif /* configIDLE_TASK_STACK_SIZE */
|
||||
|
||||
#ifndef configENABLE_TASK_SNAPSHOT
|
||||
#define configENABLE_TASK_SNAPSHOT 1
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
||||
|
@ -63,22 +63,25 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portCHAR int8_t
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE unsigned char
|
||||
#define portBASE_TYPE long
|
||||
#define portLONG int32_t
|
||||
#define portSHORT int16_t
|
||||
#define portSTACK_TYPE uint8_t
|
||||
#define portBASE_TYPE int
|
||||
|
||||
#define BaseType_t portBASE_TYPE
|
||||
#define TickType_t unsigned portLONG
|
||||
#define UBaseType_t unsigned portBASE_TYPE
|
||||
#define StackType_t portSTACK_TYPE
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef portBASE_TYPE BaseType_t;
|
||||
typedef unsigned portBASE_TYPE UBaseType_t;
|
||||
|
||||
typedef unsigned portLONG portTickType;
|
||||
typedef unsigned int INT32U;
|
||||
#define portMAX_DELAY ( portTickType ) 0xffffffff
|
||||
#if( configUSE_16_BIT_TICKS == 1 )
|
||||
typedef uint16_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||
#else
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
@ -131,6 +134,7 @@ void PortEnableInt_NoNest( void );
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
#define xPortGetCoreID() 0
|
||||
#define xTaskGetCurrentTaskHandleForCPU(_cpu) xTaskGetCurrentTaskHandle()
|
||||
|
||||
// no need to disable/enable lvl1 isr again in ISR
|
||||
//#define portSET_INTERRUPT_MASK_FROM_ISR() PortDisableInt_NoNest()
|
||||
|
@ -30,6 +30,7 @@ NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
|
||||
#include <xtensa/config/tie.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
#include <xtensa/xtruntime-frames.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -79,6 +80,52 @@ space to help manage the spilling of the register windows.
|
||||
#define XT_STK_SAR 0x4C
|
||||
#define XT_STK_EXCCAUSE 0x50
|
||||
|
||||
#define XT_STK_EXCVADDR 0x54
|
||||
|
||||
STRUCT_BEGIN
|
||||
STRUCT_FIELD (long, 4, XT_STK_EXIT, exit) /* exit point for dispatch */
|
||||
STRUCT_FIELD (long, 4, XT_STK_PC, pc) /* return PC */
|
||||
STRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */
|
||||
STRUCT_FIELD (long, 4, XT_STK_A0, a0)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A1, a1) /* stack pointer before interrupt */
|
||||
STRUCT_FIELD (long, 4, XT_STK_A2, a2)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A3, a3)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A4, a4)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A5, a5)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A6, a6)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A7, a7)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A8, a8)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A9, a9)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A10, a10)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A11, a11)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A12, a12)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A13, a13)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A14, a14)
|
||||
STRUCT_FIELD (long, 4, XT_STK_A15, a15)
|
||||
STRUCT_FIELD (long, 4, XT_STK_SAR, sar)
|
||||
STRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
|
||||
STRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
STRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg)
|
||||
STRUCT_FIELD (long, 4, XT_STK_LEND, lend)
|
||||
STRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
|
||||
#endif
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* Temporary space for saving stuff during window spill */
|
||||
STRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0)
|
||||
STRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1)
|
||||
STRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2)
|
||||
#endif
|
||||
#ifdef XT_USE_SWPRI
|
||||
/* Storage for virtual priority mask */
|
||||
STRUCT_FIELD (long, 4, XT_STK_VPRI, vpri)
|
||||
#endif
|
||||
#ifdef XT_USE_OVLY
|
||||
/* Storage for overlay state */
|
||||
STRUCT_FIELD (long, 4, XT_STK_OVLY, ovly)
|
||||
#endif
|
||||
STRUCT_END(XtExcFrame)
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
#define XT_STK_LBEG 0x50
|
||||
#define XT_STK_LEND 0x54
|
||||
@ -115,6 +162,49 @@ Windowed -
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
SOLICITED STACK FRAME FOR A THREAD
|
||||
|
||||
A stack frame of this structure is allocated whenever a thread enters the
|
||||
RTOS kernel intentionally (and synchronously) to submit to thread scheduling.
|
||||
It goes on the current thread's stack.
|
||||
|
||||
The solicited frame only includes registers that are required to be preserved
|
||||
by the callee according to the compiler's ABI conventions, some space to save
|
||||
the return address for returning to the caller, and the caller's PS register.
|
||||
|
||||
For Windowed ABI, this stack frame includes the caller's base save area.
|
||||
|
||||
Note on XT_SOL_EXIT field:
|
||||
It is necessary to distinguish a solicited from an interrupt stack frame.
|
||||
This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
|
||||
always at the same offset (0). It can be written with a code (usually 0)
|
||||
to distinguish a solicted frame from an interrupt frame. An RTOS port may
|
||||
opt to ignore this field if it has another way of distinguishing frames.
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
STRUCT_BEGIN
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, a0)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A12, a1) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A13, a2)
|
||||
#else
|
||||
STRUCT_FIELD (long, 4, XT_SOL_EXIT, exit)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PC, pc)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_PS, ps)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_NEXT, next)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A0, a0) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A1, a1)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A2, a2)
|
||||
STRUCT_FIELD (long, 4, XT_SOL_A3, a3)
|
||||
#endif
|
||||
STRUCT_END(XtSolFrame)
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
SOLICTED STACK FRAME FOR A THREAD
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "freertos/xtensa_context.h"
|
||||
|
||||
#define PANIC(_fmt, ...) ets_printf(_fmt, ##__VA_ARGS__)
|
||||
|
||||
@ -42,39 +43,14 @@
|
||||
#define ESP_PANIC_PRINT
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ESP_PANIC_GDBSTUB)
|
||||
#define ESP_PANIC_GDBSTUB
|
||||
#else
|
||||
#undef ESP_PANIC_GDBSTUB
|
||||
#endif
|
||||
|
||||
#ifdef ESP_PANIC_PRINT
|
||||
|
||||
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 void panic_frame(panic_frame_t *frame)
|
||||
static inline void panic_frame(XtExcFrame *frame)
|
||||
{
|
||||
static const char *sdesc[] = {
|
||||
"PC", "PS", "A0", "A1",
|
||||
@ -161,6 +137,11 @@ void panicHandler(void *frame, int wdt)
|
||||
|
||||
#ifdef ESP_PANIC_REBOOT
|
||||
esp_panic_reset();
|
||||
#elif defined(ESP_PANIC_GDBSTUB)
|
||||
extern void esp_gdbstub_panic_handler(void *frame);
|
||||
|
||||
PANIC("Entering gdb stub now.\r\n");
|
||||
esp_gdbstub_panic_handler(frame);
|
||||
#else
|
||||
while (1) {
|
||||
esp_task_wdt_reset();
|
||||
|
@ -78,7 +78,7 @@ uint8_t *__cpu_init_stk(uint8_t *stack_top, void (*_entry)(void *), void *param,
|
||||
uint32_t *sp, *tp, *stk = (uint32_t *)stack_top;
|
||||
|
||||
/* Create interrupt stack frame aligned to 16 byte boundary */
|
||||
sp = (uint32_t *)(((INT32U)(stk + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
|
||||
sp = (uint32_t *)(((uint32_t)(stk + 1) - XT_CP_SIZE - XT_STK_FRMSZ) & ~0xf);
|
||||
|
||||
/* Clear the entire frame (do not use memset() because we don't depend on C library) */
|
||||
for (tp = sp; tp <= stk; ++tp) {
|
||||
@ -88,7 +88,7 @@ uint8_t *__cpu_init_stk(uint8_t *stack_top, void (*_entry)(void *), void *param,
|
||||
/* Explicitly initialize certain saved registers */
|
||||
SET_STKREG(XT_STK_PC, _entry); /* task entrypoint */
|
||||
SET_STKREG(XT_STK_A0, _exit); /* to terminate GDB backtrace */
|
||||
SET_STKREG(XT_STK_A1, (INT32U)sp + XT_STK_FRMSZ); /* physical top of stack frame */
|
||||
SET_STKREG(XT_STK_A1, (uint32_t)sp + XT_STK_FRMSZ); /* physical top of stack frame */
|
||||
SET_STKREG(XT_STK_A2, param); /* parameters */
|
||||
SET_STKREG(XT_STK_EXIT, _xt_user_exit); /* user exception exit dispatcher */
|
||||
|
||||
|
@ -446,7 +446,7 @@ void pthread_exit(void *value_ptr)
|
||||
}
|
||||
xSemaphoreGive(s_threads_mux);
|
||||
|
||||
ESP_LOGD(TAG, "Task stk_wm = %ld", uxTaskGetStackHighWaterMark(NULL));
|
||||
ESP_LOGD(TAG, "Task stk_wm = %u", uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
if (detached) {
|
||||
vTaskDelete(NULL);
|
||||
|
@ -285,7 +285,7 @@ void aws_iot_task(void *param) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Stack remaining for task '%s' is %lu bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
|
||||
ESP_LOGI(TAG, "Stack remaining for task '%s' is %u bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
sprintf(cPayload, "%s : %d ", "hello from ESP32 (QOS0)", i++);
|
||||
paramsQOS0.payloadLen = strlen(cPayload);
|
||||
|
@ -324,7 +324,7 @@ void aws_iot_task(void *param) {
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "*****************************************************************************************");
|
||||
ESP_LOGI(TAG, "Stack remaining for task '%s' is %lu bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
|
||||
ESP_LOGI(TAG, "Stack remaining for task '%s' is %u bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
ESP_LOGI(TAG, "Free memory for application is %d bytes", esp_get_free_heap_size());
|
||||
|
||||
|
@ -22,7 +22,7 @@ struct async_resp_arg {
|
||||
esp_err_t hello_get_handler(httpd_req_t *req)
|
||||
{
|
||||
#define STR "Hello World!"
|
||||
ESP_LOGI(TAG, "Free Stack for server task: '%ld'", uxTaskGetStackHighWaterMark(NULL));
|
||||
ESP_LOGI(TAG, "Free Stack for server task: '%u'", uxTaskGetStackHighWaterMark(NULL));
|
||||
httpd_resp_send(req, STR, strlen(STR));
|
||||
return ESP_OK;
|
||||
#undef STR
|
||||
|
Reference in New Issue
Block a user