cancel
Showing results for 
Search instead for 
Did you mean: 

[Need Help] Hard Fault Analysis On LR after ADC check HAL_OK

dios_kuri
Associate III
Hi i am a student, building a program using STM32F4 Discoery board for my research's hardware. So my program which i write for STM32F4 Discovery board has been stuck in Hard Fault after certain ADC Poll code. An overview of my code is :
  • Use different ADC Channels from ADC1 only (just 1 ADC, multi channel) to read 3 sensors.
  • Each time i about to read any ADC channel i configure the channels (e.g 2 or 5) >> start hadc1 >> poll conversion >> get the value >> stop hadc1 and i repeat that for other channels.
  • After some calculation programs i fetch it to USART
 
After reading a blog about HardFault analyzer, i managed to tweak my code and get the info about on which line i got stuck, including the LR and PC (showed by number 1 in the pic, top left). Turns out it is faulting when it is checking whether HAL_OK is TRUE in the main.c (number 3 in the pic, bottom).
The LR (call return address) has the adress 0x08000955 whis is not listed in the dissasembly (number 2 in the pic, top right)
HARDFAULT KONTOL.JPG

 

I think the bad LR address might be the problem, i.e. reffering to the non-exist address in disassembly, note that in disassembly window (number 2) there is no address 0x8000955 after 0x08000954, but it goes straight to 0x8000956 instead.
But i am not really sure about it. Also, if thats the case then i would need group member's suggestion on how to deal with the fault. So i dont really know how what to do in this situation. Could anyone please help me?
 
 
some notes:
The USART works fine, i did try the code by commenting out the ADC related code (using //) and using incremental values as dummy data.
 
 
I had some trouble with HAL getting locked which send me to the Hal_Locked instance
But, I changed the Hal_Locked function so it can unlock itself in stm32f4xx_hal_def.h.
heres the Hal_locked function 
HARDFAULT KONTOL1.JPGThanks in advance!
_____________________________________________________________
 
 
14 REPLIES 14

I don't see the ADC peripheral address anywhere in the list.

Perhaps compile with USE_FULL_ASSERT defined so the library code can sanity check some of the parameters and fields for you.

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

>Suggest if you have printf() working, that a) you print out the pointer "%p", b) dump out the structure, and c) the pointer for hadc->Instance

 

What i understood

a) i need to add printf("%p") in the end of the while(1) (please correct my printf code)

b) i dont know to do this and what structure mean... please bear with me

c) im not sure how to print out the hadc->Instance pointer


I hope you would help me what to do.. i didnt really find anything in google..

Perhaps compile with USE_FULL_ASSERT defined so the library code can sanity check some of the parameters and fields for you.

 

to do that do i just add the "#define USE_FULL_ASSERT" in the main code?

Do immediately prior to you calling HAL_ADC_ConfigChannel() 

printf("%p\n", &hadc);

printf("%p\n", hadc->Instance);

also dump(sizeof(hadc), (uint8_t*)&hadc);

write a dump(size_t size, uint8_t *buffer) function that prints out the bytes in memory

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

Hi, @Tesla DeLorean 

Thank you for your advices i just got the time to do it today. So i have changed the ADC from STM32CUBEMX all over again following my old reference, and i changed the HardFault handler to the one which is more dense. I retrace the Hard Fault and find that the code faults exactly at this code here which i supposed is for changing the sampling time(?)

hardfault clear old sample time.JPG

 

 

 

 

 

 

 

 

 

 

 

Heres the clearer code (its on the clear old sample time)

 if (sConfig->Channel > ADC_CHANNEL_9)
  {
    /* Clear the old sample time */
    hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel);
    
    /* Set the new sample time */
    hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel);
  }
  else /* ADC_Channel include in ADC_Channel_[0..9] */
  {
    /* Clear the old sample time */
    hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel);
    
    /* Set the new sample time */
    hadc->Instance->SMPR2 |= ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel);
  }

 

and here is the Hardfault printf output

[Hard Fault]
r0 = 200000D8, r1 = 20000FA8, r2 = 00000001, r3 = 00000007
r4 = 00000000, r5 = 4D575020, r6 = 40021000, sp = 20000F48
r12= 00000000, lr = 080038B3, pc = 08000AD6, psr= 81000200
bfar=4D575030, cfsr=00008200, hfsr=40000000, dfsr=00000003, afsr=00000000

00000309 080065E8 20000F90 20000F88 08005C7B 20000000 200002EC 00000000
200000DE 00000014 00000000 08002BD5 00000014 20000000 000003E8 40021000
000003E8 00000200 40000438 00000000 20000000 000003E8 40021000 080038B3
00000001 00000001 00000000 00000000 20000000 08006215 00000003 00000010

409A 6803 68DD 432A 60DA E010 2002 BD78(692E)EB02 0242 4093 439E 612E

===================================================================================

So now do i put the print %p and dump before that code line? 

Thank you again.