2018-01-05 01:59 AM
Hi and happy new year
I need help,to avoid an hard fault after un unpredictable time(2 ...120 sec) when i use the USART1 Tx
MCU is STM32F410RBT,mounted on a custom board
Configuration done with CubeMx,IDE is STM32 WorkbenchI have to acquire 12 analog channels at 1KHz,then i have to send the data to a PC using USART1 at 460800 bpsI trigger the ADC with TIM1,then the ADC transfers in DMA the 12 x 12 bit samples to a 16 bit buffer
unsigned short ADC1ConvertedValues[ADC_BUFFER_SIZE];I associated some interrupt to the timer event ,to the end of 12 channels conversions and to the end of ADC DMA transfer,
in these interrupt routines i move somo pin so that i can't verify on the scope the activities.
Channel1-yellow and channel 2-blue goes high when the TIM event happensChannel 1 goes low ath the end of ADC conversions,Channel 2 goes low at the end of ADC DMA transferA 3rd scope -green channel is connected to the UART Tx pinFirst thing i notice is that the ADC DMA transfer pulse is prior than the ADC EoC,maybe because of the highest priority of the DMA transfer interrupt?
Anyway everything looks okay until here.
In the DMA interrupt routine i call HAL_UART_Transmit_DMA(&huart1, (uint8_t *)buff_char_prova, 20);
or i simply turn on a flag that calls the same function in the main loop.
After some seconds i have hard fault ,the same happens if i call HAL_UART_Transmit_IT(&huart1, (uint8_t *)buff_char_prova, 20);or the blocking function
HAL_UART_Transmit(&huart1, (uint8_t *)buff_char_prova, 20);//(in main loop)
Saving the content of registers and program counter PC during hard fault shows every time a different PC value.May i have some help,please ?Attached is the whole project,including CubeMx file.Many thanks for your time.Diego,Milan ,Italy2018-01-05 02:46 AM
I use the KEIL IDE and during the debugging and hard fault I can see what kind of hard fault occured (hard fault type):
http://www.keil.com/appnotes/files/apnt209.pdf
Since you get different PC value each time it means that the code that crashed is NOT deterministic (not the same code) because the data from the ADC is random and influence the code (location for example), or more likely the stack (changing the return addresses of called functions).
Check the stack size defined, especially if the buffer for adc data is allocated inside a function (main() is also a function) because the array is allocated on the stack.
Instead you can simply allocate the array as global variable (outside main() or any other function) to see if it helps.
It's a guess only.
2018-01-05 03:53 AM
Moving the array outside any function cause array to be allocated outside the stack and heap (assumed that the array size is known to the compiler, not dynamic array)
2018-01-05 04:29 AM
Thanks for help Bogdan,
about the buffer size ,it is a fixed size array of 48 unsigned short ,that should be used not more than a quarter,
it is declared as global.I already tried doubling the stack size,just to check if,at least,the hard fault happens after longer time,but i have noticed no difference
2018-01-05 04:43 AM
DMA buffer?
2018-01-05 04:45 AM
Is the pointer initialized?
2018-01-05 06:22 AM
To expand on Bogdan's post, specifically check for IMPRECISE FAULT. AN209 is an excellent reference. Even though
https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
is related to FreeRTOS, it provides concise information on HARD/IMPRECISE FAULT.2018-01-05 06:29 AM
Yes,it is,
even after hard fault i can verify it in DMA registers that both memory and peripheral address registers are right set at their addresses.I 'm beginning to think that it is an electrical problem .This because if i speed up the clocks from 48 to 96 MHz the problem is even worse.I want to check grounds and capacitor,justo to exclude it.Consider that i did the board by myself in a fast proptotype way
2018-01-05 09:31 AM
Double check FLASH Wait States, classic cause of random Hard Faults.
Check voltage on VCAP pins.
2018-01-06 08:21 AM
Thanks Bogdan , Doug and Clive
SOLVED.It depended by hardware:
As you can see it is not exactly professional:anyway
1)I put some capacitor closer to VDD pins
2)I added 3 'wired vias' across the 2 ground planes
3)last but probably more important,i have soldered better the 0402 sized VCAP pin capacitor, it was probably disconnected
In over 20 hours i never had hard fault,despite i doubled the core speed at 96MHz.
The misleading things were:
1)Previous lucky experiences with similar mounting and only few caps2)The fact that the hard fault never happened with this code,unless activating USART1Thanks again for help