stm32f072 hardfault [SOLVED] - Page 1
Forum section: electronics / general

author: Ribster
author_rank: Frequent Contributor
timestamp: April 17, 2016, 07:37:22 pm
content: I get a hardfault on my F0 deviceIn my hardfault handler, i added a piece of code that copies the PC to R1.If i go look at the address of that instruction, i get 0x8000297.On that address, it calls a simple memory operation to copy the address SP+4 -> MSP to R3.That is, if i correctly interpreted the instructions.However, i don't see any problem doing this.The microcontroller is jamming away with reading ADC, UART, SPI and doing some GPIO toggling.After 30 seconds or so, the hardfault appears..Any ideas?

author: Ribster
author_rank: Frequent Contributor
timestamp: April 17, 2016, 08:01:06 pm
content: Update: i added a new hardfault handler for saving the registers.I'm followinghttps://mcuoneclipse.com/2012/11/24/debugging-hard-faults-on-arm-cortex-m/.The stacked_lr points me to the pop of a write pin routine. As you can see below. toggling a pin cannot cause this, am i right?I am suspecting the stacked_pc to be the culprit. Since this address is pure rubbish, and i cannot find it in my dissasembly.

author: AndyC_772
author_rank: Super Contributor
timestamp: April 17, 2016, 08:06:35 pm
content: Are you enabling the watchdog on the CPU, and forgetting to kick it from time to time?The only other time I've had unexpected hard faults, is when the code running on the CPU isn't actually the code which the IDE thinks is running, ie. part of the flash hasn't been programmed for some reason.

author: Ribster
author_rank: Frequent Contributor
timestamp: April 17, 2016, 08:19:23 pm
content: Quote from: AndyC_772 on April 17, 2016, 08:06:35 pmHey AndyC,I'm not enabling the watchdog. This is also the first time that i'm experiencing this behavior.I get consistently a hardfault after 1 minute cpu time.It's a new custom PCB, so maybe it's hardware related. But since the hardfault is consistent in time, i really doubt it.

author: stmdude
author_rank: Frequent Contributor
timestamp: April 17, 2016, 08:25:17 pm
content: Quote from: Ribster on April 17, 2016, 08:01:06 pmOn the STM32s, it can, if you're trying to modify a pin on a GPIO block that isn't clocked.

author: Ribster
author_rank: Frequent Contributor
timestamp: April 17, 2016, 08:33:42 pm
content: Update: Changing my clock from HSI to HSE with PLL solved the problem.I changed everything to a simple blinking led on a HC595 shift register.The led was blinking steadily, and after a minute it started to blink inconsistently with hardfault as result.Maybe an issue with the HSI, which would be weird.Thanks for the advice and support!

author: AndyC_772
author_rank: Super Contributor
timestamp: April 18, 2016, 06:18:26 am
content: That's very odd, I'd be amazed if the HSI clock itself were actually faulty. Maybe the RCC isn't set up correctly, and there's a clock that's running at a speed that's outside its range?How is your clock configuration done? Did you use STM32 Cube?I see references to ST's HAL in your code. Maybe there's a bug in that, which applies in your particular clock configuration? It's one reason why I gave up using it very early on, and now always just poke registers directly myself.One minute is a very long time for something to "work" despite an error, though. Do you have a SysTick handler? How often is it called, and what does it do? Are there any other timer interrupts going off?

author: Ribster
author_rank: Frequent Contributor
timestamp: April 18, 2016, 09:43:46 am
content: I guess it has to do with the RCC. Which i find very odd. The first time i'm encountering this.Faulty code:Code:RCC_ClkInitTypeDef RCC_ClkInitStruct;RCC_OscInitTypeDef RCC_OscInitStruct;/* No HSE Oscillator on Nucleo, Activate PLL with HSI/2 as source */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_NONE;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK){Error_Handler();}/* Select PLL as system clock source and configure the HCLK, PCLK1 clocks dividers */RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1);RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1)!= HAL_OK){Error_Handler();}Good code:Code:RCC_ClkInitTypeDef RCC_ClkInitStruct;RCC_OscInitTypeDef RCC_OscInitStruct;RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;/* Enable HSE Oscillator and activate PLL with HSE as sourcePLLCLK = (8 * 6) / 1) = 48 MHz */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;HAL_RCC_OscConfig(&RCC_OscInitStruct);/*Select PLL 48 MHz output as USB clock source */PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLCLK;HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);/* Select PLL as system clock source and configure the HCLK and PCLK1clock dividers */RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1);RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);I am running on the HSE with PLL, and had 0 issues so far..And i hear your pain and share it. I use cubeMX to plan my gpio / pheriperals and dma's.After that i use the cube package and manually port the examples of the peripherals over.This is a fast way to getting things up and running.If i decide to use this project for serious stuff, i take the time for bare metal register programming.But, time is money and a day has only so few

author: Brutte
author_rank: Frequent Contributor
timestamp: April 18, 2016, 10:05:19 am
content: QuoteIt is pointless to enter hard fault handler, do some asm woodoo and then hit a breakpoint waiting for a debugger. Why cannot you just start from a breakpoint when you already have a debugger connected? The debugger has no problems with reading registers, as can be seen on the screenshot you provided.There is also a "vector catch" option that does this trick even better, no need for an explicit breakpoint then.QuoteI cannot imagine how a mis-configured clock can cause a hard fault. Well, you could theoretically PLL overclock a device and load an erroneous op-code from flash but that seems like a kindergarten error. I suggest you should configure MCO (PA8) for HCLK and make sure you are/were not running at 320MHz, instead of 32MHz.

