2018-07-10 03:28 PM
I have been struggling for several days now to track down a hard fault I am getting in one of my programs. It seems to be related to printf (and similar) functions.
After running for a while I will get a hardfault from __vprintf_float_long_long(). Unfortunately that is where the stack trace stops. The fault type varies, sometimes it doesn't even fault, it just gets stuck in __vprintf_float_long_long never to return.
Sometimes I get BFARVALID=1, and PRECISERR=1, and BFAR=0xFFFFFFFF. Sometimes I get INVSTATE=1.
Presently, I have a fault on these lines:
F7FCF8B9 bl 0x08035B24 <__RAL_pre_padding>
9704 str r7, [sp, #16] 463A mov r2, r7 4641 mov r1, r8 2030 movs r0, #0x30 F7FCF8A5 bl 0x08035B08 <__RAL_print_padding> 1E63 subs r3, r4, #1 9305 str r3, [sp, #20] D40D bmi 0x080399E0 AF0D add r7, sp, #0x34 443C add r4, r7 F8DD8010 ldr.w r8, [sp, #16] F8141D01 ldrb r1, [r4, #-1]! <--Faulted from here 4640 mov r0, r8 F7FCF87F bl 0x08035AD4 <__putc>I have r1=0x20001780 and r4=0
I am using rowley crossworks V4.0 with their tasking library. My processor is an STM32F446. I have hardfloat enabled.
I have check my stacks and confirmed there is no overflow. I have tried mutexing access to printf, replacing printf with vsnprintf, and many other things. Is there something I can do to get more meaningful debug data? Are there any know problems with gcc libraries that might explain what is going wrong? Please help!
2018-07-13 06:12 PM
Well it looks pretty clear that R4 is pointing to an invalid address and faulting because of that. The code in vfprintf may well be valid, and you're just feeding in crap.
R4-1 == 0xFFFFFFFF == BFAR
http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/Cihfaaha.html
DMA1_Stream7 EXTI15_10 ??
2018-07-15 09:33 PM
The documentation is unclear whether it is DMA1_Stream7 or EXTI15_10, but I don't have either of those enabled. Here is a dump of my ISER registers at the time of the fault:
NVIC_ISER0 0xa4000000
WWDG 0 TAMP_STAMP 0 RTC_WKUP 0 FLASH 0 RCC 0 EXTI0 0 EXTI1 0 EXTI2 0 EXTI3 0 EXTI4 0 DMA1_Stream0 0 DMA1_Stream1 0 DMA1_Stream2 0 DMA1_Stream3 0 DMA1_Stream4 0 DMA1_Stream5 0 DMA1_Stream6 0 ADC 0 CAN1_TX 0 CAN1_RX0 0 CAN1_RX1 0 CAN1_SCE 0 EXTI9_5 0 TIM1_BRK_TIM9 0 TIM1_UP_TIM10 0 TIM1_TRG_COM_TIM11 1 TIM1_CC 0 TIM2 0 TIM3 1 TIM4 0 I2C1_EV 1 NVIC_ISER1 0x013000e1 I2C1_ER 1 I2C2_EV 0 I2C2_ER 0 SPI1 0 SPI2 0 USART1 1 USART2 1 USART3 1 EXTI15_10 0 RTC_Alarm 0 OTG_FS_WKUP 0 TIM8_BRK_TIM12 0 TIM8_UP_TIM13 0 TIM8_TRG_COM_TIM14 0 TIM8_CC 0 DMA1_Stream7 0 FMC 0 TIM5 0 SPI3 0 UART4 1 UART5 1 TIM6_DAC 0 TIM7 0 DMA2_Stream0 1 DMA2_Stream1 0 DMA2_Stream2 0 DMA2_Stream3 0 DMA2_Stream4 0 ETH 0 ETH_WKUP 0 CAN2_TX 0 NVIC_ISER2 0x00000080 CAN2_RX0 0 CAN2_RX1 0 CAN2_SCE 0 OTG_FS 0 DMA2_Stream5 0 DMA2_Stream6 0 DMA2_Stream7 0 USART6 1 I2C3_EV 0 I2C3_ER 0 DCMI 0 FPU 0 UART7 0 UART8 0 SPI4 0 LCD_TFT 0 LCD_TFT_1 0The NVIC_ISPR registers also confirm that EXTI15_10 or DMA2_Stream7 is pending. Though they do show 3 other (probably legitimate) pending interrupts.
So the question is how can I get VECTPENDING==0x2F?