cancel
Showing results for 
Search instead for 
Did you mean: 

How to solve strange hard fault issue

MClar.3
Associate II

Building a custom board, which can accept either an STM32F205 or an STM32F405. Have boards with both MCU built. System running FreeRTOS 10, with three tasks total.

Embedded software has shared application code between the two builds, only the stuff generated by CubeMX is different. I'm using the USB_OTG_FS and CAN1 peripherals, TIM1 as the system timebase, TIM2 as a timestamp for CAN messages, and the CRC unit. Nothing fancy.

It seems that when I try and write my config file to flash (it's in a sector by itself) I get an oddball IRQ from the Timer Tick, and then a hard fault.

The kicker, which is really confusing me, is if I load the code compiled for the STM32F205 onto the STM32F405, everything works as expected. No crashes, config saved and CRCd correctly.

I've got limited experience with debugging hard faults, but looking at the registers in CubeIDE, it seems it's a forced hard fault (HFSR bit 30 is set). CFSR bit 16 is set (UNDEFINSTR) but not sure whether that's relevant or not.

I've tried using the FreeRTOS taskDISABLE_INTERRUPTS() function, the __enable_irq function, suspending the other two tasks on the system, but I can't see what's going wrong. Tried the hard fault code on the FreeRTOS Site (not allowed to post links...) but it never seems to actually run it - It just gets stuck on the hard fault entry. Looking back up the stack, the only hint of code addresses are the Timer 1 IRQ Handler, xPortStartScheduler, prvPortStartFirstTask.

I guess I'm asking is there something inherently wrong with the way this version of CubeMX / FreeRTOS work on an M4, or is it fixable, or should I just resign to using the M3 code compiled for the '205?

Any assistance gratefully received,

Matt.

7 REPLIES 7

Would be super-helpful to show the actual instruction/registers it's faulting on.

For an M4F build, I might guess some floating point instructions, or stack/context push, whilst the FPU isn't enabled.

Have the Hard Fault Handler output actionable data.

Other thing perhaps look at MCU speed, flash wait states, prefetch. Although the F2 had the more evident critical path issues there.

On HW side check VCAP voltages and capacitors.

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

Hi Tesla,

Thanks for replying 🙂

Indeed - I didn't want to overload with information in the first post.

Screenshot of registers attached. Also have the map file if needed.

MClar.3
Associate II

VCAP pins are at 1.25V or so at 2.2µF. The voltage on the '205 board is a bit lower at 1.18V, still with 2.2µF caps. They're X7R 1206 size. I've got some 1µF, 4.7µF and 10µF I could just about fit on the pads. The system as a whole is powered from USB. There's a filter, and a linear 3.3V LDO providing VDD.

Power Regulator Voltage is set at "Power Regulator Scale 1", which is the only option.

I've tried slowing the '405 down to 120MHz (same as the '205) and it's still the same.

CubeIDE MX is reporting the Instruction Cache, Prefetch Cache, and Data Cache are all enabled, with the flash latency at 5 WS.

Indeed the M3 vs M4 difference and an interrupt as a trigger points to a stack memory issues!

S.Ma
Principal

Are you able to breakpoint in hardfault and look at the call stack and core dbg cycle counter? What happen if you change the stack size? If using an rtos are you using a single global task for interrupts? If you can find a way to increase the hardfault occurence (half speed core, optimisation level change), it might help find the root cause.

> single global task for interrupts

What is that?

I totally agree. I did some more reasearch last night, and found that the M4 can dump out a much larger frame to the stack on a context switch. Makes sense now!

Sooo...

This morning I've increased the size of the stacks. Task Stacks in FreeRTOS (including the timer task) have been increased from 128 / 512 words(the values on the M3 code) to 512 / 1024 words, the timer task has been increased to 512 words, and the linker stack has gone from 2K up to 8K.

Working like a charm now!

Thanks all for the hints on stack sizes - If I'd known the M4 dumped a much larger stack frame 24 hours ago. Hindsight is a wonderful thing!