2012-04-12 08:18 AM
Hi,
I have written a Bootloader that looks at the micro sd card and loads firmware.bin file into address 0x00800C000 and jumps program execution to 0x00800C004. I have changed the Flash address in the code that is loaded to 0x0080C000 and i have also used NVIC_SetVectorTable to change the vector table address.The funny thing is it works if i flash in a debug version of the bin file, if i try to flash in a Release version of the code it throws a hard fault exception???The code also works fine if i load in a basic bin file with no interrupts but as soon as i set up the interrupt for Timer 3 a hard fault exception is thrown.I am using Timer 3 for file system timing in bootloader code but i disable it before jumping to the new code location at 0x0080C004I have attached the code for both the bootloader and the code for the LEDFlash application that i am having trouble running when loaded in release version.Could someone give me some pointers on what I am doing wrong and why the debug bin works but not the Release?Cheers2012-04-12 09:15 AM
Hi,
In system_stm32f10x.c file (LEDFlash application), try to update the define VECT_TAB_OFFSET to 0xC0002012-04-12 09:54 AM
Running SystemInit() a second time around is not advisable, it doesn't seem to pay any attention the the current state of the system and bangs the HSE and PLL assuming a cold start running from HSI, rather than one already running from the PLL. Much grinding of gears and consternation will occur...
Remove the call to SystemInit in startup_stm32f10x_md.s in the application project.2012-04-12 03:34 PM
Thanks for the advice, I will try these things out tonight and report back.
2012-04-13 05:23 AM
I have tried both of these ideas, both by themself and together at the same time to no avail.
I found some more ''interesting'' behaviour, if i remove a loop which waits for the Led1FlashCount to get to 0 the hard fault handler is not triggered. The Led1FlashCount is decremented in the Timer 3 Interrupt. This line is commented in the code below.int main(void){ RCC_Configuration(); NVIC_Configuration(); Timer3_Init(); Led1_Init(); USBMassStorage_Init(); uint8_t status = 0; while (1) { if(status == 0) { status = 1; Led1Flash(20, 200); } else if(status == 1) { status = 2; Led1Flash(5, 600); } else { status = 0; Led1Flash(2, 1800); } //This code causes the application to crash??? while(Led1FlashCount > 0) { } }}this is the Timer 3 interrupt codevoid TIM3_IRQHandler(void){ if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); if(WaitCounter > 0) { WaitCounter--; } if(Led1FlashCount > 0) { if(Led1DurationCount > 0) { Led1DurationCount--; } if(Led1State == 1 && Led1DurationCount < Led1Duraion / 2) { Led1Off(); } if(Led1DurationCount == 0) { Led1FlashCount--; if(Led1FlashCount > 0) { Led1DurationCount = Led1Duraion; Led1On(); } else { Led1Off(); } } } disk_timerproc(); }}2012-04-13 05:24 AM
Another funny thing i noticed is even though the main code has gone to HardFault_Handler the USB Mass Storage still works?!?!
2012-04-13 05:24 AM
Just as a sanity check, i set the LedFlash test app back to base address 0x0800000 and flashed it into the mcu and it works perfectly...
2012-04-13 07:04 AM
Perhaps then you need to install a Hard Fault handler that actually decodes the fault state instead of spinning in a while(1); loop.
The examples by Joseph Yiu, and his book, are recommended. Hard faults typically occur because you read or write memory which is outside the FLASH, ROM or peripheral addresses. Look at the instructions around the faulting PC, writes are buffered so it might be a prior instruction. Also use a debugger. Step into the code observing when/where it faults.2012-04-14 10:00 PM
Thanks for the good advice after quite a few late nights, i found that the problem to be one of the variables being optimised away by the compiler, i made the variable volatile and everything works perfectly now, thanks heaps :)