mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
arch: move debug helpers
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
// Copyright 2015-2019 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 "sdkconfig.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_debug_helpers.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
#include "soc/cpu.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
bool IRAM_ATTR esp_backtrace_get_next_frame(esp_backtrace_frame_t *frame)
|
||||
{
|
||||
//Use frame(i-1)'s BS area located below frame(i)'s sp to get frame(i-1)'s sp and frame(i-2)'s pc
|
||||
void *base_save = (void *)frame->sp; //Base save area consists of 4 words under SP
|
||||
frame->pc = frame->next_pc;
|
||||
frame->next_pc = *((uint32_t *)(base_save - 16)); //If next_pc = 0, indicates frame(i-1) is the last frame on the stack
|
||||
frame->sp = *((uint32_t *)(base_save - 12));
|
||||
|
||||
//Return true if both sp and pc of frame(i-1) are sane, false otherwise
|
||||
return (esp_stack_ptr_is_sane(frame->sp) && esp_ptr_executable((void*)esp_cpu_process_stack_pc(frame->pc)));
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR esp_backtrace_print(int depth)
|
||||
{
|
||||
//Check arguments
|
||||
if (depth <= 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
//Initialize stk_frame with first frame of stack
|
||||
esp_backtrace_frame_t stk_frame;
|
||||
esp_backtrace_get_start(&(stk_frame.pc), &(stk_frame.sp), &(stk_frame.next_pc));
|
||||
//esp_cpu_get_backtrace_start(&stk_frame);
|
||||
esp_rom_printf("\r\n\r\nBacktrace:");
|
||||
esp_rom_printf("0x%08X:0x%08X ", esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
||||
|
||||
//Check if first frame is valid
|
||||
bool corrupted = (esp_stack_ptr_is_sane(stk_frame.sp) &&
|
||||
esp_ptr_executable((void*)esp_cpu_process_stack_pc(stk_frame.pc))) ?
|
||||
false : true;
|
||||
|
||||
uint32_t i = (depth <= 0) ? INT32_MAX : depth;
|
||||
while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
|
||||
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get previous stack frame
|
||||
corrupted = true;
|
||||
}
|
||||
esp_rom_printf("0x%08X:0x%08X ", esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
|
||||
}
|
||||
|
||||
//Print backtrace termination marker
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (corrupted) {
|
||||
esp_rom_printf(" |<-CORRUPTED");
|
||||
ret = ESP_FAIL;
|
||||
} else if (stk_frame.next_pc != 0) { //Backtrace continues
|
||||
esp_rom_printf(" |<-CONTINUES");
|
||||
}
|
||||
esp_rom_printf("\r\n\r\n");
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2015-2019 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 <xtensa/coreasm.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
#include <xtensa/hal.h>
|
||||
|
||||
/*
|
||||
* esp_backtrace_get_start(uint32_t *pc, uint32_t *sp, uint32_t *next_pc)
|
||||
*
|
||||
* High Addr
|
||||
* ..................
|
||||
* | i-3 BS |
|
||||
* | i-1 locals | Function B
|
||||
* .................. i-1 SP
|
||||
* | i-2 BS |
|
||||
* | i locals | Function A (Start of backtrace)
|
||||
* ------------------ i SP
|
||||
* | i-1 BS |
|
||||
* | i+1 locals | Backtracing function (e.g. esp_backtrace_print())
|
||||
* ------------------ i+1 SP
|
||||
* | i BS |
|
||||
* | i+2 locals | esp_backtrace_get_start() <- This function
|
||||
* ------------------ i+2 SP
|
||||
* | i+1 BS |
|
||||
* | i+3 locals | xthal_window_spill()
|
||||
* ------------------ i+3 SP
|
||||
* .................. Low Addr
|
||||
*/
|
||||
.section .iram1, "ax"
|
||||
.align 4
|
||||
.global esp_backtrace_get_start
|
||||
.type esp_backtrace_get_start, @function
|
||||
esp_backtrace_get_start:
|
||||
entry a1, 32
|
||||
call8 xthal_window_spill //Spill registers onto stack (excluding this function)
|
||||
//a2, a3, a4 should be out arguments for i SP, i PC, i-1 PC respectively. Use a5 and a6 as scratch
|
||||
l32e a5, sp, -16 //Get i PC, which is ret addres of i+1
|
||||
s32i a5, a2, 0 //Store i PC to arg *pc
|
||||
l32e a6, sp, -12 //Get i+1 SP. Used to access i BS
|
||||
l32e a5, a6, -12 //Get i SP
|
||||
s32i a5, a3, 0 //Store i SP to arg *sp
|
||||
l32e a5, a6, -16 //Get i-1 PC, which is ret address of i
|
||||
s32i a5, a4, 0 //Store i-1 PC to arg *next_pc
|
||||
retw
|
||||
Reference in New Issue
Block a user