Teensy 3 halting debug enabled by default?!

cmason

Well-known member
It seems that the Teensy 3 is being set up by default with hardware debug enabled. This makes it difficult or impossible to use the software-based DebugMonitor facilities, because any debug event will halt the core, and because there's no USB JTAG/Serial Wire Debug exposure (yet?), it's not possible to actually make use of halting debug (short of soldering directly to the chip).

The "Cortex M4 Technical Reference Manual" indicates (pg 8-5) that the reset state of the DFSR (0xE000ED30) register is 0. I'm hoping this means that the bootloader firmware is enabling hardware debug explicitly. It's not possible to reset this bit in software.

This sort of puts a skewer in my hope to implement a debug monitor in the teensy directly (as opposed to using JTAG or Serial Wire Debug). I would think that when a hardware debugger is attached, it would turn on the hardware debug support, but that by default, the Teensy would allow software debugging.

Paul, I know you were reticent to talk about the debug capabilities, but can you confirm that hardware debug is enabled and if so if it would be possible to change this?

-c


Code:
// Debug Exception and Monitor Control Register (DEMCR), ARMv7 ref manual, Table C1-12, Page 568.
#define DEMCR *((uint32_t*)0xE000EDFC)
#define DEMCR_TRCENA 1 << 24
#define DEMCR_MON_REQ 1 << 19
#define DEMCR_MON_STEP << 18
#define DEMCR_MON_PEND 1 << 17
#define DEMCR_MON_EN 1 << 16


// Debug Watchpoint and Trace Control Register (DWT_CTRL), ARMv7 ref manual, Table C1-24, page 592.
#define DWT_CTRL_ADDR (uint32_t*)0xE0001000
#define DWT_CTRL_NUMCOMP ((* DWT_CTRL_ADDR) & 0xF0000000) >> 28

// Table C1-23
#define DWT_COMPN(n) *((uint32_t*)0xE0001020+(n << 4))
#define DWT_MASKN(n) *((uint32_t*)0xE0001024+(n << 4))
#define DWT_FUNCTIONN(n) *((uint32_t*)0xE0001028+(n << 4))
#define DWT_FUNCTION_DATA_WATCHPOINT_READ_ONLY 0b0101
#define DWT_FUNCTION_DATA_WATCHPOINT_WRITE_ONLY 0b0101
#define DWT_FUNCTION_DATA_WATCHPOINT_READ_WRITE 0b0111
#define DWT_FUNCTION_PC_WATCHPOINT 0b0100

// Debug Halting Control and Status Register (DHCSR), ARMv7 ref manual, Table C1-9, page 564
#define DHCSR *((uint32_t*)0xE000EDF0)
#define DHCSR_C_DEBUGEN 1

Serial.print("Halting debug is ");
Serial.print((DHCSR & DHCSR_C_DEBUGEN) ? "ON, agh" : "OFF");
Serial.println(".");

// Turn on the Debug facilities in the chip, and also enable the DebugMonitor exception.
DEMCR = DEMCR_TRCENA | DEMCR_MON_EN;
Serial.print("Hello, world, we have ");
// Test for debug support.
if (DEMCR & DEMCR_TRCENA) {
	DWT_MASKN(0) = -1;
	Serial.print(DWT_CTRL_NUMCOMP);
	Serial.print(" debug comparators and the mask sizes are ");
	for (int i = 0; i < DWT_CTRL_NUMCOMP; ++i) {
		if (i != 0) Serial.print(", ");
		Serial.print(DWT_MASKN(i), 16);
	}
} else {
	Serial.print("no debug support");
}
Serial.print(".");
Serial.println();

Serial.flush();
delay(5000);

uint32_t * heap = (uint32_t*)sbrk(500);

Serial.print("Heap is 0x");
Serial.print((uint32_t)heap, 16);
Serial.println();

DWT_COMPN(0) = (uint32_t)heap ;
DWT_MASKN(0) = 0x1;
DWT_FUNCTIONN(0) = DWT_FUNCTION_DATA_WATCHPOINT_READ_WRITE;

Serial.print("Added debug comparator at 0x");
Serial.print(DWT_COMPN(0), 16);
Serial.print(" with mask 0x");
Serial.print(DWT_MASKN(0), 16);
Serial.print(" and function 0b" );
Serial.print(DWT_FUNCTIONN(0), 2);
Serial.println(".");

Serial.flush();
delay(5000);

// crash -- hard, because halting debug is enabled.
*heap = 1;
 
Yes, halting mode is enabled. Currently it's only used for the auto-reset feature, but I plan to do much, much more in several months. I can't discuss those plans at this time.
 
Back
Top