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 */

     }

 }

This discussion is locked. Please start a new topic to ask your question.
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