cancel
Showing results for 
Search instead for 
Did you mean: 

Custom Bootloader for update the firmware but application don't start.

PZamb.2
Associate III

Hi.

I'm writing a bootloader for update a firmware of my project by usb pen drive.

Whe bootloader start verify that in the pen drive there io a .bin file, erase the flash and copy teh bin in the flash defined address.

The flash address is 0x08010000.

This process appare running fine , whith debugger I verified the address and the application is present, but when Jump the cpu don't run.

I tested various jump routines take from examples of bootloader find OnLine , but none work.

I don't. know there is the problem.

I use STM32Cube compiler and the test is applied to Nucleo -F413ZH.

this is the routines code:

/*  Bootloader Test */

#include "bootloader.h"

#include "stm32f4xx_hal.h"

#include "string.h"

extern UART_HandleTypeDef huart3;

extern char USBHPath[4];  /* USBH logical drive path */

extern FATFS USBHFatFS;   /* File system object for USBH logical drive */

extern FIL USBHFile;      /* File object for USBH */

extern char RD_buffer[100];

extern char sw_boot;

FRESULT fresult;

FILINFO USBHfno;

#define UART &huart3

typedef void (*pFunction)(void);

typedef void (application_t)(void);

typedef struct

{

   uint32_t      stack_addr;    // Stack Pointer

   application_t*   func_p;       // Program Counter

} JumpStruct;

/**************************** Various test routine *************************************/

void jumpToApp(const uint32_t address)

{

   const JumpStruct* vector_p = (JumpStruct*)address;

    HAL_SuspendTick();

    HAL_RCC_DeInit();

    HAL_DeInit();

    SysTick->CTRL = 0;

    SysTick->LOAD = 0;

    SysTick->VAL = 0;

    SCB->VTOR = address;

   /* let's do The Jump! */

   /* Jump, used asm to avoid stack optimization */

   asm("msr msp, %0; bx %1;" : : "r"(vector_p->stack_addr), "r"(vector_p->func_p));

}

void BOOT_JumpToApplication(uint32_t ui32StartAddr)

{

   uint32_t* vectorTable = (uint32_t*)ui32StartAddr;

   uint32_t topOfStack = vectorTable[0];

   HAL_RCC_DeInit();

   HAL_DeInit();

   /* disebale systick and its irq */

   HAL_SuspendTick();

   HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);

   HAL_NVIC_DisableIRQ(TIM2_IRQn);

   HAL_NVIC_DisableIRQ(OTG_FS_IRQn);

   SysTick->CTRL = 0;

   SysTick->LOAD = 0;

   SysTick->VAL = 0;

   /* Jump to user application */

   asm ( "mov sp, %0" : : "r" (topOfStack) );

   uint32_t resetHandlerAddr = vectorTable[1];

   asm ( "bx %0" : : "r" (resetHandlerAddr) );

   ((void (*)())(resetHandlerAddr))();

}

void JumpToApplication(void) // non va

{

   HAL_RCC_DeInit();

   HAL_DeInit();

     SysTick->CTRL = 0;

     SysTick->LOAD = 0;

     SysTick->VAL = 0;

     SCB->VTOR = APP_ADDRESS;

   uint32_t mainStackPointer = *(volatile uint32_t *)(APP_ADDRESS);

       __set_MSP(mainStackPointer);

   uint32_t programResetHandlerAddress = *(volatile uint32_t *) (APP_ADDRESS + 4);

   void (* programResetHandler)(void) = (void (*)(void)) programResetHandlerAddress;

       programResetHandler();

}

 void goto_application(void)

{

 //void (*app_reset_handler)(void) = (void*)(*((volatile uint32_t*) (APP_ADDRESS + 4U)));

   void (*app_reset_handler)(void) = ((volatile uint32_t*) (APP_ADDRESS + 4U));

   HAL_RCC_DeInit();

   HAL_DeInit();

   HAL_SuspendTick();

   HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);

   HAL_NVIC_DisableIRQ(TIM2_IRQn);

   HAL_NVIC_DisableIRQ(OTG_FS_IRQn);

   HAL_NVIC_DisableIRQ(OTG_FS_WKUP_IRQn);

   __disable_irq();

   SysTick->CTRL = 0;

   SysTick->LOAD = 0;

   SysTick->VAL = 0;

   SCB->VTOR = APP_ADDRESS;

   __set_MSP(*(volatile uint32_t*) APP_ADDRESS);

 app_reset_handler();   //call the app reset handler

}

 void JumpToBootloader2(void)

 {

  uint32_t i=0;

  void (*SysMemBootJump)(void);

  /* Set the address of the entry point to bootloader */

     volatile uint32_t BootAddr = APP_ADDRESS;

  /* Disable all interrupts */

     __disable_irq();

  /* Disable Systick timer */

     SysTick->CTRL = 0;

  /* Set the clock to the default state */

     HAL_RCC_DeInit();

  /* Clear Interrupt Enable Register & Interrupt Pending Register */

     for (i=0;i<5;i++)

     {

     NVIC->ICER[i]=0xFFFFFFFF;

     NVIC->ICPR[i]=0xFFFFFFFF;

     }

  /* Re-enable all interrupts */

     __enable_irq();

  /* Set up the jump to booloader address + 4 */

     SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr + 4))));

  /* Set the main stack pointer to the bootloader stack */

     __set_MSP(*(uint32_t *)BootAddr);

  /* Call the function to jump to bootloader location */

     SysMemBootJump();

  /* Jump is done successfully */

     while (1)

     {

      /* Code should never reach this loop */

     }

 }

13 REPLIES 13
PZamb.2
Associate III

for boot loader

Kamil Duljas
Senior III

Ok, could you show code that set application address?

Dudo
PZamb.2
Associate III

Ok Thanks I found the problem

In the application connection script I do not change ten Flash Addresses, default 0x800000; But must be 0x8010000.

Now Run.

Thank for your inspiration,

Nice :) Please marked best answer as resolved problem :)

Dudo