AnsweredAssumed Answered

KDS K22 Bootloader Jump

Question asked by weblar on Oct 27, 2016
Latest reply on Nov 3, 2016 by Raymundo Velarde

I know this question has been asked a fair few times on here but I've discovered an "issue" with a bootloader I've developed for a Kinetis K22 when jumping to a user application.

 

The bootloader initializes an I2C device (through Processor Expert) and the device makes use of the I2C1 interrupt. There is also a USB interrupt enabled as USB is how the user application is transferred to the K22.

 

When I've determined that the user application is valid, I first of all disable the I2C interrupt and de-initilalize the device (calling PE functions) before calling __asm("CPSID i") to disable interrupts. I then jump to the user application, which is successful and I can see the user application running.

 

The problem comes, however, when the user application also wants to use the I2C device (using the PE component again), the interrupt never seems to fire when enabled and hence no I2C transactions can complete. As soon as I comment out the I2C initialization, the user application runs happily again. I would hazard a guess that any peripheral wanting to use an interrupt will come up against this issue in user app space.

 

If I check the SCB->VTOR register, I can see that it points to the correct re-located vector table and that also, in the vector table, the I2C1 interrupt is now at the correct vector location in user application space (the map file confirmed this).

 

So, I'm clearly missing something - either through not cleaning up correctly before the jump or not jumping properly.

 

My jump routine is basically:

 

uint32_t addr = ((uint32_t *)0x10000)[1];

if (addr != 0xFFFFFFFF) {

    I2C_PDD_DisableInterrupt(I2C0_BASE_PTR);

    GI2C1_Deinit();

    __asm("CPSID i");

 

    // Jump to the user application

    ((void(*)(void)addr)();

    // Should never get here

    for (;;) {

    }

}

 

The jump basically produces "LDR r3 [r7, #4]" and "BLX r3" assembly instructions to perform the jump - which is what I've seen mentioned in other bootloader jump questions.

 

I'm pretty sure my user application linker file is set up correctly:

 

m_interrupts (RX) : ORIGIN = 0x00010000, LENGTH = 0x00000188

m_text (RX) : ORIGIN = 0x00010410, LENGTH = 0x000EFBF0

// RAM... 0x1FFF0000 and 0x20000000

m_cfmprotrom (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010

 

 

I guess ultimately, what I'm wanting, is when the user application is executed, everything is cleared down as if the bootloader had never even been run - ram cleared, peripherals at their default levels, etc, etc. Previous bootloaders I've developed with IAR seemed to be more straightforward to implement so maybe Processor Expert is getting in the way a little bit.

 

For extra information (whether it is necessary or not), my user application is a clone of the bootloader application but with the USB removed and the linker configuration changed so as to start from address 0x10000. 

 

If anyone could provide any suggestions, I'd be very grateful. 

Outcomes