AnsweredAssumed Answered

Custom Bootloader for Kinetis MKE06Z microcontrollers on IAR EWARM issue

Question asked by Nicolas Giussani on Apr 21, 2016
Latest reply on Apr 23, 2016 by Mark Butcher

I've been having some trouble in the implementation of a custom bootloader for a Kinetis MKE06Z microcontroller, not in the bootloader itself but in the relocation of the application code and the behavior after jumping to it. The application is completely coded in C.

The bootloader executes everything as expected, determines if it should run or jump to user application. This is the sequence that implements the jump:

__disable_interrupt();
SCB->VTOR = RELOCATION_VECTOR_ADDR & 0x3FFFFE00;
JumpToUserApplication(RELOCATION_VECTOR_ADDR);

where:

void JumpToUserApplication(uint32_t userStartup) {

/* set up stack pointer */
asm("LDR    r1, [r0]");
asm("MOV    r13, r1");
/* jump to application reset vector */
asm("ADDS   r0,r0,#0x04 ");
asm("LDR    r0, [r0]");
asm("BX     r0");

}

as implemented in Frescale's AN4767.

So far, so good. Once the jump is executed, I trace the application behavior (on the Disassembly Window) and find out after some instructions, it gets stuck at some specific address with a jump instruction, which ends up being an infinite loop. I then run it step by step to determine which was the instruction that causes this malfunction. It's very strange, as it is running OK and suddenly jumps to a RAM address. A couple of cycles and then jumps to the infinite loop. I took note of the addresses with the instruction causing this strange jump and the one with the infinite loop. I look at the core registers and find out there is an exception, and notice it's the number 0x03 (Hard Fault). Then switch to debugging the user application.

Once in the user application, I start debugging. The user application works fine running like this (no jump from the bootloader). Then I look for the relevant addresses and discover that the routine causing the hard fault when jumping from bootloader is from IAR: __iar_data_init3. The thing is, it's part of a precompiled library and I'm not sure if it's safe to remove it (by removing the __iar_program_start and replacing it directly with the call to main on the startup file.

The real question is: why does the application behave like that after the jump from the booloader but not if there is no such jump? Why does this routine jumps to a RAM address (when it shouldn't)?

Of course, it may be a little to specific, but hopefully there's someone that can help me.

Outcomes