Jumping from Bootloader to Application

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Jumping from Bootloader to Application

3,426 Views
jonathan_guinta
Contributor I

I'm in the process of jumping from bootloader to application code for MKL15Z128VFT4.

 

Bootloader Address map:

 

m_interrupts start 0x00

m_flash_config start 0x400

m_interrupts_ram start 0x1FFFF000

m_text start 0x410

m_data start 0x1FFFF200

m_comm start 0x20002FFD

 

Application Address map:

 

m_interrupts start 0x7200

m_flash_config start 0x7400

m_interrupts_ram start 0x1FFFF000

m_text start 0x7410

m_data start 0x1FFFF200

m_comm start 0x20002FFD

 

I'm able to jump to startup_MKL15Z4.s successfully and debug through SystemInit and init_data_bss where the vector table is copied from application flash to ram and the vector table offset register is set as the RAM address of the interrupt vector table after the application vector table is copied to RAM. This is all good, though I'm not able to make the jump from _start to finding the main function of my application code. Anyone have any suggestions? I've been troubleshooting this for a while now.

 

Bootloader Code:

 

//Location of Initial Program Counter for application code

#define APPBOOT_VECTOR 0x7200

void (*bootAddress)(void);

volatile unsigned int * safeBootVector;

volatile unsigned int * appBootVector;

 

 

void jumpToAppCode()

{

  //converting value appBootVector points to, to a function pointer that takes a void arg and returns void

  bootAddress = (void(*)(void))(*appBootVector);

 

 

  uint32_t appStack = (uint32_t)(APPBOOT_VECTOR);

 

 

  //disable interrupts just in case

  __disable_irq();

  //set the vector table offset register to beginning of application vector table

  SCB->VTOR = appStack;

  __enable_irq();

 

 

  //set the stack pointer to beginning of application vector table

  //__set_MSP(appStack);

 

 

  //start the application

  bootAddress();

}

 

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */

int main(void)

/*lint -restore Enable MISRA rule (6.3) checking. */

{

  /* Write your local variable definition here */

 

 

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                    ***/

 

 

  Flash_Manager fm;

 

 

  appBootVector = (unsigned int *)(APPBOOT_VECTOR + 4);

 

 

  //Location of Communication_start shared between application and boot code

  int fwUpdateFlagPointer = 0x20002FFD;

 

 

  //value should equal the value stored at fwUpdateFlagPointer address

  //a common address in RAM shared between Application and Bootloader

  char value = *((char*)fwUpdateFlagPointer);

 

 

  // Read FW_UPDATE_FLAG from External SPI flash

  unsigned char fwUpdateFlag = fm.readFirmwareUpdateFlag();

 

 

  //fwUpdateFlag == 7 means booloader portion of FW update from spi flash to uC flash not complete

  //value == 2 means application FW update to SPI flash complete

  //if FW update to SPI flash hasn't been done and FW update from SPI flash not in progress, jumpt to app

  if(value != 2 && fwUpdateFlag != 7)

   jumpToAppCode(); //jump to application portion of flash

 

}

 

Application portion of Code:

 

    .syntax unified

    .arch armv6-m

 

 

    .section .isr_vector, "a"

    .align 2

    .globl __isr_vector

__isr_vector:

    .long   __StackTop                                      /* Top of Stack */

    .long   Boot_Reset_Handler                              /* Reset Handler */

    .long   NMI_Handler                                     /* NMI Handler*/

    .long   HardFault_Handler                               /* Hard Fault Handler*/

    .long   0                                               /* Reserved*/

    .long   0                                               /* Reserved*/

    .long   0                                               /* Reserved*/

    .long   0                                               /* Reserved*/

    .long   0                                               /* Reserved*/

    .long   0                                               /* Reserved*/

    .long   0                                               /* Reserved*/

    .long   SVC_Handler                                     /* SVCall Handler*/

    .long   0                                               /* Reserved*/

    .long   0                                               /* Reserved*/

    .long   PendSV_Handler                                  /* PendSV Handler*/

    .long   SysTick_Handler                                 /* SysTick Handler*/

 

 

                                                            /* External Interrupts*/

    .long   DMA0_IRQHandler                                 /* DMA channel 0 transfer complete*/

    .long   DMA1_IRQHandler                                 /* DMA channel 1 transfer complete*/

    .long   DMA2_IRQHandler                                 /* DMA channel 2 transfer complete*/

    .long   DMA3_IRQHandler                                 /* DMA channel 3 transfer complete*/

    .long   Reserved20_IRQHandler                           /* Reserved interrupt*/

    .long   FTFA_IRQHandler                                 /* Command complete and read collision*/

    .long   LVD_LVW_IRQHandler                              /* Low-voltage detect, low-voltage warning*/

    .long   LLWU_IRQHandler                                 /* Low leakage wakeup Unit*/

    .long   I2C0_IRQHandler                                 /* I2C0 interrupt*/

    .long   I2C1_IRQHandler                                 /* I2C1 interrupt*/

    .long   SPI0_IRQHandler                                 /* SPI0 single interrupt vector for all sources*/

    .long   SPI1_IRQHandler                                 /* SPI1 single interrupt vector for all sources*/

    .long   UART0_IRQHandler                                /* UART0 status and error*/

    .long   UART1_IRQHandler                                /* UART1 status and error*/

    .long   UART2_IRQHandler                                /* UART2 status and error*/

    .long   ADC0_IRQHandler                                 /* ADC0 interrupt*/

    .long   CMP0_IRQHandler                                 /* CMP0 interrupt*/

    .long   TPM0_IRQHandler                                 /* TPM0 single interrupt vector for all sources*/

    .long   TPM1_IRQHandler                                 /* TPM1 single interrupt vector for all sources*/

    .long   TPM2_IRQHandler                                 /* TPM2 single interrupt vector for all sources*/

    .long   RTC_IRQHandler                                  /* RTC alarm*/

    .long   RTC_Seconds_IRQHandler                          /* RTC seconds*/

    .long   PIT_IRQHandler                                  /* PIT interrupt*/

    .long   Reserved39_IRQHandler                           /* Reserved interrupt*/

    .long   Reserved40_IRQHandler                           /* Reserved interrupt*/

    .long   DAC0_IRQHandler                                 /* DAC0 interrupt*/

    .long   TSI0_IRQHandler                                 /* TSI0 interrupt*/

    .long   MCG_IRQHandler                                  /* MCG interrupt*/

    .long   LPTMR0_IRQHandler                               /* LPTMR0 interrupt*/

    .long   Reserved45_IRQHandler                           /* Reserved interrupt*/

    .long   PORTA_IRQHandler                                /* PORTA Pin detect*/

    .long   PORTD_IRQHandler                                /* PORTD Pin detect*/

 

 

    .size    __isr_vector, . - __isr_vector

 

 

