My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

backtrace.cpp 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #if defined(__arm__) || defined(__thumb__)
  23. #include "backtrace.h"
  24. #include "unwinder.h"
  25. #include "unwmemaccess.h"
  26. #include "../HAL_MinSerial.h"
  27. #include <stdarg.h>
  28. // Dump a backtrace entry
  29. static bool UnwReportOut(void *ctx, const UnwReport *bte) {
  30. int *p = (int*)ctx;
  31. (*p)++;
  32. const uint32_t a = bte->address, f = bte->function;
  33. MinSerial::TX('#'); MinSerial::TXDec(*p); MinSerial::TX(" : ");
  34. MinSerial::TX(bte->name?:"unknown"); MinSerial::TX('@'); MinSerial::TXHex(f);
  35. MinSerial::TX('+'); MinSerial::TXDec(a - f);
  36. MinSerial::TX(" PC:"); MinSerial::TXHex(a);
  37. MinSerial::TX('\n');
  38. return true;
  39. }
  40. #ifdef UNW_DEBUG
  41. void UnwPrintf(const char *format, ...) {
  42. char dest[256];
  43. va_list argptr;
  44. va_start(argptr, format);
  45. vsprintf(dest, format, argptr);
  46. va_end(argptr);
  47. MinSerial::TX(&dest[0]);
  48. }
  49. #endif
  50. /* Table of function pointers for passing to the unwinder */
  51. static const UnwindCallbacks UnwCallbacks = {
  52. UnwReportOut,
  53. UnwReadW,
  54. UnwReadH,
  55. UnwReadB
  56. #ifdef UNW_DEBUG
  57. , UnwPrintf
  58. #endif
  59. };
  60. // Perform a backtrace to the serial port
  61. void backtrace() {
  62. unsigned long sp = 0, lr = 0, pc = 0;
  63. // Capture the values of the registers to perform the traceback
  64. __asm__ __volatile__ (
  65. " mov %[lrv],lr\n"
  66. " mov %[spv],sp\n"
  67. " mov %[pcv],pc\n"
  68. : [spv]"+r"( sp ),
  69. [lrv]"+r"( lr ),
  70. [pcv]"+r"( pc )
  71. ::
  72. );
  73. backtrace_ex(sp, lr, pc);
  74. }
  75. void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc) {
  76. UnwindFrame btf;
  77. // Fill the traceback structure
  78. btf.sp = sp;
  79. btf.fp = btf.sp;
  80. btf.lr = lr;
  81. btf.pc = pc | 1; // Force Thumb, as CORTEX only support it
  82. // Perform a backtrace
  83. MinSerial::TX("Backtrace:");
  84. int ctr = 0;
  85. UnwindStart(&btf, &UnwCallbacks, &ctr);
  86. }
  87. #else // !__arm__ && !__thumb__
  88. void backtrace() {}
  89. #endif // __arm__ || __thumb__