AnsweredAssumed Answered

Custom Bootloader fails to Launch App - HardFault_Handler

Question asked by dupont.michael on Feb 12, 2018
Latest reply on Feb 12, 2018 by dupont.michael

I have built an STM32F303ZET6 project using the AC6 IDE and FreeRTOS.  The base application (located at 0x08000000) incorporates a mechanism for loading a new firmware image above the base application (at 0x08030000 via linker script with vector table offset specified in the system_stm32f3xx.c ). Should something go awry with the newly loaded image (bad checksum or missing code at the expected location), the base image is a fallback so the product is less likely to become a brick.  So far, base code runs properly, base code detects a new file on the file system, FLASH gets updated  with the new code and in the proper area of FLASH.

BUT...

I can't get the newly loaded image to run.

 

Here's the entire litany of things I'm doing (and yes, I'm sure some of it is WAY redundant including disabling the tar out of the interrupts...):

void LaunchApp(void)

{

#if 1

osThreadSuspendAll();

 

__disable_irq();

 

HAL_ADC_MspDeInit(&hadc1);

HAL_ADC_MspDeInit(&hadc2);

HAL_ADC_MspDeInit(&hadc3);

HAL_ADC_MspDeInit(&hadc4);

HAL_UART_MspDeInit(&huart2);

HAL_UART_MspDeInit(&huart3);

HAL_UART_MspDeInit(&huart4);

HAL_UART_MspDeInit(&huart5);

HAL_SPI_MspDeInit(&hspi2);

HAL_TIM_Base_MspDeInit(&htim1);

HAL_TIM_Base_MspDeInit(&htim2);

HAL_TIM_Base_MspDeInit(&htim3);

HAL_TIM_Base_MspDeInit(&htim4);

HAL_TIM_Base_MspDeInit(&htim8);

HAL_TIM_Base_MspDeInit(&htim15);

HAL_TIM_IC_MspDeInit(&htim20);

HAL_PCD_MspDeInit(&hpcd_USB_FS);

 

   // Clear Interrupt Enable

    NVIC->ICER[0] = 0xFFFFFFFF;

    NVIC->ICER[1] = 0xFFFFFFFF;

    NVIC->ICER[2] = 0xFFFFFFFF;

    NVIC->ICER[3] = 0xFFFFFFFF;

    NVIC->ICER[4] = 0xFFFFFFFF;

    NVIC->ICER[5] = 0xFFFFFFFF;

    NVIC->ICER[6] = 0xFFFFFFFF;

    NVIC->ICER[7] = 0xFFFFFFFF;

 

    // Clear Pending Interrupts

NVIC->ICPR[0] = 0xFFFFFFFF;

NVIC->ICPR[1] = 0xFFFFFFFF;

NVIC->ICPR[2] = 0xFFFFFFFF;

NVIC->ICPR[3] = 0xFFFFFFFF;

NVIC->ICPR[4] = 0xFFFFFFFF;

NVIC->ICPR[5] = 0xFFFFFFFF;

NVIC->ICPR[6] = 0xFFFFFFFF;

NVIC->ICPR[7] = 0xFFFFFFFF;

#endif

 

#if 1

__disable_irq();

 

portDISABLE_INTERRUPTS();

osThreadTerminate(taskUART_BlueTooth->MyTaskThreadID());

osThreadTerminate(taskUART_UpStream->MyTaskThreadID());

osThreadTerminate(taskUART_DownStream->MyTaskThreadID());

osThreadTerminate(taskUART_DebugPort->MyTaskThreadID());

vTaskDelete(xTimerGetTimerDaemonTaskHandle());

#endif

 

__disable_irq();

 

  HAL_RCC_DeInit();

  HAL_DeInit();

 

__disable_irq();

 

  SysTick->CTRL = 0;

  SysTick->LOAD = 0;

  SysTick->VAL = 0;

 

__set_CONTROL(0); // Assure privileged operation

__set_MSP(*(__IO uint32_t*) APP_LOAD_ADDRESS);

 

__disable_irq();

 

     JumpAddress = *(volatile unsigned long*) (APP_LOAD_ADDRESS + 4);

     JumpToApplication = (pFunction) JumpAddress;

     JumpToApplication();

while (1);

}

I have confirmed that the stack pointer gets properly loaded using info from the newly loaded code's vector table.  The processor jumps to the proper location in the newly loaded code (verified against map and examined disassembly).

When I get the debugger to single step after having landed on the restart vector location in the new code, the processor IMMEDIATELY goes to the HardFault_Handler.

Nothing in the newly loaded code has had a chance to do any processor setup or anything - some lingering gremlin in the base code is the probable offender.

I have scoured every forum I can find and I'm SURE that I am at fault.  I sure would appreciate someone with more wisdom and patience to "look over my shoulder" on this and say, "Well, ya fool! You forgot to <insertYourSuggestionHere>!!!"  I am pretty sure it's one line of code that stands between me and success...or ultimate darkness.

 

Thanks in advance.

Outcomes