Not jumping to application from secondary bootloader

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

Not jumping to application from secondary bootloader

Jump to solution
2,173 Views
mohsin_butt
Contributor II

I have gone through many related threads on this forum, like "Jump from Seondary...""Kinetis bootloader...", etc. but haven't found the answer.

For failsafe update of firmware we have implemented a simple secondary bootloader which will load our application after checking CRC32. The problem is when the seondary bootloader code calls through function pointer the address of ResetISR function of application from Vector table, the RestISR function of Secondary bootloader gets executed. Here is the code from secondary bootloader that calls the application code:

void (*runApplication)(void) = 0;

uint32_t runApplicationAddress = *((uint32_t *)0x00000804UL);

runApplication = (void (*)(void))runApplicationAddress;

SCB->VTOR = (uint32_t)0x00000800;

__set_MSP((uint32_t)0x00000800);

__set_PSP((uint32_t)0x00000800);

runApplication(); /* This line calls the ResetISR of secondary bootloader although the address in the register for BLX instruction is correct for application's ResetISR.*/

Seondary bootloader is using flash area from 0x0000 -  0x0800; Application is using 0x800 - 0x10000

The code is running on Kinetis MKL13Z64, IDE MCUXpresso 11.1.0

While debugging I can see the ARM instruction for runApplicaiton() is "blx r3" and in r3 register the address is correct but it does not jump to that address, which is of application's ResetISR but to it's own.

Thanks in advance!

Labels (1)
1 Solution
1,912 Views
bobpaddock
Senior Contributor III

That seems to be setting the stack pointer to Flash?
Probably not what is really needed.


Also see if your part has any similar registers in the data sheet for

Reset and Bootloader sources.  This is from my KL27 code:

static void vectors_bootloader_mr_setup( void );
static void vectors_bootloader_mr_setup( void )
{
/*
* RCM_MR Indicates the boot source, the boot source remains set
* until the next System Reset or software can write logic one to
* clear the corresponding mode bit. While either bit is set the
* NMI input is disabled and the vector table is relocated to the
* ROM base address at 0x1C00_0000. These bits should be cleared by
* writing logic one before executing any code from either Flash or
* SRAM.
*
* A reset is forced to clear out anything that the ROM
* bootloader did, so we are sure we have the data sheet reset
* values.

* This method works around the buggy KL43/27/17 bootloaders as
* described in: "Problem Analysis and solutions for booting from
* ROM BOOTLOADER in KL series".
*/
if( 0U != ( RCM_MR & RCM_MR_BOOTROM_MASK ) )
{
RCM_MR = RCM_MR_BOOTROM_MASK; /* Clear the bits that indicated a bootlaoder boot via ROM */
RCM_FM = 0U; /* Boot from Flash not ROM on next reset */

SCB_AIRCR = ( SCB_AIRCR_VECTKEY( 0x05FAU ) | SCB_AIRCR_SYSRESETREQ_MASK ); /* Force a Software Reset */
}
}

View solution in original post

0 Kudos
8 Replies
1,913 Views
bobpaddock
Senior Contributor III

That seems to be setting the stack pointer to Flash?
Probably not what is really needed.


Also see if your part has any similar registers in the data sheet for

Reset and Bootloader sources.  This is from my KL27 code:

static void vectors_bootloader_mr_setup( void );
static void vectors_bootloader_mr_setup( void )
{
/*
* RCM_MR Indicates the boot source, the boot source remains set
* until the next System Reset or software can write logic one to
* clear the corresponding mode bit. While either bit is set the
* NMI input is disabled and the vector table is relocated to the
* ROM base address at 0x1C00_0000. These bits should be cleared by
* writing logic one before executing any code from either Flash or
* SRAM.
*
* A reset is forced to clear out anything that the ROM
* bootloader did, so we are sure we have the data sheet reset
* values.

* This method works around the buggy KL43/27/17 bootloaders as
* described in: "Problem Analysis and solutions for booting from
* ROM BOOTLOADER in KL series".
*/
if( 0U != ( RCM_MR & RCM_MR_BOOTROM_MASK ) )
{
RCM_MR = RCM_MR_BOOTROM_MASK; /* Clear the bits that indicated a bootlaoder boot via ROM */
RCM_FM = 0U; /* Boot from Flash not ROM on next reset */

SCB_AIRCR = ( SCB_AIRCR_VECTKEY( 0x05FAU ) | SCB_AIRCR_SYSRESETREQ_MASK ); /* Force a Software Reset */
}
}