/* Flash Configuration */

    .section .FlashConfig, "a"

    .long 0xFFFFFFFF

    .long 0xFFFFFFFF

    .long 0xFFFFFFFF

    .long 0xFFFFFFFE

 

 

    .text

    .thumb

 

 

/* Reset Handler */

 

 

    .thumb_func

    .align 2

    .globl   Boot_Reset_Handler

    .weak    Boot_Reset_Handler

    .type    Boot_Reset_Handler, %function

Boot_Reset_Handler:

    cpsid   i               /* Mask interrupts */

#ifndef __NO_SYSTEM_INIT

    bl SystemInit

#endif

    bl init_data_bss

    cpsie   i               /* Unmask interrupts */

#ifndef __START

#define __START _start

#endif

#ifndef __ATOLLIC__

    bl    __START

#else

    bl    __libc_init_array

    bl    main

#endif

 

After _start it jumps to the exception loop....

Labels (1)
0 Kudos
Reply
5 Replies

1,786 Views
jonathan_guinta
Contributor I

Sorry, meant to type SysTick->CTRL = 0U

0 Kudos
Reply

1,786 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello ,

- Why enable the interrupt here :

pastedImage_0.png

    could you try enable the interrupt after jump.

-  Do you use KDS IDE ? If yes, there is a code about jump, i think you can refer to :

  // relocate vector table

    SCB_VTOR = RELOCATED_VECTORS;

  JumpToUserApplication(*((unsigned long*)RELOCATED_VECTORS), *((unsigned long*)(RELOCATED_VECTORS+4)));

pastedImage_1.png

- There is a bootloader about KL26, i thin you can refer to the jumper code , it is the same as i mentioned above.

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------


Have a great day,
Alice Yang

0 Kudos
Reply

1,786 Views
jonathan_guinta
Contributor I

Hi Alice,

I tried the code you have suggested and I'm experiencing the exact same behavior. I arrive at the breakpoints I set for the startup_MKL15Z4.s file, I execute the init_data_bss and SystemInit, and then when I step to the __START call, the program jumps to the DefaultISR loop for an exception. If I comment out the SystemInit call, the program will jump from __START to main of my application, but I have to manually step through the code otherwise the exception will be triggered again. I'm not sure what's going on, I'm new to this. Is there an issue restarting the clocks and watchdog in the default code for the SystemInit function? The init_data_bss function appears to be ok transferring the application vector table from flash to RAM and the data rom from flash to RAM.

Regards,

Jon

0 Kudos
Reply

1,785 Views
jonathan_guinta
Contributor I

Update:

So I narrowed it down to here:

void OSA_TimeInit(void)

{

  uint64_t divider;

  /* Disable timer and interrupt */

  SysTick->CTRL = 0U;

  /* A write of any value to current value register clears the field to 0, and also clears the SYST_CSR COUNTFLAG bit to 0. */

  SysTick->VAL = 0U;

#if FSL_FEATURE_SYSTICK_HAS_EXT_REF

    /* Set the clock source back to core freq */

    CLOCK_SYS_SetSystickSrc(kClockSystickSrcCore);

#endif

  /* Get SysTick counter input frequency and compute divider value */

  divider = ((((uint64_t)CLOCK_SYS_GetSystickFreq() * OSA1_TIMER_PERIOD_US)) / 1000000U);

  assert(divider != 0U);

  /* Set divide input clock of systick timer */

  SysTick->LOAD = (uint32_t)(divider - 1U);

  /* Set interrupt priority and enable interrupt */

  NVIC_SetPriority(SysTick_IRQn, 1U);

  /* Run timer and enable interrupt */

  SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);

}

If I enable the bare metal OSA Timer (System Tick interrupt) and interrupt in the bootloader code, then I can't successfully make the jump from __start to main in the application portion of the code.

0 Kudos
Reply

1,786 Views
jonathan_guinta
Contributor I

I figured it out, it was the OSA_Timer interrupt, it needed to be turned off: SysTick->VTOR = 0U. Once this was disabled, then the jump to main in the application code worked.

0 Kudos
Reply