atmel-samd: Add Micro Trace Buffer support to the debug build.

The Micro Trace Buffer records the history of the pc and can be used
to debug hard faults even when the stack trace is useless.
This commit is contained in:
Scott Shawcroft 2016-10-04 16:13:33 -07:00
parent 98458c56cc
commit 1fa4c20c27
3 changed files with 30 additions and 4 deletions

View File

@ -92,8 +92,10 @@ CFLAGS_CORTEX_M0 = \
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M0) $(COPT)
#Debugging/Optimization
# TODO(tannewt): Figure out what NDEBUG does. Adding it to the debug build
# reduces code size pretty dramatically.
ifeq ($(DEBUG), 1)
CFLAGS += -Os -ggdb
CFLAGS += -Os -ggdb -DNDEBUG -DENABLE_MICRO_TRACE_BUFFER
else
CFLAGS += -Os -DNDEBUG
endif

View File

@ -41,6 +41,8 @@
*
*/
#include <stdbool.h>
#include "samd21.h"
/* Initialize segments */
@ -65,7 +67,7 @@ void Dummy_Handler(void);
/* Cortex-M0+ core handlers */
void NMI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void HardFault_Handler( void ) __attribute__( ( naked ) );
void SVC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
@ -269,7 +271,17 @@ void Reset_Handler(void)
main();
/* Infinite loop */
while (1);
while (true);
}
void HardFault_Handler(void)
{
#ifdef ENABLE_MICRO_TRACE_BUFFER
// Turn off the micro trace buffer so we don't fill it up in the infinite
// loop below.
REG_MTB_MASTER = 0x00000000 + 6;
#endif
while(true) {}
}
/**
@ -277,6 +289,6 @@ void Reset_Handler(void)
*/
void Dummy_Handler(void)
{
while (1) {
while (true) {
}
}

View File

@ -270,7 +270,19 @@ void MP_WEAK __assert_func(const char *file, int line, const char *func, const c
struct usart_module usart_instance;
#ifdef ENABLE_MICRO_TRACE_BUFFER
#define TRACE_BUFFER_SIZE 256
__attribute__((__aligned__(TRACE_BUFFER_SIZE * sizeof(uint32_t)))) uint32_t mtb[TRACE_BUFFER_SIZE];
#endif
void samd21_init(void) {
#ifdef ENABLE_MICRO_TRACE_BUFFER
memset(mtb, 0, sizeof(mtb));
// AWIDTH is 15.
REG_MTB_POSITION = ((uint32_t) (mtb - REG_MTB_BASE)) & 0xFFFFFFF8;
REG_MTB_FLOW = ((uint32_t) mtb + TRACE_BUFFER_SIZE * sizeof(uint32_t)) & 0xFFFFFFF8;
REG_MTB_MASTER = 0x80000000 + 6;
#endif
irq_initialize_vectors();
cpu_irq_enable();