0 Kudos
1,912 Views
mohsin_butt
Contributor II

Yes indeed that was setting stack pointer to Flash. When I removed setting PSP and MSP it worked.

Can you please tell why it was causing this problem?

Thanks for the reply.

0 Kudos
1,912 Views
bobpaddock
Senior Contributor III

Ideally writing to Flash via the first call or push would cause an exception.

Failing that, when the first function went to return it would load crap from the Flash at address 0x800UL into the PC and jump to that, which would have no meaning and lead to a crash.

0 Kudos
1,912 Views
mohsin_butt
Contributor II

Thanks Bob.

Although the controller is jumping to application code but after debugging I found that it just goes to a IntDefaultHandler. In the description of this handler its written:

// Processor ends up here if an unexpected interrupt occurs or a specific
// handler is not present in the application code.

WEAK_AV void IntDefaultHandler(void)

{ while(1) {}
}

I am disabling all interrupts before setting VTOR and jumping to application code. What could be the reason for this? Should I start a new Thread for this problem?

Greetings,

0 Kudos
1,912 Views
bobpaddock
Senior Contributor III

That means that an interrupt has been enabled, with no corresponding IRQ function to overload the 'weak' default handler.

Two ways of finding out which IRQ is causing it is to write a small handler for each IRQ that will override the 'weak' default that does something unique for each IRQ, such as output a number or blink different LED patterns for each.

Second way is to look at the stack and  registers see what  was pushed that caused the exception.  The above option is far easier.

0 Kudos
1,912 Views
mohsin_butt
Contributor II

After further debugging, I found some strange behaviour. It seems like Vector Offset Register is Flash Sector Aligned.

The microcontroller is jumping after every function call into a Reserved20_IRQHandler which has an IRQ 4. The strange thing is that in IPSR register exception number is 0x8, which is of I2C0_IRQ but it is not jumping to that handler. This is happening during read and writes on I2C0 Bus which made sense.

This gave me a hint that my application firmware was exactly 16 bytes off from the flash sector start address and then I moved my application firmware to the start of next sector and now it is working as expected.

My question is it really because that VTOR is Flash sector aligned or is it some other problem which just happened to be solved by moving application firmware to the start of another sector and eventually setting the VTOR to the start of a Flash sector address.

I hope the description of my observation is not too complicated.

PS:

Just for explanation: The secondary bootloader's start address in Flash was 0x00 and application firmware at address 0x800 but there was also 16bytes of data that was attached through a script at the start of application firmware which made the firmware image's starting address 0x7F0. During flashing I realised that 0x7f0 is not working because the whole sector should be erased first before writing so then I offsetted the application firmware 16 bytes and then the start address of application firmware was 0x810 and additional data was at address 0x800.

0 Kudos
1,912 Views
bobpaddock
Senior Contributor III

There are many places where things need aligned on 4, 8, 16 or 256 byte boundaries.
I do not know in your specific case.

Sadly these alignment things are rarely easy to find documentation for.

Here is an example of needing eight byte alignment:

/*
* Set stack top to end of RAM.
*
* To prevent obscure problems with printf like library code, when
* printing 64-bit numbers, the stack needs to be aligned to an
* eight byte boundary.
*
* See "Eight-byte Stack Alignment" - http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/14269.html
*/

0 Kudos
1,912 Views
mohsin_butt
Contributor II

Thanks Bob for your continuous support. I found the description of VTOR alignment here. Now things are more clear.