Skip to main content
Tobe
Senior III
January 19, 2025
Question

Hard fault that happens only with debug, and using pause/start buttons

  • January 19, 2025
  • 5 replies
  • 1803 views

Hi,

i have an issue, where i implemented using DMA. The DMA works seemingly without issues, but when debugging and using the start/pause buttons, the hard fault happens.

Would the be a smart way to *simulate* a pause/start of a debug session??


EDIT:

I found out, that this issue only happens when the interrupt is activated:

 

volatile uint16_t adcArray[12]
void DMA1_Channel2_IRQHandler(){
	ADC_TEST_2_ON

	// Transfer complete
	if( READ_BIT(DMA1->IFCR, DMA_IFCR_CTCIF2) ){
		DMA1->IFCR |= (DMA_IFCR_CTCIF2);		// Clear bit transfer complete

//		tempFETBits 	= 0;
//		battVoltBits 	= 0;
//		throttleBits 	= 0;
//		buttonSensBits 	= 0;

		tempFETBits = adcArray[0];

		ADC_TEST_2_OFF;
	}

	// Transfer error
	if( READ_BIT(DMA1->IFCR, DMA_IFCR_CTEIF2) ){
		DMA1->IFCR |= (DMA_IFCR_CTEIF2);		// Clear bit
		//TODO: save event
		while(1);
	}

	ADC_TEST_2_OFF;
}

 

5 replies

waclawek.jan
Super User
January 19, 2025

Debug the hardfault. Check content of the fault registers (SCB_CFSR and its components). If you are using an IDE which provides you a backtrace (call stack, whateverisitcalled), look at the point where the fault handler was called (taking into mind that imprecise error happens a couple of instructions before that point), in mixed C-disasm view, to see what was the cause of fault.

JW

 

Tobe
TobeAuthor
Senior III
January 19, 2025

In the meanwhile, i found out, that the hardfault only happens, when i resume out of the DMA handler. But if it was resumed from the DMA handler, while other handlers happend when the DMA handler was active, then this problem does dont happen.

I dont see a problem with my program, so i would just try to work without DMA interrupt. The hard fault was a INVPC.

I wonder if it would haunt me at a later stage?

Tesla DeLorean
Guru
January 19, 2025

>>I wonder if it would haunt me at a later stage?

What part?

Suggests you're DMA is trashing, or servicing routines are trashing the stack.

Would avoid using auto/local for DMA buffers, and context/scope can change.

Watch alignment and abutting structures, especially when using cache management. The CM7 expecting 32-byte alignment.

Perhaps also watch maximal stack depth in worst-case scenarios.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Andrew Neil
Super User
January 21, 2025

@Tobe wrote:

when debugging and using the start/pause buttons, the hard fault happens.


Remember that halting debug is intrusive.

Things like timers can carry on counting, UARTs can carry on receiving while the CPU is halted - but the CPU then won't be able to action interrupts in a timely manner.

I don't know about DMA, but maybe it can keep running, but stuff falls over when the CPU is halted and unable to handle completion...?

In some cases (eg, watchdog), there are options to control what happens during a debug halt - have you checked for such options relating to DMA?

 


@Tobe wrote:

I found out, that this issue only happens when the interrupt is activated:


I'm not sure if that supports the above hypothesis or not ... ?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Tobe
TobeAuthor
Senior III
January 21, 2025

Yes, its quite complicated. Even worse, when you have to debug the debug session!

Where would i found these options for debug halt?

 

 

Andrew Neil
Super User
January 21, 2025

@Tobe wrote:

Where would i found these options for debug halt?


In the Chip's Reference Manual

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
waclawek.jan
Super User
January 21, 2025

As @Tesla DeLorean said above:

> Would avoid using auto/local for DMA buffers

JW

Tobe
TobeAuthor
Senior III
January 21, 2025
Avoid while(1) loops in IRQ?

I might have some of those in IRQs. But they work as expected: Letting the program stay at a fault.

 

Would avoid using auto/local for DMA buffers

I guess if i dont know much about this, then im doing it right? ;-)).

 

 

I have implement an eventlog, but havent done much with the DMA on it. I think the issue stems from having the DMA IRQ active, and like the DMA beeing fired. As i said, there is no problem, if inside the DMA interrupt, but while other interrupts were active.

waclawek.jan
Super User
January 21, 2025

Local variables are defined inside function. 

You want DMA buffers be defined as globals (i.e. outside functions) and volatile. 

Make sure they are big enough to accommodate all data from DMA (taking into account the memory-side transfer size set in DMA, times number of transfers).

JW

Andrew Neil
Super User
January 21, 2025

@waclawek.jan wrote:

You want DMA buffers be defined as globals (i.e. outside functions) and volatile. 


More specifically, you want them to be defined with static duration; ie, they exist for the entire duration of the program.

Unless qualified as static, local variables have automatic duration; ie, they cease to exist as soon as the function exits.

Clearly, if a DMA operation is still using  an automatic variable when the function exits - that's going to cause trouble!

 

https://en.cppreference.com/w/cpp/language/storage_duration

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Tobe
TobeAuthor
Senior III
January 22, 2025

I was considering the "local" in "auto/local" so describe something else. I would never ever consider using DMA with local variables. Then DMA would barely make any sense. I am aware, that local variables vanish.

That variable is declared as volatile. I have checked that the DMA was not writing outside of the allocated memory of the variable.

I have a faily stable program running. I had no such issues for a long time (about 500 hours).

waclawek.jan
Super User
January 22, 2025

I said, debug the hardfault. The only information you gave back was, that it's an invalid PC, from which I draw the conclusion that you may have thrashed stack.

If this is not the case, debug the hardfault. Check content of the fault registers (SCB_CFSR and its components). If you are using an IDE which provides you a backtrace (call stack, whateverisitcalled), look at the point where the fault handler was called (taking into mind that imprecise error happens a couple of instructions before that point), in mixed C-disasm view, to see what was the cause of fault. If in doubts, post info relevant to these points.

JW