author: Psi
author_rank: Super Contributor
timestamp: April 18, 2016, 12:41:56 pm
content: ive had a stm32L100 pseudo-randomly change between 16 mhz and 32mhz sysclk based on external factors like touching the pcb or probing thingsI suspect there are some incorrect RCC clock setting combinations which can cause odd behavior like this sort of thing

author: Brutte
author_rank: Frequent Contributor
timestamp: April 18, 2016, 12:53:23 pm
content: Quote from: Psi on April 18, 2016, 12:41:56 pmYou mean settings that are referenced in the datasheets as "unpredictable" or "reserved"?If it says "Thou shalt not" then just don't.

author: dgtl
author_rank: Regular Contributor
timestamp: April 18, 2016, 05:30:11 pm
content: Some typical random hardfault causes Ive had:* Wrong flash latency (FLASH_ACR). One less than needed kind-of-works, causing random crashes.* Board decoupling issues (missing capacitors on the VCAP pins or power rails).

author: newbrain
author_rank: Super Contributor
timestamp: April 18, 2016, 06:47:01 pm
content: Quote from: Ribster on April 18, 2016, 09:43:46 amTo be honest, I would say both code snippets are not completely correct.Starting from the end: as you correctly say, the Nucleos do not have an HSE (on Nucleo 64 you can solder a quartz and two caps, if you want to snap off the ST-Link), so the HSE setting should not be RCC_HSE_ON, but RCC_HSE_BYPASS in order for the pin to simply act as an input for the clock coming from the ST-Link. It will work, as you have experienced, but it will needlessly drive the internal oscillator output pin.In the fist one, the prescaler is setRCC_PREDIV_DIV1, meanaing that the input clock isnot divided(~=8MHz HSI) or divided by two, according to the PLL source selecttion value.PLL source is set toRCC_PLLSOURCE_HSIwhich for very few F0s is defined to mean HSI/2: you can check if that's your case by looking at stm32f0xx_hal_rcc_ex.h (you did not specify the F0 you are using).If not, you are trying to run the MCU at 96MHz, good luck with that!If, instead, the define ends up == 0 (that is, RCC_CFGR_PLLSRC_HSI_DIV2 from the relevant stm32f0nnxx.h) something else is going on...

author: Brutte
author_rank: Frequent Contributor
timestamp: April 18, 2016, 07:37:49 pm
content: Quote from: newbrain on April 18, 2016, 06:47:01 pmThis is F072, as in the title. It does not have a HSI divided by two.So with first code SYSCLK run at 96MHz.QuoteHow come the uC was able to withstand that mad run and execute code "correctly" being overclocked twice??Do we have a world record?

author: Ribster
author_rank: Frequent Contributor
timestamp: April 18, 2016, 07:44:00 pm
content: I have the current setup running with the HSE at 8MHz, multiplying to 48MHz.I can confirm that this setup works, i have a WS2812B led running with correct timing.If i have a look at that code again, i multiply my HSI from 8MHz by factor 12 instead of 6.So this is the error..Running the CPU at 96MHz works for a little bit, then it goes into hardfault.When i change the PLL factor to 6, it runs reliably..So, i guess i'm losing my mind. Idiot that i amUpdate: The time before hardfault is shorter now. Since i have 3 leds sinking some current, i think it's due to thermal properties. So it seems that overclocking the cpu is okay, as long as you can keep it cool...

author: newbrain
author_rank: Super Contributor
timestamp: April 18, 2016, 07:59:11 pm
content: Quote from: Brutte on April 18, 2016, 07:37:49 pmWhoops!I even have the same board (but I soldered a quartz on it, used as CEC to USB HID adapter for Kodi).At least I got the bug right.Overclocking this chips is not unheard of... but 2x is quite good!To the OP: Try a little heatsink, if you are brave enough!

author: Ribster
author_rank: Frequent Contributor
timestamp: April 18, 2016, 08:07:47 pm
content: Why stop at x2 ?

author: Ribster
author_rank: Frequent Contributor
timestamp: April 19, 2016, 09:05:55 am
content: Quote from: newbrain on April 18, 2016, 07:59:11 pmI'm not using a discovery board.I'm using my self made board, just to be clear

author: newbrain
author_rank: Super Contributor
timestamp: April 19, 2016, 11:04:13 am
content: Quote from: Ribster on April 19, 2016, 09:05:55 amI see, the code referred to Nucleo so I thought you were using one, I think I skipped right to that post, seeing that it contained something I could check...Quote from: Brutte on April 18, 2016, 07:37:49 pmIt's just not defined in the HAL, but it's there:Quoteand, in CMSIS device include stm32f072xb.h:Code:#define RCC_CFGR_PLLSRC_HSI_DIV2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */

author: dannyf
author_rank: Super Contributor
timestamp: April 19, 2016, 12:51:52 pm
content: The whole 0x2 family is interesting for its hardware uart, and crystal-less USB. Some possibilities:1) a jlink with only the 0x2 - the official version runs on 072 but a tssop20-pin 042 would be much nicer. It supports swd+swo on CMx parts, and fits on your thumb.2) with the right software, you have a $3 scope out of a few parts.

author: Brutte
author_rank: Frequent Contributor
timestamp: April 20, 2016, 06:45:20 am
content: Quote from: newbrain on April 19, 2016, 11:04:13 amCode:#define RCC_CFGR_PLLSRC_HSI_DIV2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */#define RCC_CFGR_PLLSRC_HSI_PREDIV ((uint32_t)0x00008000) /*!< HSI/PREDIV clock selected as PLL entry clock source */So the question is: which PLL source was chosen. If the second option with PREDIV ==1 then we have 96MHz.Anyway, I think now OP is able to find that out by oneself by analyzing a clock tree (or simply using a startup code provided by ST examples).