We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
I have am issue where my main application runs fine when I start it directly from the uVision IDE but when it is 'jumped' to from my bootloader I get a HardFault.
The only info on the hardfault is that it is "Forced" all other fault registers are 0.
It is the Hardfault handler in the main app that is getting executed, thus the fault is happening in the main app so it is difficult to debug. Also note, the fault happens after Sysinit is called but before my main is called (somewhere in the C lib init - __main)
Can anyone think of why a fault might occur when being 'jumped' to as opposed to running from the IDE debugger directly.
Note: I've stripped down the bootloader to really a simple mem init + mem test +
__asm void boot_jump( uint32_t address ) { LDR SP, [R0] ;Load new stack pointer address LDR PC, [R0, #4] ;Load new program counter address } void execute_user_code(void) { /* Change the Vector Table to the USER_FLASH_START in case the user application uses interrupts */ SCB->VTOR = USER_FLASH_START & 0x1FFFFF80; boot_jump(USER_FLASH_START); }
This is on an LPC1788
I think you need to jump to an uneven address:
NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAIN_BOOT_START_SECTOR);
where
void NVIC_SetVectorTable(DWORD NVIC_VectTab, DWORD Offset) { NVIC_VECT_TABLE = NVIC_VectTab | (Offset & 0x1FFFFF80); }
and
#define MAIN_BOOT_START_SECTOR 1
I hope this helps...
Where does your application start?
My application starts at 0x4000.
I don't think the jump address is the problem because the SysInit function of the main app gets executed.
The HardFault happens in the __main somewhere?
Does it also fail if you empty the application entirely? Are you sure the application does not set the CRP flag? That can cause problems, though not likely the one you have.
If I use a really simple main application it does not fail. In other words if the main app looks like:
int main() { printf("test"); while(1); }
The boot loader correctly jumps to this app.
I'm not sure what that means. What settings in my 'real' app could cause a fault in the C library initialization?
I don't know. Why don't either show them, or remove them all and add one by one until a failure occurs...?
Thank you Tamir.
I may have to do this, it will be a long an tedious process.
M
In case someone else encounters this issue I found my problem.
It had to do with pending interrupts when I jumped to the main application. These caused faults as the system had not been initialized.
I change my boot_jump to the following:
void NVIC_DeInit(void) { uint8_t tmp; /* Disable all interrupts */ NVIC->ICER[0] = 0xFFFFFFFF; NVIC->ICER[1] = 0x00000001; /* Clear all pending interrupts */ NVIC->ICPR[0] = 0xFFFFFFFF; NVIC->ICPR[1] = 0x00000001; /* Clear all interrupt priority */ for (tmp = 0; tmp < 32; tmp++) { NVIC->IP[tmp] = 0x00; } } void NVIC_SCBDeInit(void) { uint8_t tmp; SCB->ICSR = 0x0A000000; SCB->VTOR = 0x00000000; SCB->AIRCR = 0x05FA0000; SCB->SCR = 0x00000000; SCB->CCR = 0x00000000; for (tmp = 0; tmp < 32; tmp++) { SCB->SHP[tmp] = 0x00; } SCB->SHCSR = 0x00000000; SCB->CFSR = 0xFFFFFFFF; SCB->HFSR = 0xFFFFFFFF; SCB->DFSR = 0xFFFFFFFF; } void NVIC_SetVTOR(uint32_t offset) { //SCB->VTOR = (offset & NVIC_VTOR_MASK); SCB->VTOR = offset; } __asm void boot_jump( uint32_t address ) { LDR SP, [R0] ;Load new stack pointer address LDR PC, [R0, #4] ;Load new program counter address } void execute_user_code(void) { NVIC_DeInit(); NVIC_SCBDeInit(); NVIC_SetVTOR(USER_FLASH_START); boot_jump(USER_FLASH_START); }
I think it would be enough to switch to privileged mode via a SVC and to call "__disable_irq()" before the jump.
Of stop the interrupt source, of course.
I tried that first but the pending bits in the NVIC still seemed to cause an issue when the C library was initializing.