cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault_Handler

asaccomandi
Associate II

Hello,
until recently, I used the STM32F411CEU6 microcontroller; lately, I switched to the STM32G0B1.
I've ported the old C++ code from the STM32F411CEU6 to the STM32G0B1.
Everything works correctly; the only issue is that now, 'HardFault_Handler()' occurrences happen randomly.
When I manage to identify them through the debugger, I see that they occur in various places
(there's always corrupted memory). For months, I've checked all possible allocations and addressing,
but the code seems correct to me. The only thing that has significantly reduced the HardFault_Handler
occurrences is the elimination of all 'volatile' directives.
Does anyone have any idea why this might be happening?

Thank you

8 REPLIES 8
TDK
Guru

> there's always corrupted memory

Check your clock settings and in particular flash wait states. Verify power is good and appropriate bulk/decoupling caps are present.

Is there a pattern to where the corrupted memory is? Is it on the stack or heap or statically allocated? Could be a read/write past the bounds of the buffer.

If you feel a post has answered your question, please click "Accept as Solution".

Show some particular illustrations of the failure.

The Cortex-M0(+) parts are sensitive to alignment issues. Watch for structure packing and pointer alignment.

Volatile variables should not be an issue.

What clocking, PLL settings, and FLASH wait states. Check HSE_VALUE.

Supplies, VCAP capacitors.

Check variables involved, and paths to failure. Instrument, and narrow search by sanity checking pointer, structures and stack.

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

Thank you for the response.

The damaged memory is found both in the heap (often on string objects) and in static allocation (typically in the UART handle); I have never seen issues on the stack.
I must have checked buffer limits a thousand times! I've verified the power supply, and it's stable at 3.3 volts.
If it were an alignment problem, I believe the error would manifest more systemically.
I configured the clock settings through STM32CubeIDE.

However, through STM32CubeIDE, I don't see how to set the alignment. Can you tell me how to do it?

Sorry, how can I adjust the FLASH wait states?

Andrea

using cube, it should set flash wait correct, see ->

AScha3_0-1701760248330.png

and about alignment : you have to set it...if needed

try first other optimizer settings; what you use now ?

here example : byte array aligned to 32 byte border for dma and cache access (on H7 cpu with cache)

 

 

uint8_t inbuf[4096*8] __attribute__ ((aligned (32)));

 

see:

https://community.arm.com/support-forums/f/armds-forum/1080/alignment-of-variables-for-cortex-m0

https://stackoverflow.com/questions/16020784/variable-alignement-with-cortex-m0-under-gcc

 

++ in ide: on debug (menu: window-> show view -> fault analyzer )  might help, after a hard fault, to see..

AScha3_1-1701761368475.png

 

If you feel a post has answered your question, please click "Accept as Solution".

I don't have active optimization options, and in any case, I've tried them all, but the result was the same.

I will try to work on the alignment and will let you know;

for now, thanks

andrea

TDK
Guru

What are your clock settings? Flash wait states is typically configured in SystemClock_Config. If you have insufficient wait states, you can get memory errors everywhere like this. Since it's both in the stack and heap, could be what you have going on here. Unlikely to be a buffer overflow on the stack, as that wouldn't go into the heap.

If you feel a post has answered your question, please click "Accept as Solution".

Get a serial port working with STDIO so you can get actionable data, and provide data to diagnose remotely.

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

Show SystemClock_Config() code, make sure local/auto structures are properly cleared.

Watch local/auto usage throughout application. If not explicitly set or cleared these variables will contain random stack junk 

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

Hi,

 

I configured the 'Flash wait states', with the call:
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

and it's "Two wait states"... and it's already the highest value. 

Anyway, I'll give you the rest of the clock initialization.

if you have any ideas...

Thanks

andrea

 

static void SystemClock_Config(void) {

 

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 

// configure the main internal regulator output voltage

HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

 

// Configure LSE Drive Capability

HAL_PWR_EnableBkUpAccess();

__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);

 

// Initializes the RCC Oscillators according to the specified parameters in the RCC_OscInitTypeDef structure.

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.LSEState = RCC_LSE_ON;

RCC_OscInitStruct.LSIState = RCC_LSI_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;

RCC_OscInitStruct.PLL.PLLN = PLLN_PRESCALER_CLOCK; // defined in main.h

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;

RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

 

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {

errorHandler("Main - Error osc init.");

}

 

// Initializes the CPU, AHB and APB buses clocks

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;

 

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {

errorHandler("Main - Error clock init.");

}

}