2016-10-27 12:45 AM
Hi,
I've read a ton of forum posts here regarding hard fault error encountered when jumping from custom BL to App. But, in my case, it's working fine the first time I did the jump to App. But, when I jump back to BL and then jump back to App, the code will encounter a hard fault error in the Appcode before it enters main() function.The sequence is like this: Reset - Bootloader - Jump to App - Jump to Bootloader - Jump to App (but the app main() never execute this time due to hard fault error).I tried removing the freertos in the appcode and the above sequence worked fine. But I need to make it work with freertos.Any idea what could be the problem here? I suppose the vector table, jump addresses are correct since they worked fine the first time. I'm also disabling the interrupt, setting the stack pointer, before I do the jump.Here's the code snippet:void jumpToUserCode(void){ /* Create pointer to usrmain address*/ typedef void (*funcEntryPtr)(void); uint32_t jumpAddr = *(volatile uint32_t*)(APP_ADDRESS + 0x04); /*First word is the SP value, next word is the reset vectore*/ funcEntryPtr usrMain = (funcEntryPtr) jumpAddr; /*jumpAddr typecasted*/ /*Shut down any tasks running*/ //HAL_RCC_DeInit(); //HAL_SPI_DeInit(&hspi1); //HAL_DeInit(); /*reset the SysTick Timer*/ SysTick->CTRL=0; SysTick->LOAD=0; SysTick->VAL=0; SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; /*disable systick interrupt*/ HAL_FLASH_Lock(); __disable_irq(); __set_PRIMASK(1); /*Setting vector table to APP VTOR*/ //SCB->VTOR = APP_ADDRESS; /*Setting main stack pointer to APP_ADDRESS*/ __set_MSP(*(uint32_t*) APP_ADDRESS);/*Stack pointer (RAM value) default*/ /*Call firmware at jumpaddr (from pointer above)*/ usrMain(); }void jumpToBootCode(void){ /* Create pointer to usrmain address*/ typedef void (*funcEntryPtr)(void); uint32_t jumpAddr = *(volatile uint32_t*)(BOOT_ADDRESS + 0x04); /*First word is the SP value, next word is the reset vector*/ funcEntryPtr usrBoot = (funcEntryPtr) jumpAddr; /*jumpAddr typecasted*/ /*Shut down any tasks running*/ osThreadSuspendAll(); //HAL_RCC_DeInit(); //HAL_SPI_DeInit(&hspi1); //HAL_DeInit(); /*reset the SysTick Timer*/ SysTick->CTRL=0; SysTick->LOAD=0; SysTick->VAL=0; SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk); SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; /*disable systick interrupt*/ HAL_FLASH_Lock(); __disable_irq(); __set_PRIMASK(1); /*Setting vector table to BOOT VTOR*/ //SCB->VTOR = BOOT_ADDRESS; /*Setting main stack pointer to BOOT SP*/ __set_MSP(*(uint32_t*) BOOT_ADDRESS);/*Stack pointer (RAM value) default*/ /*Call firmware at jumpaddr (from pointer above)*/ usrBoot(); } #!stm32-!bootloader2016-10-27 01:31 AM
As a workaround, I'm just issuing a System Reset when I want to jump from Application to Bootloader and it solved the problem. On the other hand, I still use the Jump function when I want to jump from Bootloader to Application. This works since the Bootloader is at address 0x08000000 while the Application is at 0x08004000.
Another question: Is it okay if I just issue a system reset when I want to jump to Bootloader from App? In what case should I use a jump to BL instead of a reset?Thanks!2016-10-27 02:17 AM
I have tested on stm32f107, application address set to 0x08000000 while bootloader at address 0x08036000, it worked fine, can jump from application to bootloader.
but facing problem when loaded same on stm32f407 board, code goes to hard fault error. Have tried to locate issue with debugger and found some function causing hard fault problem, can see in attachment. Looking to resolve this issue, any help? ________________ Attachments : Capture.PNG : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0qK&d=%2Fa%2F0X0000000bji%2FoXAQKkrn50FcsFCi0HAeeBUaTq8AqzRPGMGTIHVGha0&asPdf=false2016-10-27 05:50 AM
I've read a ton of forum posts here regarding hard fault error encountered when...
And yet you don't post the code that is actually faulting, along with the processor context there? This doesn't have to be an exercise that takes a lot of time and head scratching, it is a gross failure and a pretty finite set of conditions. Understand where it faults, why that is happening, and work backward from there. You can't transfer control from interrupt or user contexts. Make sure the code doesn't expect reset conditions, and is adaptive to how it finds the system, ie clocks, PLLs, etc, see especially code in SystemInit() and called by it.2016-10-27 05:56 AM
@Programmer5 are you the OP here or did you just hijack the thread?
A while(1) loop for the Hard Fault Handler isn't going to help diagnose a problem, looking at using one that outputs some basic diagnostic information so you understand what code is actually faulting, and the register states when it occurs.