ATSAMD51 Atmel START dies in DefaultHandler

Project assigns gpio, sets PLL0 to 4.096MHz, calls delay_init(SysTick), initialized analog comparator with no enabled interrupts, initializes RTC in calendar mode 2 with two callbacks, initializes the DAC0 with no interrupts and launches FreeRTOS 10 with a trivial task (monitors some switches that update time and execute actions) and tick hook callback.

The system executes the task once (no actions occur, so none of them are at fault.) and executes the tick hook once. It gets here and then encounters an unhandled interrupt.

for (;;) {
	/* Query the timers list to see if it contains any timers, and if so,
	obtain the time at which the next timer will expire. */
	xNextExpireTime = prvGetNextExpireTime(&xListWasEmpty);

	/* If a timer has expired, process it.  Otherwise, block this task
	until either a timer does expire, or a command is received. */
	prvProcessTimerOrBlockTask(xNextExpireTime, xListWasEmpty);  // crashes on return

	/* Empty the command queue. */

Did you identify the unhandled interrupt and check why the corresponding ISR wasn’t installed correctly ? Or what exactly is the problem you want to solve ?

When I get an unhandled interrupt, the first thing I do is see if the hardware can tell me what interrupt it is. Often the Interrupt controller has a way to read the currently active interrupt.

If you can’t find out how to do that, duplicate the default unhandled interrupt and make each interrupt have its own so you can tell.

Once you know the interrupt, then it is normally an easier task to figure out why it occurred and why not ISR was installed.

Still learning how to do that in ARM. But only the RTC and the SysTicks should have any ISRs.

This page provides instructions

Other exceptions probably have default handlers too - such as hard fault, bus fault, etc.

On the ARM, typically the startup assembly file will declare the interrupt vectors with a weak symbol definition all stacked in a row, ending with a jump to self as a default handler. Add a jump to self between each of the definitions so you can tell which one it gets int,

If you are using a Cortex-M processor, the NVIC should have a register that tells you the current interrupt so you can read that in the debugger to see what has happened,

You may have accidentally enabled a wrong interrupt, or you program could have raised an exception from something like a bad memory access.

When I do not start FreeRTOS handler and I do enable RTC NVIC.ISER[0] is 1<<11 as expected and no others are enabled. At the point of a hard fault the ISER[x] are all zero except bit for RTC.

The once per minute ‘alarms’ of the RTC are not firing without the handler, so I suspect I was failing to enable interrupts at all until the Handler started. That could explain why I was not getting UART RXC interrupts earlier…

OK, it is the hard fault handler.

As Richard mentioned above, you can use the information on this page to find the cause of the hard fault:


That was embarrasing, since for the past decade of using FreeRTOS I have told everyone that ever worked for me never to use the default stack size…

Hardfault was identified by the assembly interpretation in default handler.
A simple assignment statement was implicated by the disassembly listing and the PC.

Commenting out everything put me in the stack overflow handler, which just never got called because the errant stack overflow caused a hard fault before the overflow was diagnosed.

Now I can get back to non RTOS issues like why my RTC alarms are not triggering and why my touch buttons are always on…