Skip to main content
Associate
July 29, 2025
Question

STM32F Unexpected Hardfault cause by code not reached

  • July 29, 2025
  • 6 replies
  • 1013 views

Hi ! I'm working on a STM32F429VET, with keil as an IDE. 

My problem is the next, this code which is NOT reached (because it need a command from the terminal to be). Make my entire program crash in contact of loop, causing an IACCVIOL if i let this part of the code commented, works fine if i uncomment it. Anybody have encounter similiar behavior ? I dont get it at all.

void adc_measure(uint16_t channel, uint8_t *result)
{
 measureInProgress = true;
 adc_init(channel);

 HAL_TIM_Base_Start_IT(&htim2);

// while (measure_pending_count < NB_MEASURES)
// {
// 
// adc_read();
// __disable_irq(); // Prevent race condition
// measure_pending_count++;
// __enable_irq();
// 
// }
 

 HAL_ADC_Stop(&hadc1);
 float measure = adc_compute_value(channel); // convert the value toward needed unit (mA or V)
 //snprintf((char *)result, RESULT_PRECISION, "%f", measure);
}

 

 

 

6 replies

Andrew Neil
Super User
July 29, 2025

Are you sure it's not reached?

Have you tried setting a breakpoint in that code to confirm?

 

How to debug Hard faults:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/tac-p/708193/highlight/true#M51

 

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.
tfdeAuthor
Associate
July 30, 2025

Hi!

I did verify with a breakpoint and it is not reach.

I check your link and will write a response accordingly.

Tesla DeLorean
Guru
July 29, 2025

Instrument and root cause the Hard Fault

https://github.com/cturvey/RandomNinjaChef/blob/main/KeilHardFault.c

We lack significant context here. We don't see the fault, the variable definitions, the adc_read() function, or the initialization or handlers.

Probably something not initialized correctly prior to function entrance. Or perhaps stack overflow due to local/auto variables in one of the called routines.

Keil tend to have a very small stack allocation. Make it several KB in startup.s file, and perhaps mark it with a pattern so you make some high/low water mark determination.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
tfdeAuthor
Associate
July 30, 2025

Hi! 

I did not succeed in making the code you send me work. 

I wrote a bigger response with as much detail as i though isefull. 

I do really think its some kind of stack overflow but 1. i don't know how to prove that and 2. i dont know how to debug that. 

Andrew Neil
Super User
July 30, 2025

@tfde wrote:

I do really think its some kind of stack overflow but 1. i don't know how to prove that and 2. i dont know how to debug that. 


Take a look at Keil's Application Note AN316Determining the stack usage of applications...

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.
TDK
Super User
July 29, 2025

Code that isn't executed can't cause a hard fault. The bug is elsewhere.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Andrew Neil
Super User
July 30, 2025

@TDK wrote:

Code that isn't executed can't cause a hard fault. 


Well, ...

If it's included in the image, it can affect memory layout - which might, indirectly, lead to other things failing ...

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.
tfdeAuthor
Associate
July 30, 2025

Hi again! I wasn't expecting to have answer that fast ! 

First thanks to you three, those comment help reduce the search area.

So first, my code who is next is effectively not reach (verify by the use of bp), and now i have conclude that, if i comment adc read, everything break, and if i comment it everything is okay. 

Everything break: Meaning any loop and especially the loop in HAL_Delay() make the program hardfault.

void adc_measure(uint16_t channel, uint8_t *result)
{
	measureInProgress = true;
 adc_init(channel);

 HAL_TIM_Base_Start_IT(&htim2);

 while (measureInProgress)
 {
 if (measure_pending_count > 0)
 {
 adc_read();
 __disable_irq(); // Prevent race condition
 measure_pending_count--;
 __enable_irq();
 }
 }
 measure_pending_count = 0;

 HAL_ADC_Stop(&hadc1);
 float measure = adc_compute_value(channel); // convert the value toward needed unit (mA or V)
 snprintf((char *)result, RESULT_PRECISION, "%f", measure);
}

 Here is the fault report, register, and dissasembly code of when the crash happen 

tfde_0-1753860634683.png

tfde_1-1753860667236.png

tfde_2-1753860721121.png

I also attach the entire "adc_driver.c/.h" file where the bug seem to take place. 

Also i feel its important to precise that this function if call, is nested in multiple function call (5).

My english isn't perfect because its not my mother tongue and i'm very new to embedded system. So i'm maybe missing a key component.  

 

Andrew Neil
Super User
July 30, 2025

STM32CubeIDE gives you a call tree showing where the fault occurred - can Keil do that?

If it turns out that the location is consistent, then set a breakpoint just before that point to see what's happening...

 

PS:

Yes, it seems that it can:

AndrewNeil_0-1753864561654.png

https://www.keil.com/appnotes/files/apnt209.pdf#page=17

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.
tfdeAuthor
Associate
July 30, 2025

Thank for the tips. 

It if i use this technique here is what i get : 

tfde_0-1753864977703.png

It seems like the program go out of memory bound, i dont get how commenting a file change the issue of that. 

Lead II
July 30, 2025

adc_reset_value() is only called once. So measureCount, used as your array index, is not set to zero so it keeps increasing beyond the length of the buffer. This is a buffer overflow!

Edit: I see you are calling adc_init() every time you do a measurement instead of once. This is not the way you should use the ADC. You need to initialize your peripheral only once. Also avoid using global variables if possible. But at least this clears measureCount. The problem is elsewhere.

"Kudo posts if you have the same problem and kudo replies if the solution works.Click ""Accept as Solution"" if a reply solved your problem. If no solution was posted please answer with your own."
tfdeAuthor
Associate
July 30, 2025

Hi! Maybe im overlooking something but, its call everytime i use adc_measure () so the value are reset everytime they need to be ? 

Tesla DeLorean
Guru
July 30, 2025

Random failing, I'd double check the PLL settings, and FLASH WAIT STATES, and electrically the voltage observed on VCAP pins, and the amount of capacitance actually placed, ie 2u2 per pin or 4u7 in total

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..