[2.0.x] Move backtrace to a shared location (#10237)
- And implement the `backtrace()` function call2.0.x
parent
7dc256432f
commit
749f19e502
@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* Marlin 3D Printer Firmware
|
||||||
|
* Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
|
*
|
||||||
|
* Based on Sprinter and grbl.
|
||||||
|
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
|
|
||||||
|
#if defined(__arm__) || defined(__thumb__)
|
||||||
|
|
||||||
|
#include "unwinder.h"
|
||||||
|
#include "unwmemaccess.h"
|
||||||
|
#include "../Marlin.h"
|
||||||
|
|
||||||
|
// Dump a backtrace entry
|
||||||
|
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
|
||||||
|
int* p = (int*)ctx;
|
||||||
|
|
||||||
|
(*p)++;
|
||||||
|
|
||||||
|
SERIAL_CHAR('#'); SERIAL_PRINT(*p,DEC); SERIAL_ECHOPGM(" : ");
|
||||||
|
SERIAL_ECHOPGM(bte->name?bte->name:"unknown"); SERIAL_ECHOPGM("@0x"); SERIAL_PRINT(bte->function,HEX);
|
||||||
|
SERIAL_CHAR('+'); SERIAL_PRINT(bte->address - bte->function,DEC);
|
||||||
|
SERIAL_ECHOPGM(" PC:"); SERIAL_PRINT(bte->address,HEX); SERIAL_CHAR('\n');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(UNW_DEBUG)
|
||||||
|
void UnwPrintf(const char* format, ...) {
|
||||||
|
char dest[256];
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, format);
|
||||||
|
vsprintf(dest, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
TX(&dest[0]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Table of function pointers for passing to the unwinder */
|
||||||
|
static const UnwindCallbacks UnwCallbacks = {
|
||||||
|
UnwReportOut,
|
||||||
|
UnwReadW,
|
||||||
|
UnwReadH,
|
||||||
|
UnwReadB
|
||||||
|
#if defined(UNW_DEBUG)
|
||||||
|
,UnwPrintf
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void backtrace(void) {
|
||||||
|
|
||||||
|
UnwindFrame btf;
|
||||||
|
uint32_t sp,lr,pc;
|
||||||
|
|
||||||
|
// Capture the values of the registers to perform the traceback
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
" mov %[lrv],lr\n"
|
||||||
|
" mov %[spv],sp\n"
|
||||||
|
" mov %[pcv],pc\n"
|
||||||
|
: [spv]"+r"( sp ),
|
||||||
|
[lrv]"+r"( lr ),
|
||||||
|
[pcv]"+r"( pc )
|
||||||
|
::
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fill the traceback structure
|
||||||
|
btf.sp = sp;
|
||||||
|
btf.fp = btf.sp;
|
||||||
|
btf.lr = lr;
|
||||||
|
btf.pc = pc | 1; // Force Thumb, as CORTEX only support it
|
||||||
|
|
||||||
|
// Perform a backtrace
|
||||||
|
SERIAL_ERROR_START();
|
||||||
|
SERIAL_ERRORLNPGM("Backtrace:");
|
||||||
|
int ctr = 0;
|
||||||
|
UnwindStart(&btf, &UnwCallbacks, &ctr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void backtrace(void) {}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Marlin 3D Printer Firmware
|
||||||
|
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
|
*
|
||||||
|
* Based on Sprinter and grbl.
|
||||||
|
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BACKTRACE_H_
|
||||||
|
#define _BACKTRACE_H_
|
||||||
|
|
||||||
|
// Perform a backtrace to the serial port
|
||||||
|
void backtrace(void);
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,136 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
|
||||||
|
* Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle
|
||||||
|
*
|
||||||
|
* This program is PUBLIC DOMAIN.
|
||||||
|
* This means that there is no copyright and anyone is able to take a copy
|
||||||
|
* for free and use it as they wish, with or without modifications, and in
|
||||||
|
* any context, commercially or otherwise. The only limitation is that I
|
||||||
|
* don't guarantee that the software is fit for any purpose or accept any
|
||||||
|
* liability for it's use or misuse - this software is without warranty.
|
||||||
|
***************************************************************************
|
||||||
|
* File Description: Utility functions to access memory
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if defined(__arm__) || defined(__thumb__)
|
||||||
|
|
||||||
|
#include "unwmemaccess.h"
|
||||||
|
|
||||||
|
/* Validate address */
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_SAM
|
||||||
|
// For DUE, valid address ranges are
|
||||||
|
// SRAM (0x20070000 - 0x20088000) (96kb)
|
||||||
|
// FLASH (0x00080000 - 0x00100000) (512kb)
|
||||||
|
//
|
||||||
|
#define START_SRAM_ADDR 0x20070000
|
||||||
|
#define END_SRAM_ADDR 0x20088000
|
||||||
|
#define START_FLASH_ADDR 0x00080000
|
||||||
|
#define END_FLASH_ADDR 0x00100000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TARGET_LPC1768
|
||||||
|
// For LPC1769:
|
||||||
|
// SRAM (0x10000000 - 0x10008000) (32kb)
|
||||||
|
// FLASH (0x00000000 - 0x00080000) (512kb)
|
||||||
|
//
|
||||||
|
#define START_SRAM_ADDR 0x10000000
|
||||||
|
#define END_SRAM_ADDR 0x10008000
|
||||||
|
#define START_FLASH_ADDR 0x00000000
|
||||||
|
#define END_FLASH_ADDR 0x00080000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// For STM32F103CBT6
|
||||||
|
// SRAM (0x20000000 - 0x20005000) (20kb)
|
||||||
|
// FLASH (0x00000000 - 0x00020000) (128kb)
|
||||||
|
//
|
||||||
|
#define START_SRAM_ADDR 0x20000000
|
||||||
|
#define END_SRAM_ADDR 0x20005000
|
||||||
|
#define START_FLASH_ADDR 0x00000000
|
||||||
|
#define END_FLASH_ADDR 0x00020000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __STM32F1__
|
||||||
|
// For STM32F103ZET6/STM32F103VET6
|
||||||
|
// SRAM (0x20000000 - 0x20010000) (64kb)
|
||||||
|
// FLASH (0x00000000 - 0x00080000) (512kb)
|
||||||
|
//
|
||||||
|
#define START_SRAM_ADDR 0x20000000
|
||||||
|
#define END_SRAM_ADDR 0x20010000
|
||||||
|
#define START_FLASH_ADDR 0x00000000
|
||||||
|
#define END_FLASH_ADDR 0x00080000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STM32F7
|
||||||
|
// For STM32F765 in BORG
|
||||||
|
// SRAM (0x20000000 - 0x20080000) (512kb)
|
||||||
|
// FLASH (0x08000000 - 0x08100000) (1024kb)
|
||||||
|
//
|
||||||
|
#define START_SRAM_ADDR 0x20000000
|
||||||
|
#define END_SRAM_ADDR 0x20080000
|
||||||
|
#define START_FLASH_ADDR 0x08000000
|
||||||
|
#define END_FLASH_ADDR 0x08100000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __MK64FX512__
|
||||||
|
// For MK64FX512 in TEENSY 3.5
|
||||||
|
// SRAM (0x1FFF0000 - 0x20020000) (192kb)
|
||||||
|
// FLASH (0x00000000 - 0x00080000) (512kb)
|
||||||
|
//
|
||||||
|
#define START_SRAM_ADDR 0x1FFF0000
|
||||||
|
#define END_SRAM_ADDR 0x20020000
|
||||||
|
#define START_FLASH_ADDR 0x00000000
|
||||||
|
#define END_FLASH_ADDR 0x00080000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __MK66FX1M0__
|
||||||
|
// For MK66FX1M0 in TEENSY 3.6
|
||||||
|
// SRAM (0x1FFF0000 - 0x20030000) (256kb)
|
||||||
|
// FLASH (0x00000000 - 0x00140000) (1.25Mb)
|
||||||
|
//
|
||||||
|
#define START_SRAM_ADDR 0x1FFF0000
|
||||||
|
#define END_SRAM_ADDR 0x20030000
|
||||||
|
#define START_FLASH_ADDR 0x00000000
|
||||||
|
#define END_FLASH_ADDR 0x00140000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool validate_addr(uint32_t addr) {
|
||||||
|
|
||||||
|
// Address must be in SRAM range
|
||||||
|
if (addr >= START_SRAM_ADDR && addr < END_SRAM_ADDR)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Or in FLASH range
|
||||||
|
if (addr >= START_FLASH_ADDR && addr < END_FLASH_ADDR)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnwReadW(const uint32_t a, uint32_t *v) {
|
||||||
|
if (!validate_addr(a))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*v = *(uint32_t *)a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnwReadH(const uint32_t a, uint16_t *v) {
|
||||||
|
if (!validate_addr(a))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*v = *(uint16_t *)a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnwReadB(const uint32_t a, uint8_t *v) {
|
||||||
|
if (!validate_addr(a))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*v = *(uint8_t *)a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
|
||||||
|
* Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle
|
||||||
|
*
|
||||||
|
* This program is PUBLIC DOMAIN.
|
||||||
|
* This means that there is no copyright and anyone is able to take a copy
|
||||||
|
* for free and use it as they wish, with or without modifications, and in
|
||||||
|
* any context, commerically or otherwise. The only limitation is that I
|
||||||
|
* don't guarantee that the software is fit for any purpose or accept any
|
||||||
|
* liablity for it's use or misuse - this software is without warranty.
|
||||||
|
***************************************************************************
|
||||||
|
* File Description: Utility functions to access memory
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef UNWMEMACCESS_H
|
||||||
|
#define UNWMEMACCESS_H
|
||||||
|
|
||||||
|
#include "unwarm.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
bool UnwReadW(const uint32_t a, uint32_t *v);
|
||||||
|
bool UnwReadH(const uint32_t a, uint16_t *v);
|
||||||
|
bool UnwReadB(const uint32_t a, uint8_t *v);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue